summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/src/osd/modules.lua5
-rw-r--r--src/devices/cpu/m68hc16/cpu16dasm.cpp4
-rw-r--r--src/devices/cpu/mcs51/mcs51dasm.cpp2
-rw-r--r--src/devices/cpu/psx/psx.cpp8
-rw-r--r--src/devices/cpu/scudsp/scudsp.cpp2
-rw-r--r--src/devices/cpu/tms34010/34010ops.hxx13
-rw-r--r--src/devices/sound/ics2115.cpp29
-rw-r--r--src/emu/emucore.h21
-rw-r--r--src/emu/input.cpp209
-rw-r--r--src/emu/input.h924
-rw-r--r--src/emu/inputdev.cpp32
-rw-r--r--src/emu/inputdev.h24
-rw-r--r--src/emu/ioport.cpp28
-rw-r--r--src/emu/schedule.cpp178
-rw-r--r--src/emu/schedule.h18
-rw-r--r--src/emu/sound.cpp34
-rw-r--r--src/emu/sound.h5
-rw-r--r--src/frontend/mame/clifront.cpp6
-rw-r--r--src/frontend/mame/luaengine.cpp8
-rw-r--r--src/frontend/mame/mame.cpp5
-rw-r--r--src/frontend/mame/ui/inputdevices.cpp4
-rw-r--r--src/lib/util/endianness.h40
-rw-r--r--src/mame/drivers/abc1600.cpp13
-rw-r--r--src/mame/drivers/blockch.cpp17
-rw-r--r--src/mame/drivers/ds90.cpp22
-rw-r--r--src/mame/drivers/fidel_eag68k.cpp2
-rw-r--r--src/mame/drivers/igs017.cpp6
-rw-r--r--src/mame/drivers/miconkit.cpp2
-rw-r--r--src/mame/drivers/mpu4.cpp52
-rw-r--r--src/mame/drivers/mpu4crystal.cpp63
-rw-r--r--src/mame/drivers/mpu4unsorted.cpp34
-rw-r--r--src/mame/drivers/namcos23.cpp35
-rw-r--r--src/mame/drivers/plygonet.cpp12
-rw-r--r--src/mame/drivers/seta.cpp5
-rw-r--r--src/mame/drivers/skylncr.cpp134
-rw-r--r--src/mame/drivers/sshangha.cpp18
-rw-r--r--src/mame/includes/mpu4.h7
-rw-r--r--src/mame/machine/abc1600mac.cpp2
-rw-r--r--src/mame/machine/igs022.cpp1
-rw-r--r--src/mame/machine/mpu4_characteriser_bootleg.cpp4
-rw-r--r--src/mame/machine/mpu4_characteriser_bootleg.h15
-rw-r--r--src/mame/machine/pgmprot_igs027a_type1.cpp60
-rw-r--r--src/mame/machine/pgmprot_igs027a_type1.h10
-rw-r--r--src/mame/mame.lst13
-rw-r--r--src/osd/interface/inputcode.h872
-rw-r--r--src/osd/interface/inputman.h77
-rw-r--r--src/osd/interface/inputseq.cpp210
-rw-r--r--src/osd/interface/inputseq.h107
-rw-r--r--src/osd/modules/file/posixdir.cpp6
-rw-r--r--src/osd/modules/file/posixfile.cpp2
-rw-r--r--src/osd/modules/file/winfile.cpp2
-rw-r--r--src/osd/modules/file/winrtfile.cpp4
-rw-r--r--src/osd/modules/input/input_common.cpp45
-rw-r--r--src/osd/modules/input/input_common.h74
-rw-r--r--src/osd/modules/input/input_dinput.cpp6
-rw-r--r--src/osd/modules/input/input_rawinput.cpp12
-rw-r--r--src/osd/modules/input/input_sdl.cpp8
-rw-r--r--src/osd/modules/input/input_win32.cpp4
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp6
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp3
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.cpp4
-rw-r--r--src/osd/osdcomm.h27
-rw-r--r--src/osd/osdcore.h3
-rw-r--r--src/osd/windows/winutil.cpp7
64 files changed, 1980 insertions, 1625 deletions
diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua
index e431bb93d22..3a44a1c7d05 100644
--- a/scripts/src/osd/modules.lua
+++ b/scripts/src/osd/modules.lua
@@ -54,6 +54,10 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/osdnet.h",
MAME_DIR .. "src/osd/watchdog.cpp",
MAME_DIR .. "src/osd/watchdog.h",
+ MAME_DIR .. "src/osd/interface/inputcode.h",
+ MAME_DIR .. "src/osd/interface/inputman.h",
+ MAME_DIR .. "src/osd/interface/inputseq.cpp",
+ MAME_DIR .. "src/osd/interface/inputseq.h",
MAME_DIR .. "src/osd/modules/debugger/debug_module.h",
MAME_DIR .. "src/osd/modules/font/font_module.h",
MAME_DIR .. "src/osd/modules/midi/midi_module.h",
@@ -119,6 +123,7 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp",
}
includedirs {
+ MAME_DIR .. "src/osd",
ext_includedir("asio"),
}
diff --git a/src/devices/cpu/m68hc16/cpu16dasm.cpp b/src/devices/cpu/m68hc16/cpu16dasm.cpp
index 3d646639058..84598595f52 100644
--- a/src/devices/cpu/m68hc16/cpu16dasm.cpp
+++ b/src/devices/cpu/m68hc16/cpu16dasm.cpp
@@ -1370,7 +1370,7 @@ offs_t cpu16_disassembler::disassemble(std::ostream &stream, offs_t pc, const cp
{
const u16 operand = opcodes.r16(pc + 2);
format_index8(stream, operand >> 8, 'x' + BIT(opcode, 12, 2));
- util::stream_format(stream, ", #$%02X, $%04X", opcode & 0x00ff, (pc + 6 + s8(operand & 0x00ff)) & 0xfffff);
+ util::stream_format(stream, ", #$%02X, $%05X", opcode & 0x00ff, (pc + 6 + s8(operand & 0x00ff)) & 0xfffff);
return 4 | SUPPORTED | info.m_flags;
}
else
@@ -1382,7 +1382,7 @@ offs_t cpu16_disassembler::disassemble(std::ostream &stream, offs_t pc, const cp
util::stream_format(stream, ", #$%02X", opcode & 0x00ff);
if (BIT(opcode, 9))
{
- util::stream_format(stream, ", $%04X", (pc + 6 + s16(opcodes.r16(pc + 4))) & 0xfffff);
+ util::stream_format(stream, ", $%05X", (pc + 6 + s16(opcodes.r16(pc + 4))) & 0xfffff);
return 6 | SUPPORTED | info.m_flags;
}
else
diff --git a/src/devices/cpu/mcs51/mcs51dasm.cpp b/src/devices/cpu/mcs51/mcs51dasm.cpp
index d1d8b9f2499..13ec8a161e7 100644
--- a/src/devices/cpu/mcs51/mcs51dasm.cpp
+++ b/src/devices/cpu/mcs51/mcs51dasm.cpp
@@ -226,7 +226,7 @@ const mcs51_disassembler::mem_info mcs51_disassembler::i8xc51gb_names[] = {
{ 0xd4, "ad5" },
{ 0xe4, "ad6" },
{ 0xf4, "ad7" },
- { 0x85, "acon" },
+ { 0x97, "acon" },
{ 0xc7, "acmp" },
{ 0xe8, "c1con" },
diff --git a/src/devices/cpu/psx/psx.cpp b/src/devices/cpu/psx/psx.cpp
index 7e1ce6bd6a0..57ebf91e1da 100644
--- a/src/devices/cpu/psx/psx.cpp
+++ b/src/devices/cpu/psx/psx.cpp
@@ -1185,16 +1185,16 @@ void psxcpu_device::multiplier_update()
case MULTIPLIER_OPERATION_MULT:
{
int64_t result = mul_32x32( (int32_t)m_multiplier_operand1, (int32_t)m_multiplier_operand2 );
- m_lo = extract_64lo( result );
- m_hi = extract_64hi( result );
+ m_lo = result;
+ m_hi = result >> 32;
}
break;
case MULTIPLIER_OPERATION_MULTU:
{
uint64_t result = mulu_32x32( m_multiplier_operand1, m_multiplier_operand2 );
- m_lo = extract_64lo( result );
- m_hi = extract_64hi( result );
+ m_lo = result;
+ m_hi = result >> 32;
}
break;
diff --git a/src/devices/cpu/scudsp/scudsp.cpp b/src/devices/cpu/scudsp/scudsp.cpp
index 56b2a3cbc5b..517688c226b 100644
--- a/src/devices/cpu/scudsp/scudsp.cpp
+++ b/src/devices/cpu/scudsp/scudsp.cpp
@@ -128,6 +128,8 @@ DEFINE_DEVICE_TYPE(SCUDSP, scudsp_cpu_device, "scudsp", "Sega SCUDSP")
#define scudsp_readmem(A,MD) m_data->read_dword(A | (MD << 6))
#define scudsp_writemem(A,MD,B) m_data->write_dword(A | (MD << 6), B)
+constexpr uint64_t concat_64(uint32_t hi, uint32_t lo) { return (uint64_t(hi) << 32) | lo; }
+
uint32_t scudsp_cpu_device::scudsp_get_source_mem_reg_value( uint32_t mode )
{
if ( mode < 0x8 )
diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx
index 27ef253ed6e..bb4791d9d76 100644
--- a/src/devices/cpu/tms34010/34010ops.hxx
+++ b/src/devices/cpu/tms34010/34010ops.hxx
@@ -525,8 +525,7 @@ void tms340x0_device::dint(uint16_t op)
int64_t dividend = ((uint64_t)*rd1 << 32) | (uint32_t)*rd2; \
int64_t quotient = dividend / *rs; \
int32_t remainder = dividend % *rs; \
- uint32_t signbits = (int32_t)quotient >> 31; \
- if (extract_64hi(quotient) != signbits) \
+ if ((int64_t)(int32_t)quotient != quotient) \
{ \
SET_V_LOG(1); \
} \
@@ -573,7 +572,7 @@ void tms340x0_device::divs_b(uint16_t op) { DIVS(B); }
uint64_t dividend = ((uint64_t)*rd1 << 32) | (uint32_t)*rd2; \
uint64_t quotient = dividend / (uint32_t)*rs; \
uint32_t remainder = dividend % (uint32_t)*rs; \
- if (extract_64hi(quotient) != 0) \
+ if (quotient > 0xffffffff) \
{ \
SET_V_LOG(1); \
} \
@@ -740,8 +739,8 @@ void tms340x0_device::modu_b(uint16_t op) { MODU(B); }
SET_Z_LOG(product == 0); \
SET_N_BIT(product >> 32, 31); \
\
- *rd1 = extract_64hi(product); \
- R##REG(DSTREG(op)|1) = extract_64lo(product); \
+ *rd1 = (int32_t)(product >> 32); \
+ R##REG(DSTREG(op)|1) = product & 0xffffffff; \
\
COUNT_CYCLES(20); \
}
@@ -759,8 +758,8 @@ void tms340x0_device::mpys_b(uint16_t op) { MPYS(B); }
product = mulu_32x32(m1, *rd1); \
SET_Z_LOG(product == 0); \
\
- *rd1 = extract_64hi(product); \
- R##REG(DSTREG(op)|1) = extract_64lo(product); \
+ *rd1 = (int32_t)(product >> 32); \
+ R##REG(DSTREG(op)|1) = product & 0xffffffff; \
\
COUNT_CYCLES(21); \
}
diff --git a/src/devices/sound/ics2115.cpp b/src/devices/sound/ics2115.cpp
index 4b9f1ef152b..56c0cf607c4 100644
--- a/src/devices/sound/ics2115.cpp
+++ b/src/devices/sound/ics2115.cpp
@@ -1087,33 +1087,32 @@ void ics2115_device::recalc_irq()
TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_0 )
{
- m_irq_pending |= 1 << 0;
- recalc_irq();
+ if (!(m_irq_pending & (1 << 0)))
+ {
+ m_irq_pending |= 1 << 0;
+ recalc_irq();
+ }
}
TIMER_CALLBACK_MEMBER( ics2115_device::timer_cb_1 )
{
- m_irq_pending |= 1 << 1;
- recalc_irq();
+ if (!(m_irq_pending & (1 << 1)))
+ {
+ m_irq_pending |= 1 << 1;
+ recalc_irq();
+ }
}
void ics2115_device::recalc_timer(int timer)
{
- //Old regression-based formula (minus constant)
- //u64 period = m_timer[timer].preset * (m_timer[timer].scale << 16) / 60;
-
- //New formula based on O.Galibert's reverse engineering of ICS2115 card firmware
- // TODO : Related to input clock?
u64 period = ((m_timer[timer].scale & 0x1f) + 1) * (m_timer[timer].preset + 1);
- period = (period << (4 + (m_timer[timer].scale >> 5)))*78125/2646;
+ period = period << (4 + (m_timer[timer].scale >> 5));
if (m_timer[timer].period != period)
{
+ attotime tp = attotime::from_ticks(period, clock());
+ logerror("Timer %d period %dns (%dHz)\n", timer, int(tp.as_double()*1e9), int(1/tp.as_double()));
m_timer[timer].period = period;
- // Adjust the timer lengths
- if (period) // Reset the length
- m_timer[timer].timer->adjust(attotime::from_nsec(period), 0, attotime::from_nsec(period));
- else // Kill the timer if length == 0
- m_timer[timer].timer->adjust(attotime::never);
+ m_timer[timer].timer->adjust(tp, 0, tp);
}
}
diff --git a/src/emu/emucore.h b/src/emu/emucore.h
index 8074fb0fe73..8e96e4b3778 100644
--- a/src/emu/emucore.h
+++ b/src/emu/emucore.h
@@ -242,27 +242,6 @@ constexpr int ROT270 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y;
// COMMON MACROS
//**************************************************************************
-// macro for defining a copy constructor and assignment operator to prevent copying
-#define DISABLE_COPYING(TYPE) \
- TYPE(const TYPE &) = delete; \
- TYPE &operator=(const TYPE &) = delete
-
-// macro for declaring enumeration operators that increment/decrement like plain old C
-#define DECLARE_ENUM_INCDEC_OPERATORS(TYPE) \
-inline TYPE &operator++(TYPE &value) { return value = TYPE(std::underlying_type_t<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
diff --git a/src/emu/input.cpp b/src/emu/input.cpp
index 169f76aabe3..6368c4ee4a9 100644
--- a/src/emu/input.cpp
+++ b/src/emu/input.cpp
@@ -25,21 +25,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
//**************************************************************************
@@ -370,187 +355,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
//**************************************************************************
@@ -589,6 +393,17 @@ input_manager::~input_manager()
//-------------------------------------------------
+// add_device - add a representation of a host
+// input device
+//-------------------------------------------------
+
+osd::input_device &input_manager::add_device(input_device_class devclass, std::string_view name, std::string_view id, void *internal)
+{
+ return device_class(devclass).add_device(name, id, internal);
+}
+
+
+//-------------------------------------------------
// code_value - return the value of a given
// input code
//-------------------------------------------------
@@ -1127,7 +942,7 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl
// saturate mixed absolute values
if (itemclass == ITEM_CLASS_ABSOLUTE)
- result = std::clamp(result, INPUT_ABSOLUTE_MIN, INPUT_ABSOLUTE_MAX);
+ result = std::clamp(result, osd::INPUT_ABSOLUTE_MIN, osd::INPUT_ABSOLUTE_MAX);
// if the caller wants to know the type, provide it
if (result == 0)
diff --git a/src/emu/input.h b/src/emu/input.h
index 7bc03c13831..1b6b1caca93 100644
--- a/src/emu/input.h
+++ b/src/emu/input.h
@@ -17,6 +17,10 @@
#ifndef MAME_EMU_INPUT_H
#define MAME_EMU_INPUT_H
+#include "interface/inputcode.h"
+#include "interface/inputman.h"
+#include "interface/inputseq.h"
+
#include <algorithm>
#include <array>
#include <cassert>
@@ -28,467 +32,16 @@
//**************************************************************************
-// 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
diff --git a/src/emu/inputdev.cpp b/src/emu/inputdev.cpp
index 436f83cf0df..dacffbc2e56 100644
--- a/src/emu/inputdev.cpp
+++ b/src/emu/inputdev.cpp
@@ -233,8 +233,8 @@ std::string joystick_map::to_string() const
u8 joystick_map::update(s32 xaxisval, s32 yaxisval)
{
// now map the X and Y axes to a 9x9 grid using the raw values
- xaxisval = ((xaxisval - INPUT_ABSOLUTE_MIN) * 9) / (INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN + 1);
- yaxisval = ((yaxisval - INPUT_ABSOLUTE_MIN) * 9) / (INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN + 1);
+ xaxisval = ((xaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1);
+ yaxisval = ((yaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1);
u8 mapval = m_map[yaxisval][xaxisval];
// handle stickiness
@@ -412,8 +412,8 @@ input_device_lightgun::input_device_lightgun(input_manager &manager, std::string
input_device_joystick::input_device_joystick(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal)
: input_device(manager, _name, _id, _internal),
- m_joystick_deadzone(s32(manager.machine().options().joystick_deadzone() * INPUT_ABSOLUTE_MAX)),
- m_joystick_saturation(s32(manager.machine().options().joystick_saturation() * INPUT_ABSOLUTE_MAX))
+ m_joystick_deadzone(s32(manager.machine().options().joystick_deadzone() * osd::INPUT_ABSOLUTE_MAX)),
+ m_joystick_saturation(s32(manager.machine().options().joystick_saturation() * osd::INPUT_ABSOLUTE_MAX))
{
// get the default joystick map
const char *mapstring = machine().options().joystick_map();
@@ -453,11 +453,11 @@ s32 input_device_joystick::adjust_absolute_value(s32 result) const
// if saturated, return the max
else if (result > m_joystick_saturation)
- result = INPUT_ABSOLUTE_MAX;
+ result = osd::INPUT_ABSOLUTE_MAX;
// otherwise, scale
else
- result = s64(result - m_joystick_deadzone) * s64(INPUT_ABSOLUTE_MAX) / s64(m_joystick_saturation - m_joystick_deadzone);
+ result = s64(result - m_joystick_deadzone) * s64(osd::INPUT_ABSOLUTE_MAX) / s64(m_joystick_saturation - m_joystick_deadzone);
// re-apply sign and return
return negative ? -result : result;
@@ -708,8 +708,8 @@ input_device_item::~input_device_item()
bool input_device_item::check_axis(input_item_modifier modifier, s32 memory)
{
- // use INVALID_AXIS_VALUE as a short-circuit
- return (memory != INVALID_AXIS_VALUE) && item_check_axis(modifier, memory);
+ // use osd::INVALID_AXIS_VALUE as a short-circuit
+ return (memory != osd::INVALID_AXIS_VALUE) && item_check_axis(modifier, memory);
}
@@ -894,7 +894,7 @@ bool input_device_relative_item::item_check_axis(input_item_modifier modifier, s
const s32 curval = read_as_relative(modifier);
// for relative axes, look for ~20 pixels movement
- return std::abs(curval - memory) > (20 * INPUT_RELATIVE_PER_PIXEL);
+ return std::abs(curval - memory) > (20 * osd::INPUT_RELATIVE_PER_PIXEL);
}
@@ -922,7 +922,7 @@ s32 input_device_absolute_item::read_as_switch(input_item_modifier modifier)
{
// start with the current value
s32 result = m_device.adjust_absolute(update_value());
- assert(result >= INPUT_ABSOLUTE_MIN && result <= INPUT_ABSOLUTE_MAX);
+ assert(result >= osd::INPUT_ABSOLUTE_MIN && result <= osd::INPUT_ABSOLUTE_MAX);
// left/right/up/down: if this is a joystick, fetch the paired X/Y axis values and convert
if (m_device.devclass() == DEVICE_CLASS_JOYSTICK && modifier >= ITEM_MODIFIER_LEFT && modifier <= ITEM_MODIFIER_DOWN)
@@ -977,7 +977,7 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier)
{
// start with the current value
s32 result = m_device.adjust_absolute(update_value());
- assert(result >= INPUT_ABSOLUTE_MIN && result <= INPUT_ABSOLUTE_MAX);
+ assert(result >= osd::INPUT_ABSOLUTE_MIN && result <= osd::INPUT_ABSOLUTE_MAX);
// if we're doing a lightgun reload hack, override the value
if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN && m_device.lightgun_reload_button())
@@ -985,16 +985,16 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier)
// if it is pressed, return (min,max)
input_device_item *button2_item = m_device.item(ITEM_ID_BUTTON2);
if (button2_item != nullptr && button2_item->update_value())
- result = (m_itemid == ITEM_ID_XAXIS) ? INPUT_ABSOLUTE_MIN : INPUT_ABSOLUTE_MAX;
+ result = (m_itemid == ITEM_ID_XAXIS) ? osd::INPUT_ABSOLUTE_MIN : osd::INPUT_ABSOLUTE_MAX;
}
// positive/negative: scale to full axis
if (modifier == ITEM_MODIFIER_REVERSE)
result = -result;
else if (modifier == ITEM_MODIFIER_POS)
- result = std::max(result, 0) * 2 + INPUT_ABSOLUTE_MIN;
+ result = std::max(result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN;
else if (modifier == ITEM_MODIFIER_NEG)
- result = std::max(-result, 0) * 2 + INPUT_ABSOLUTE_MIN;
+ result = std::max(-result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN;
return result;
}
@@ -1010,9 +1010,9 @@ bool input_device_absolute_item::item_check_axis(input_item_modifier modifier, s
// so the selection will not be affected by a gun going out of range
const s32 curval = read_as_absolute(modifier);
if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN &&
- (curval == INPUT_ABSOLUTE_MAX || curval == INPUT_ABSOLUTE_MIN))
+ (curval == osd::INPUT_ABSOLUTE_MAX || curval == osd::INPUT_ABSOLUTE_MIN))
return false;
// for absolute axes, look for 25% of maximum
- return std::abs(curval - memory) > ((INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN) / 4);
+ return std::abs(curval - memory) > ((osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN) / 4);
}
diff --git a/src/emu/inputdev.h b/src/emu/inputdev.h
index 1b6dabc9bab..78f2b6eeb95 100644
--- a/src/emu/inputdev.h
+++ b/src/emu/inputdev.h
@@ -13,29 +13,13 @@
#pragma once
-
-//**************************************************************************
-// CONSTANTS
-//**************************************************************************
-
-// relative devices return ~512 units per onscreen pixel
-constexpr s32 INPUT_RELATIVE_PER_PIXEL = 512;
-
-// absolute devices return values between -65536 and +65536
-constexpr s32 INPUT_ABSOLUTE_MIN = -65536;
-constexpr s32 INPUT_ABSOLUTE_MAX = 65536;
-
-// invalid memory value for axis polling
-constexpr s32 INVALID_AXIS_VALUE = 0x7fffffff;
+#include "interface/inputman.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-// callback for getting the value of an item on a device
-typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal);
-
// ======================> joystick_map
// a 9x9 joystick map
@@ -88,6 +72,8 @@ private:
class input_device_item
{
public:
+ using item_get_state_func = osd::input_device::item_get_state_func;
+
virtual ~input_device_item();
// getters
@@ -133,7 +119,7 @@ protected:
// ======================> input_device
// a logical device of a given class that can provide input
-class input_device
+class input_device : public osd::input_device
{
friend class input_class;
@@ -159,7 +145,7 @@ public:
void set_devindex(int devindex) { m_devindex = devindex; }
// item management
- input_item_id add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal = nullptr);
+ virtual input_item_id add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal) override;
// helpers
s32 adjust_absolute(s32 value) const { return adjust_absolute_value(value); }
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 76c48c05765..ac9309484d2 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -3357,8 +3357,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),
@@ -3401,7 +3401,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;
@@ -3420,7 +3420,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();
@@ -3456,8 +3456,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;
@@ -3468,7 +3468,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;
@@ -3492,11 +3492,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
@@ -3509,11 +3509,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;
}
}
}
@@ -3586,7 +3586,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)
@@ -3691,7 +3691,7 @@ void analog_field::frame_update(running_machine &machine)
// if port is positional, we will take the full analog control and divide it
// into positions, that way as the control is moved full scale,
// it moves through all the positions
- rawvalue = apply_scale(rawvalue - INPUT_ABSOLUTE_MIN, m_positionalscale) * INPUT_RELATIVE_PER_PIXEL + m_minimum;
+ rawvalue = apply_scale(rawvalue - osd::INPUT_ABSOLUTE_MIN, m_positionalscale) * osd::INPUT_RELATIVE_PER_PIXEL + m_minimum;
// clamp the high value so it does not roll over
rawvalue = std::min(rawvalue, m_maximum);
diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp
index cc69a542914..4605dbb82de 100644
--- a/src/emu/schedule.cpp
+++ b/src/emu/schedule.cpp
@@ -72,26 +72,36 @@ 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;
+
+ device_scheduler &scheduler = machine.scheduler();
+ m_start = 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)
register_save();
// insert into the list
- machine.scheduler().timer_list_insert(*this);
+ scheduler.timer_list_insert(*this);
+ if (this == scheduler.first_timer())
+ scheduler.abort_timeslice();
+
return *this;
}
@@ -202,6 +212,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 +220,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 +288,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 +296,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 +318,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 +565,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 +614,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());
+ if (timer.m_temporary)
+ {
+ 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 +763,50 @@ void device_scheduler::rebuild_execute_list()
inline emu_timer &device_scheduler::timer_list_insert(emu_timer &timer)
{
- // disabled timers sort to the end
- const attotime expire = timer.m_enabled ? timer.m_expire : attotime::never;
-
- // loop over the timer list
- emu_timer *prevtimer = nullptr;
- for (emu_timer *curtimer = m_timer_list; curtimer != nullptr; prevtimer = curtimer, curtimer = curtimer->next())
+ // disabled timers never expire
+ if (!timer.m_expire.is_never() && timer.m_enabled)
{
- // if the current list entry expires after us, we should be inserted before it
- if (curtimer->m_expire > expire)
+ // loop over the timer list
+ emu_timer *prevtimer = nullptr;
+ for (emu_timer *curtimer = m_timer_list; curtimer; prevtimer = curtimer, curtimer = curtimer->next())
{
- // link the new guy in before the current list entry
- timer.m_prev = prevtimer;
- timer.m_next = curtimer;
+ // if the current list entry expires after us, we should be inserted before it
+ if (curtimer->m_expire > timer.m_expire)
+ {
+ // link the new guy in before the current list entry
+ timer.m_prev = prevtimer;
+ timer.m_next = curtimer;
- if (prevtimer != nullptr)
- prevtimer->m_next = &timer;
- else
- m_timer_list = &timer;
+ if (prevtimer)
+ prevtimer->m_next = &timer;
+ else
+ m_timer_list = &timer;
- curtimer->m_prev = &timer;
- return timer;
+ curtimer->m_prev = &timer;
+ return timer;
+ }
}
- }
- // need to insert after the last one
- if (prevtimer != nullptr)
- prevtimer->m_next = &timer;
+ // need to insert after the last one
+ if (prevtimer)
+ prevtimer->m_next = &timer;
+ else
+ m_timer_list = &timer;
+
+ timer.m_prev = prevtimer;
+ timer.m_next = nullptr;
+ }
else
- m_timer_list = &timer;
+ {
+ // keep inactive timers in a separate list
+ if (m_inactive_timers)
+ m_inactive_timers->m_prev = &timer;
- timer.m_prev = prevtimer;
- timer.m_next = nullptr;
+ timer.m_next = m_inactive_timers;
+ timer.m_prev = nullptr;
+
+ m_inactive_timers = &timer;
+ }
return timer;
}
@@ -773,12 +819,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 +879,16 @@ inline void device_scheduler::execute_timers()
// reset or remove the timer, but only if it wasn't modified during the callback
if (!m_callback_timer_modified)
{
- // if the timer is temporary, remove it now
- if (timer.m_temporary)
- m_timer_allocator.reclaim(timer.release());
-
- // otherwise, reschedule it
- else
+ if (!timer.m_temporary)
+ {
+ // if the timer is not temporary, reschedule it
timer.schedule_next_period();
+ }
+ else
+ {
+ // otherwise, remove it now
+ m_timer_allocator.reclaim(timer.release());
+ }
}
}
diff --git a/src/emu/schedule.h b/src/emu/schedule.h
index dbaca005572..76b809aff63 100644
--- a/src/emu/schedule.h
+++ b/src/emu/schedule.h
@@ -45,7 +45,12 @@ class emu_timer
~emu_timer();
// allocation and re-use
- emu_timer &init(running_machine &machine, timer_expired_delegate &&callback, bool temporary) ATTR_HOT;
+ emu_timer &init(
+ running_machine &machine,
+ timer_expired_delegate &&callback,
+ attotime start_delay,
+ int param,
+ bool temporary) ATTR_HOT;
emu_timer &release();
public:
@@ -119,9 +124,15 @@ public:
// timers, specified by callback/name
emu_timer *timer_alloc(timer_expired_delegate callback);
[[deprecated("timer_set is deprecated; please avoid anonymous timers. Use TIMER_CALLBACK_MEMBER and an allocated emu_timer instead.")]]
- void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0);
+ void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0)
+ {
+ [[maybe_unused]] 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
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 88cdade710d..b74ff652b65 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -9,6 +9,7 @@
***************************************************************************/
#include "emu.h"
+
#include "speaker.h"
#include "emuopts.h"
#include "osdepend.h"
@@ -16,14 +17,14 @@
#include "wavwrite.h"
-
//**************************************************************************
// 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)
@@ -560,6 +561,7 @@ sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output
m_synchronous((flags & STREAM_SYNCHRONOUS) != 0),
m_resampling_disabled((flags & STREAM_DISABLE_INPUT_RESAMPLING) != 0),
m_sync_timer(nullptr),
+ m_last_update_end_time(attotime::zero),
m_input(inputs),
m_input_view(inputs),
m_empty_buffer(100),
@@ -578,8 +580,10 @@ sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output
// create a unique tag for saving
std::string state_tag = string_format("%d", m_device.machine().sound().unique_id());
auto &save = m_device.machine().save();
- save.save_item(&m_device, "stream.sample_rate", state_tag.c_str(), 0, NAME(m_sample_rate));
+ save.save_item(&m_device, "stream.sound_stream", state_tag.c_str(), 0, NAME(m_sample_rate));
+ save.save_item(&m_device, "stream.sound_stream", state_tag.c_str(), 0, NAME(m_last_update_end_time));
save.register_postload(save_prepost_delegate(FUNC(sound_stream::postload), this));
+ save.register_presave(save_prepost_delegate(FUNC(sound_stream::presave), this));
// initialize all inputs
for (unsigned int inputnum = 0; inputnum < m_input.size(); inputnum++)
@@ -648,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())
@@ -857,14 +861,24 @@ void sound_stream::sample_rate_changed()
void sound_stream::postload()
{
- // set the end time of all of our streams to now
+ // set the end time of all of our streams to the value saved in m_last_update_end_time
for (auto &output : m_output)
- output.set_end_time(m_device.machine().time());
+ output.set_end_time(m_last_update_end_time);
// recompute the sample rate information
sample_rate_changed();
}
+//-------------------------------------------------
+// presave - save/restore callback
+//-------------------------------------------------
+
+void sound_stream::presave()
+{
+ // save the stream end time
+ m_last_update_end_time = m_output[0].end_time();
+}
+
//-------------------------------------------------
// reprime_sync_timer - set up the next sync
@@ -1087,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
@@ -1459,7 +1473,7 @@ stream_buffer::sample_t sound_manager::adjust_toward_compressor_scale(stream_buf
void sound_manager::update(int param)
{
- VPRINTF(("sound_update\n"));
+ LOG("sound_update\n");
g_profiler.start(PROFILER_SOUND);
diff --git a/src/emu/sound.h b/src/emu/sound.h
index 658c956e5d4..15f6a5743a2 100644
--- a/src/emu/sound.h
+++ b/src/emu/sound.h
@@ -670,6 +670,9 @@ private:
// handle updates after a save state load
void postload();
+ // handle updates before a save state load
+ void presave();
+
// re-print the synchronization timer
void reprime_sync_timer();
@@ -693,6 +696,8 @@ private:
bool m_resampling_disabled; // is resampling of input streams disabled?
emu_timer *m_sync_timer; // update timer for synchronous streams
+ attotime m_last_update_end_time; // last end_time() in update
+
// input information
std::vector<sound_stream_input> m_input; // list of streams we directly depend upon
std::vector<read_stream_view> m_input_view; // array of output views for passing to the callback
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index 851fe572560..cef0cddf721 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -1707,10 +1707,8 @@ void cli_frontend::execute_commands(std::string_view exename)
path_iterator iter(m_options.plugins_path());
std::string pluginpath;
while (iter.next(pluginpath))
- {
- osd_subst_env(pluginpath, pluginpath);
- plugin_opts.scan_directory(pluginpath, true);
- }
+ plugin_opts.scan_directory(osd_subst_env(pluginpath), true);
+
emu_file file_plugin(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
if (file_plugin.open("plugin.ini"))
throw emu_fatalerror("Unable to create file plugin.ini\n");
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 5738e6f2cd2..fbfd3f0c829 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -716,13 +716,7 @@ void lua_engine::initialize()
static_cast<char const *(*)(char const *)>(&lang_translate),
static_cast<char const *(*)(char const *, char const *)>(&lang_translate));
emu["pid"] = &osd_getpid;
- emu["subst_env"] =
- [] (const std::string &str)
- {
- std::string result;
- osd_subst_env(result, str);
- return result;
- };
+ emu.set_function("subst_env", &osd_subst_env);
emu["device_enumerator"] = sol::overload(
[] (device_t &dev) { return devenum<device_enumerator>(dev); },
[] (device_t &dev, int maxdepth) { return devenum<device_enumerator>(dev, maxdepth); });
diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp
index f57bac1103a..6a8956401c6 100644
--- a/src/frontend/mame/mame.cpp
+++ b/src/frontend/mame/mame.cpp
@@ -143,7 +143,7 @@ void mame_machine_manager::start_luaengine()
while (iter.next(pluginpath))
{
// user may specify environment variables; subsitute them
- osd_subst_env(pluginpath, pluginpath);
+ pluginpath = osd_subst_env(pluginpath);
// and then scan the directory recursively
m_plugins->scan_directory(pluginpath, true);
@@ -204,8 +204,7 @@ void mame_machine_manager::start_luaengine()
std::error_condition const filerr = file.open("boot.lua");
if (!filerr)
{
- std::string exppath;
- osd_subst_env(exppath, file.fullpath());
+ const std::string exppath = osd_subst_env(file.fullpath());
auto &l(*lua());
auto load_result = l.load_script(exppath);
if (!load_result.valid())
diff --git a/src/frontend/mame/ui/inputdevices.cpp b/src/frontend/mame/ui/inputdevices.cpp
index e1e39f0467f..6dba1d49f92 100644
--- a/src/frontend/mame/ui/inputdevices.cpp
+++ b/src/frontend/mame/ui/inputdevices.cpp
@@ -58,12 +58,12 @@ protected:
s32 const value = (input.itemclass() == ITEM_CLASS_ABSOLUTE) ? input.read_as_absolute(ITEM_MODIFIER_NONE) : input.read_as_relative(ITEM_MODIFIER_NONE);
if (0 < value)
{
- float const fillright = indcentre + (float(value) / float(INPUT_ABSOLUTE_MAX) * (indright - indcentre));
+ float const fillright = indcentre + (float(value) / float(osd::INPUT_ABSOLUTE_MAX) * (indright - indcentre));
container().add_rect(indcentre, indtop, (std::min)(fillright, indright), indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
else if (0 > value)
{
- float const fillleft = indcentre - (float(value) / float(INPUT_ABSOLUTE_MIN) * (indcentre - indleft));
+ float const fillleft = indcentre - (float(value) / float(osd::INPUT_ABSOLUTE_MIN) * (indcentre - indleft));
container().add_rect((std::max)(fillleft, indleft), indtop, indcentre, indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
container().add_line(indleft, indtop, indright, indtop, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
diff --git a/src/lib/util/endianness.h b/src/lib/util/endianness.h
index cef615fcb87..d983afe8c6b 100644
--- a/src/lib/util/endianness.h
+++ b/src/lib/util/endianness.h
@@ -13,7 +13,11 @@
#pragma once
+#include <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); }
diff --git a/src/mame/drivers/abc1600.cpp b/src/mame/drivers/abc1600.cpp
index 876a041cdc5..39434dbb35c 100644
--- a/src/mame/drivers/abc1600.cpp
+++ b/src/mame/drivers/abc1600.cpp
@@ -1005,12 +1005,13 @@ void abc1600_state::abc1600(machine_config &config)
//-------------------------------------------------
ROM_START( abc1600 )
- ROM_REGION( 0x71c, "plds", 0 )
- ROM_LOAD( "1020 6490349-01.8b", 0x104, 0x104, CRC(1fa065eb) SHA1(20a95940e39fa98e97e59ea1e548ac2e0c9a3444) ) // PAL16L8A expansion bus strobes
- ROM_LOAD( "1021 6490350-01.5d", 0x208, 0x104, CRC(96f6f44b) SHA1(12d1cd153dcc99d1c4a6c834122f370d49723674) ) // PAL16L8 interrupt encoder and ROM/RAM control
- ROM_LOAD( "1023 6490352-01.11e", 0x410, 0x104, CRC(a2f350ac) SHA1(77e08654a197080fa2111bc3031cd2c7699bf82b) ) // PAL16R6 interrupt acknowledge
- ROM_LOAD( "1024 6490353-01.12e", 0x514, 0x104, CRC(67f1328a) SHA1(b585495fe14a7ae2fbb29f722dca106d59325002) ) // PAL16R4 expansion bus timing and control
- ROM_LOAD( "1025 6490354-01.6e", 0x618, 0x104, CRC(9bda0468) SHA1(ad373995dcc18532274efad76fa80bd13c23df25) ) // PAL16R4 DMA transfer
+ ROM_REGION( 0x860, "plds", 0 )
+ ROM_LOAD( "1020 6490349-01.8b", 0x104, 0x104, CRC(1fa065eb) SHA1(20a95940e39fa98e97e59ea1e548ac2e0c9a3444) ) // BUS INTERFACE X35
+ ROM_LOAD( "1021 6490350-01.5d", 0x208, 0x104, CRC(96f6f44b) SHA1(12d1cd153dcc99d1c4a6c834122f370d49723674) ) // X36 BOOT DECODE, MAP ACK PLUS INT PRIO
+ ROM_LOAD( "1023 6490352-01.11e", 0x410, 0x104, CRC(a2f350ac) SHA1(77e08654a197080fa2111bc3031cd2c7699bf82b) ) // X36 IO INTERFACE STROBE HANDLER
+ ROM_LOAD( "1024 6490353-01.12e", 0x514, 0x104, CRC(67f1328a) SHA1(b585495fe14a7ae2fbb29f722dca106d59325002) ) // X36 CHANNEL SELECT TIMER
+ ROM_LOAD( "1025 6490354-01.6e", 0x618, 0x104, CRC(9bda0468) SHA1(ad373995dcc18532274efad76fa80bd13c23df25) ) // X36 Z80A-DMA INTERFACER
+ ROM_LOAD( "1031", 0x71c, 0x144, CRC(0aedc9fc) SHA1(2cbbc7d5cb16b410d296062feb77ed26ff01af24) ) // NS32081 IN ABC1600
ROM_END
diff --git a/src/mame/drivers/blockch.cpp b/src/mame/drivers/blockch.cpp
index 346e13b5cab..4e370781f43 100644
--- a/src/mame/drivers/blockch.cpp
+++ b/src/mame/drivers/blockch.cpp
@@ -14,6 +14,9 @@ Hardware notes:
- discrete sound
- 15 switches (not the usual small dipswitches, but separate large switches)
+TV Game 8080 hardware is pretty much the same, but on a completely different
+cheaper looking PCB. It has 13 switches instead of 15.
+
TODO:
- missing paddle position read (or maybe ball vs paddle collision detection)
- interrupts are wrong, it looks like it expects IN.2 0x40 to be low for a while before the 2nd irq
@@ -22,6 +25,7 @@ TODO:
- identify remaining switches
- the flyer photo shows a green screen, assumed to be an overlay on a B&W CRT
- sound emulation
+- verify tvgm8080 title, the only reference is from the instruction card which said: TV.GAME -8080-
******************************************************************************/
@@ -296,6 +300,14 @@ ROM_START( blockch )
ROM_LOAD("4.59", 0x0c00, 0x0400, CRC(edf84910) SHA1(292aa16b5f23cae16c03fa7c0e711a5c2a04c27b))
ROM_END
+ROM_START( tvgm8080 )
+ ROM_REGION(0x10000, "maincpu", 0)
+ ROM_LOAD("1", 0x0000, 0x0400, CRC(1665afec) SHA1(f4ce9d834a396962d86cf8afd3c2d06ee1709ab6))
+ ROM_LOAD("2", 0x0400, 0x0400, CRC(86314a5e) SHA1(b1cf040fceee99d6e192a3506ce71a7a82e426bc))
+ ROM_LOAD("3", 0x0800, 0x0400, CRC(7c8d1319) SHA1(37613d4b8e2da7e91d436015124f1ef37011f910))
+ ROM_LOAD("4", 0x0c00, 0x0400, CRC(bf3423a8) SHA1(acfe811e2c2a20a306b054e58b0a7493d5d90ba6))
+ROM_END
+
} // anonymous namespace
@@ -304,5 +316,6 @@ ROM_END
Drivers
******************************************************************************/
-// YEAR NAME PARENT MACHINE INPUT CLASS INIT SCREEN COMPANY, FULLNAME, FLAGS
-GAME( 1978, blockch, 0, blockch, blockch, blockch_state, empty_init, ROT270, "Sun Electronics / Gifu Tokki", "G.T. Block Challenger", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL )
+// YEAR NAME PARENT MACHINE INPUT CLASS INIT SCREEN COMPANY, FULLNAME, FLAGS
+GAME( 1978, blockch, 0, blockch, blockch, blockch_state, empty_init, ROT270, "Sun Electronics / Gifu Tokki", "G.T. Block Challenger", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL )
+GAME( 1978, tvgm8080, blockch, blockch, blockch, blockch_state, empty_init, ROT270, "bootleg?", "TV Game 8080", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL )
diff --git a/src/mame/drivers/ds90.cpp b/src/mame/drivers/ds90.cpp
index 5fdcfa4be97..6b7a4ec7fe1 100644
--- a/src/mame/drivers/ds90.cpp
+++ b/src/mame/drivers/ds90.cpp
@@ -152,17 +152,17 @@ ROM_START( x37 )
ROM_REGION( 0x8000, MC68010_TAG, 0 )
ROM_LOAD( "x37.07o", 0x0000, 0x8000, CRC(d505e7e7) SHA1(a3ad839e47b1f71c394e5ce28bce199e5e4810d2) )
- ROM_REGION( 0x104, "plds", 0 )
- ROM_LOAD( "pat8003.12l", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8031.05h", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8032.07h", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8033.06h", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8034.12g", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8035.05g", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8036.07g", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8037.10k", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8038.04n", 0x000, 0x104, NO_DUMP )
- ROM_LOAD( "pat8039.12h", 0x000, 0x104, NO_DUMP )
+ ROM_REGION( 0xa28, "plds", 0 )
+ ROM_LOAD( "pat8003.12l", 0x000, 0x104, CRC(7c7b6dd1) SHA1(ab98fe70d589273b6a0437a818d9ae4bf9319ad5) ) // SCC decoder and clock multiplexor control
+ ROM_LOAD( "pat8031.05h", 0x104, 0x104, CRC(2836e65b) SHA1(305feb8dff7d6762f2ab50d25316ad43140456eb) ) // DS60 MAPPER CONTROL
+ ROM_LOAD( "pat8032.07h", 0x208, 0x104, CRC(356118d2) SHA1(e8e1dc6accdb8f0de481b91aa844f4b95f967826) ) // DS60 MAIN FUNCTION ENCODER
+ ROM_LOAD( "pat8033.06h", 0x30c, 0x104, CRC(5f61f902) SHA1(b151621af0d9e851437ef4e3a02ecb78a6e102dd) ) // DS60 RAM REFRESH AND MAPPER WRITE CONTROL
+ ROM_LOAD( "pat8034.12g", 0x410, 0x104, CRC(1105f161) SHA1(1923c0c954d3c812197d40f51bf3f53a158f87db) ) // DS60 CIO, SCC, FDC AND BOOTPROM CONTROLLER
+ ROM_LOAD( "pat8035.05g", 0x514, 0x104, CRC(f25be5d9) SHA1(ed51b5cedea34c81b8cbdefd994e13aabd44a036) ) // DS60 RAM DATA PATH CONTROL
+ ROM_LOAD( "pat8036.07g", 0x618, 0x104, CRC(350ff68e) SHA1(2d239bf324209adc7677eeb76b22c476ae0e6523) ) // DS60 RAM CONTROL SEQUENCER
+ ROM_LOAD( "pat8037.10k", 0x71c, 0x104, CRC(a0e818b3) SHA1(a0d49ba0f09e235b28037539044e133f777fa4c7) ) // DS60 SASI INTERFACE CONTROL
+ ROM_LOAD( "pat8038.04n", 0x820, 0x104, CRC(46ff5ce3) SHA1(c4a9025162b623bfcb74ac52f39de25bd53e448b) ) // DS60 PARITY GENERATION/DETECTION CONTROL
+ ROM_LOAD( "pat8039.12h", 0x924, 0x104, CRC(d3f6974f) SHA1(98dc1bac1c822fe7af0edd683acfc2e5c51f0451) ) // DS60 NS32081 FLOATING POINT PROCESSOR INTERFACE
ROM_END
COMP( 1985, x37, 0, 0, x37, x37, x37_state, empty_init, "Luxor", "X37 (prototype)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
diff --git a/src/mame/drivers/fidel_eag68k.cpp b/src/mame/drivers/fidel_eag68k.cpp
index 09f57056cec..45fa127fb21 100644
--- a/src/mame/drivers/fidel_eag68k.cpp
+++ b/src/mame/drivers/fidel_eag68k.cpp
@@ -560,7 +560,7 @@ void excel68k_state::fex68k(machine_config &config)
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
- m_board->set_delay(attotime::from_msec(150));
+ m_board->set_delay(attotime::from_msec(200));
/* video hardware */
PWM_DISPLAY(config, m_display).set_size(8, 16);
diff --git a/src/mame/drivers/igs017.cpp b/src/mame/drivers/igs017.cpp
index 174e072896f..77d76bec7af 100644
--- a/src/mame/drivers/igs017.cpp
+++ b/src/mame/drivers/igs017.cpp
@@ -3887,9 +3887,9 @@ INPUT_PORTS_END
static INPUT_PORTS_START( tarzan )
PORT_START("DSW1")
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:1")
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x01, DEF_STR( On ) )
+ PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:1")
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x0e, 0x0e, "Coin Value" ) PORT_DIPLOCATION("SW1:2,3,4")
PORT_DIPSETTING( 0x0e, "1" )
PORT_DIPSETTING( 0x0c, "2" )
diff --git a/src/mame/drivers/miconkit.cpp b/src/mame/drivers/miconkit.cpp
index 4ba1931d64f..4ed0ea5e99b 100644
--- a/src/mame/drivers/miconkit.cpp
+++ b/src/mame/drivers/miconkit.cpp
@@ -25,7 +25,7 @@ Hardware notes:
- beeper
TODO:
-- correct video timing
+- correct video timing, maybe 10MHz / 2 / (262*320)
- there's a 2-player start button on the cocktail cabinet, but where is it
hooked up, if at all? (when inserting 2 coins, the game automatically starts)
diff --git a/src/mame/drivers/mpu4.cpp b/src/mame/drivers/mpu4.cpp
index dd61303fc78..2be04458a11 100644
--- a/src/mame/drivers/mpu4.cpp
+++ b/src/mame/drivers/mpu4.cpp
@@ -2111,58 +2111,6 @@ void mpu4_state::init_m4default_big()
}
-uint8_t mpu4_state::crystal_sound_r()
-{
- return machine().rand();
-}
-//this may be a YMZ280B
-void mpu4_state::crystal_sound_w(uint8_t data)
-{
- logerror("crystal_sound_w %02x\n",data);
-}
-
-void mpu4_state::init_m_frkstn()
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- init_m4default();
- space.install_read_handler(0x0880, 0x0880, read8smo_delegate(*this, FUNC(mpu4_state::crystal_sound_r)));
- space.install_write_handler(0x0881, 0x0881, write8smo_delegate(*this, FUNC(mpu4_state::crystal_sound_w)));
-}
-
-// thanks to Project Amber for descramble information
-static void descramble_crystal( uint8_t* region, int start, int end, uint8_t extra_xor)
-{
- for (int i=start;i<end;i++)
- {
- uint8_t x = region[i];
- switch (i & 0x58)
- {
- case 0x00: // same as 0x08
- case 0x08: x = bitswap<8>( x^0xca , 3,2,1,0,7,4,6,5 ); break;
- case 0x10: x = bitswap<8>( x^0x30 , 3,0,4,6,1,5,7,2 ); break;
- case 0x18: x = bitswap<8>( x^0x89 , 4,1,2,5,7,0,6,3 ); break;
- case 0x40: x = bitswap<8>( x^0x14 , 6,1,4,3,2,5,0,7 ); break;
- case 0x48: x = bitswap<8>( x^0x40 , 1,0,3,2,5,4,7,6 ); break;
- case 0x50: x = bitswap<8>( x^0xcb , 3,2,1,0,7,6,5,4 ); break;
- case 0x58: x = bitswap<8>( x^0xc0 , 2,3,6,0,5,1,7,4 ); break;
- }
- region[i] = x ^ extra_xor;
- }
-}
-
-
-void mpu4_state::init_crystal()
-{
- init_m_frkstn();
- descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0x00);
-}
-
-void mpu4_state::init_crystali()
-{
- init_m_frkstn();
- descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0xff); // invert after decrypt?!
-}
-
/* generate a 50 Hz signal (based on an RC time) */
TIMER_DEVICE_CALLBACK_MEMBER(mpu4_state::gen_50hz)
{
diff --git a/src/mame/drivers/mpu4crystal.cpp b/src/mame/drivers/mpu4crystal.cpp
index df07f00c1b6..47c42a99915 100644
--- a/src/mame/drivers/mpu4crystal.cpp
+++ b/src/mame/drivers/mpu4crystal.cpp
@@ -17,9 +17,72 @@ public:
mpu4_state(mconfig, type, tag)
{
}
+
+ void init_crystali();
+ void init_crystal();
+ void init_m_frkstn();
+
+private:
+ uint8_t crystal_sound_r();
+ void crystal_sound_w(uint8_t data);
};
+uint8_t mpu4crystal_machines_state::crystal_sound_r()
+{
+ return machine().rand();
+}
+
+//this may be a YMZ280B
+void mpu4crystal_machines_state::crystal_sound_w(uint8_t data)
+{
+ logerror("crystal_sound_w %02x\n",data);
+}
+
+void mpu4crystal_machines_state::init_m_frkstn()
+{
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+ init_m4default();
+ space.install_read_handler(0x0880, 0x0880, read8smo_delegate(*this, FUNC(mpu4crystal_machines_state::crystal_sound_r)));
+ space.install_write_handler(0x0881, 0x0881, write8smo_delegate(*this, FUNC(mpu4crystal_machines_state::crystal_sound_w)));
+}
+
+// thanks to Project Amber for descramble information
+static void descramble_crystal(uint8_t* region, int start, int end, uint8_t extra_xor)
+{
+ for (int i=start;i<end;i++)
+ {
+ uint8_t x = region[i];
+ switch (i & 0x58)
+ {
+ case 0x00: // same as 0x08
+ case 0x08: x = bitswap<8>( x^0xca , 3,2,1,0,7,4,6,5 ); break;
+ case 0x10: x = bitswap<8>( x^0x30 , 3,0,4,6,1,5,7,2 ); break;
+ case 0x18: x = bitswap<8>( x^0x89 , 4,1,2,5,7,0,6,3 ); break;
+ case 0x40: x = bitswap<8>( x^0x14 , 6,1,4,3,2,5,0,7 ); break;
+ case 0x48: x = bitswap<8>( x^0x40 , 1,0,3,2,5,4,7,6 ); break;
+ case 0x50: x = bitswap<8>( x^0xcb , 3,2,1,0,7,6,5,4 ); break;
+ case 0x58: x = bitswap<8>( x^0xc0 , 2,3,6,0,5,1,7,4 ); break;
+ }
+ region[i] = x ^ extra_xor;
+ }
+}
+
+
+void mpu4crystal_machines_state::init_crystal()
+{
+ init_m_frkstn();
+ descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0x00);
+}
+
+void mpu4crystal_machines_state::init_crystali()
+{
+ init_m_frkstn();
+ descramble_crystal(memregion( "maincpu" )->base(), 0x0000, 0x10000, 0xff); // invert after decrypt?!
+}
+
+
+
#define M4FRKSTN_SOUND \
ROM_REGION( 0x40000, "upd", 0 ) \
ROM_LOAD("fr1snd.bin", 0x00000, 0x40000, CRC(2d77bbde) SHA1(0397ede538e913dc2972e260589022564fcd8fe4) )
diff --git a/src/mame/drivers/mpu4unsorted.cpp b/src/mame/drivers/mpu4unsorted.cpp
index e2cc15d7ea3..024bed06a94 100644
--- a/src/mame/drivers/mpu4unsorted.cpp
+++ b/src/mame/drivers/mpu4unsorted.cpp
@@ -2304,23 +2304,23 @@ GAME(199?, m4brnzeb, m4brnze, mod4oki, mpu4, mpu4unsorted_state, init_
/* *if* these are MPU4 they have a different sound system at least - The copyright strings in them are 'AET' tho (Ace?) - Could be related to the Crystal stuff? */
-GAME(199?, m4sbx, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 1)",GAME_FLAGS )
-GAME(199?, m4sbxa, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 2)",GAME_FLAGS )
-GAME(199?, m4sbxb, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 3)",GAME_FLAGS )
-GAME(199?, m4sbxc, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 4)",GAME_FLAGS )
-GAME(199?, m4sbxd, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 5)",GAME_FLAGS )
-GAME(199?, m4sbxe, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 6)",GAME_FLAGS )
-
-GAME(199?, m4bclimb, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Bear Climber (MPU4?)",GAME_FLAGS )
-GAME(199?, m4captb, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Captain Bear (MPU4?)",GAME_FLAGS )
-GAME(199?, m4jungj, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 1)",GAME_FLAGS )
-GAME(199?, m4jungja, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 2)",GAME_FLAGS )
-GAME(199?, m4jungjb, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 3)",GAME_FLAGS )
-GAME(199?, m4jungjc, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 4)",GAME_FLAGS )
-
-GAME(199?, m4fsx, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 1)",GAME_FLAGS )
-GAME(199?, m4fsxa, m4fsx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 2)",GAME_FLAGS )
-GAME(199?, m4fsxb, m4fsx, mpu4crys, mpu4, mpu4unsorted_state, init_m_frkstn, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 3)",GAME_FLAGS )
+GAME(199?, m4sbx, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 1)",GAME_FLAGS )
+GAME(199?, m4sbxa, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 2)",GAME_FLAGS )
+GAME(199?, m4sbxb, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 3)",GAME_FLAGS )
+GAME(199?, m4sbxc, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 4)",GAME_FLAGS )
+GAME(199?, m4sbxd, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 5)",GAME_FLAGS )
+GAME(199?, m4sbxe, m4sbx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Super Bear X (MPU4?) (set 6)",GAME_FLAGS )
+
+GAME(199?, m4bclimb, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Bear Climber (MPU4?)",GAME_FLAGS )
+GAME(199?, m4captb, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Captain Bear (MPU4?)",GAME_FLAGS )
+GAME(199?, m4jungj, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 1)",GAME_FLAGS )
+GAME(199?, m4jungja, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 2)",GAME_FLAGS )
+GAME(199?, m4jungjb, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 3)",GAME_FLAGS )
+GAME(199?, m4jungjc, m4jungj, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Jungle Japes (MPU4?) (set 4)",GAME_FLAGS )
+
+GAME(199?, m4fsx, 0, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 1)",GAME_FLAGS )
+GAME(199?, m4fsxa, m4fsx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 2)",GAME_FLAGS )
+GAME(199?, m4fsxb, m4fsx, mpu4crys, mpu4, mpu4unsorted_state, init_m4default, ROT0, "AET/Coinworld","Fun Spot X (MPU4?) (set 3)",GAME_FLAGS )
// Error 42 then 52, 54
GAME(199?, m4ccop, 0, mod4oki_cheatchr, mpu4_cw, mpu4unsorted_state, init_m4default, ROT0, "Coinworld","Cash Cops (MPU4?) (set 1)",GAME_FLAGS )
diff --git a/src/mame/drivers/namcos23.cpp b/src/mame/drivers/namcos23.cpp
index 659e6481d27..6878c402ef5 100644
--- a/src/mame/drivers/namcos23.cpp
+++ b/src/mame/drivers/namcos23.cpp
@@ -403,7 +403,7 @@ Notes:
C421 (QFP208)
C422 (QFP64)
C435 (x2, QFP144)
- C444 (QFP136)
+ C444 (QFP136) This replaces C403 from System 23 but likely integrates the 2x IDT7200 chips used on System 23 inside this custom chip.
C447 (QFP256)
Other ICs
@@ -515,7 +515,7 @@ Notes:
C421 (QFP208)
C422 (QFP64)
C435 (x2, QFP144)
- C444 (QFP136)
+ C444 (QFP136) This replaces C403 from System 23 but likely integrates the 2x IDT7200 chips used on System 23 inside this custom chip.
C447 (QFP256)
C450 (BGAxxx)
C451 (QFP208)
@@ -681,7 +681,7 @@ Notes:
Angler King AG1 Ver.A (for Super System 23)
GP500 5GP3 Ver.C (for Super System 23)
Time Crisis 2 TSS4 Ver.A (for Super System 23)
- Final Furlong 2 FFS1 Ver.? (for Super System 23)
+ Final Furlong 2 FFS1 Ver.A (for Super System 23)
Final Furlong 2 FFS2 Ver.? (for Super System 23)
Type 3:
@@ -1457,6 +1457,11 @@ public:
uint32_t m_tileid_mask;
uint32_t m_tile_mask;
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
private:
void update_main_interrupts(uint32_t cause);
void update_mixer();
@@ -1509,7 +1514,6 @@ private:
void c435_state_reset_w(uint16_t data);
TILE_GET_INFO_MEMBER(TextTilemapGetInfo);
- DECLARE_VIDEO_START(s23);
DECLARE_MACHINE_RESET(gmen);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(interrupt);
@@ -1558,9 +1562,6 @@ private:
void motoxgo_exio_map(address_map &map);
void timecrs2iobrdmap(address_map &map);
- virtual void machine_start() override;
- virtual void machine_reset() override;
-
required_device<mips3_device> m_maincpu;
required_device<h83002_device> m_subcpu;
required_device<h8_adc_device> m_adc;
@@ -2415,7 +2416,7 @@ void namcos23_state::textchar_w(offs_t offset, uint32_t data, uint32_t mem_mask)
// Video start/update callbacks
-VIDEO_START_MEMBER(namcos23_state,s23)
+void namcos23_state::video_start()
{
m_gfxdecode->gfx(0)->set_source(reinterpret_cast<uint8_t *>(m_charram.target()));
m_bgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(namcos23_state::TextTilemapGetInfo)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
@@ -3665,8 +3666,6 @@ void namcos23_state::gorgon(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_namcos23);
- MCFG_VIDEO_START_OVERRIDE(namcos23_state,s23)
-
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -3730,8 +3729,6 @@ void namcos23_state::s23(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_namcos23);
- MCFG_VIDEO_START_OVERRIDE(namcos23_state,s23)
-
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -3817,8 +3814,6 @@ void namcos23_state::ss23(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_namcos23);
- MCFG_VIDEO_START_OVERRIDE(namcos23_state,s23)
-
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -4703,7 +4698,7 @@ ROM_START( finfurl2 )
ROM_LOAD16_BYTE( "29f016.ic1", 0x000001, 0x200000, CRC(5b04e4f2) SHA1(8099fc3deab9ed14a2484a774666fbd928330de8) )
ROM_REGION( 0x80000, "subcpu", 0 ) /* Hitachi H8/3002 MCU code */
- ROM_LOAD16_WORD_SWAP( "m29f400.ic3", 0x000000, 0x080000, CRC(9fd69bbd) SHA1(53a9bf505de70495dcccc43fdc722b3381aad97c) )
+ ROM_LOAD16_WORD_SWAP( "ffs1vera.ic3", 0x000000, 0x080000, CRC(9fd69bbd) SHA1(53a9bf505de70495dcccc43fdc722b3381aad97c) )
ROM_REGION( 0x40000, "iocpu", 0 ) /* I/O board HD643334 H8/3334 MCU code */
ROM_LOAD( "asca-3a.ic14", 0x000000, 0x040000, CRC(8e9266e5) SHA1(ffa8782ca641d71d57df23ed1c5911db05d3df97) )
@@ -4744,11 +4739,11 @@ ROM_END
ROM_START( finfurl2j )
ROM_REGION32_BE( 0x400000, "user1", 0 ) /* 4 megs for main R4650 code */
- ROM_LOAD16_BYTE( "29f016_jap1.ic2", 0x000000, 0x200000, CRC(0215125d) SHA1(a99f601441c152b0b00f4811e5752c71897b1ed4) )
- ROM_LOAD16_BYTE( "29f016_jap1.ic1", 0x000001, 0x200000, CRC(38c9ae96) SHA1(b50afc7276662267ff6460f82d0e5e8b00b341ea) )
+ ROM_LOAD16_BYTE( "ffs1vera.ic2", 0x000000, 0x200000, CRC(0215125d) SHA1(a99f601441c152b0b00f4811e5752c71897b1ed4) )
+ ROM_LOAD16_BYTE( "ffs1vera.ic1", 0x000001, 0x200000, CRC(38c9ae96) SHA1(b50afc7276662267ff6460f82d0e5e8b00b341ea) )
ROM_REGION( 0x80000, "subcpu", 0 ) /* Hitachi H8/3002 MCU code */
- ROM_LOAD16_WORD_SWAP( "m29f400.ic3", 0x000000, 0x080000, CRC(9fd69bbd) SHA1(53a9bf505de70495dcccc43fdc722b3381aad97c) )
+ ROM_LOAD16_WORD_SWAP( "ffs1vera.ic3", 0x000000, 0x080000, CRC(9fd69bbd) SHA1(53a9bf505de70495dcccc43fdc722b3381aad97c) )
ROM_REGION( 0x40000, "iocpu", 0 ) /* I/O board HD643334 H8/3334 MCU code */
ROM_LOAD( "asca-3a.ic14", 0x000000, 0x040000, CRC(8e9266e5) SHA1(ffa8782ca641d71d57df23ed1c5911db05d3df97) )
@@ -5462,8 +5457,8 @@ GAME( 1998, gunwarsa, gunwars, gmen, s23, namcos23_state, init_
GAME( 1998, raceon, 0, gmen, s23, namcos23_state, init_s23, ROT0, "Namco", "Race On! (World, RO2 Ver. A)", GAME_FLAGS | MACHINE_NODEVICE_LAN )
GAME( 1998, 500gp, 0, ss23, s23, namcos23_state, init_s23, ROT0, "Namco", "500 GP (US, 5GP3 Ver. C)", GAME_FLAGS | MACHINE_NODEVICE_LAN )
GAME( 1998, aking, 0, ss23, s23, namcos23_state, init_s23, ROT0, "Namco", "Angler King (Japan, AG1 Ver. A)", GAME_FLAGS )
-GAME( 1998, finfurl2, 0, gmen, s23, namcos23_state, init_s23, ROT0, "Namco", "Final Furlong 2 (World)", GAME_FLAGS | MACHINE_NODEVICE_LAN )
-GAME( 1998, finfurl2j, finfurl2, gmen, s23, namcos23_state, init_s23, ROT0, "Namco", "Final Furlong 2 (Japan)", GAME_FLAGS | MACHINE_NODEVICE_LAN )
+GAME( 1998, finfurl2, 0, gmen, s23, namcos23_state, init_s23, ROT0, "Namco", "Final Furlong 2 (World)", GAME_FLAGS | MACHINE_NODEVICE_LAN ) // 99/02/26 15:08:47 Overseas
+GAME( 1998, finfurl2j, finfurl2, gmen, s23, namcos23_state, init_s23, ROT0, "Namco", "Final Furlong 2 (Japan, FFS1 Ver.A)", GAME_FLAGS | MACHINE_NODEVICE_LAN ) // 99/02/26 15:03:14 Japanese
GAME( 1999, crszone, 0, ss23e2, s23, namcos23_state, init_s23, ROT0, "Namco", "Crisis Zone (World, CSZO4 Ver. B)", GAME_FLAGS )
GAME( 1999, crszonev4a, crszone, ss23e2, s23, namcos23_state, init_s23, ROT0, "Namco", "Crisis Zone (World, CSZO4 Ver. A)", GAME_FLAGS )
GAME( 1999, crszonev3b, crszone, ss23e2, s23, namcos23_state, init_s23, ROT0, "Namco", "Crisis Zone (US, CSZO3 Ver. B, set 1)", GAME_FLAGS )
diff --git a/src/mame/drivers/plygonet.cpp b/src/mame/drivers/plygonet.cpp
index f4a28cffced..5134048f050 100644
--- a/src/mame/drivers/plygonet.cpp
+++ b/src/mame/drivers/plygonet.cpp
@@ -704,18 +704,18 @@ GFXDECODE_END
TILE_GET_INFO_MEMBER(polygonet_state::ttl_get_tile_info)
{
- const uint16_t *ttl_vram = (uint16_t *)&m_ttl_vram[0];
- const int code = ttl_vram[BYTE_XOR_BE(tile_index)] & 0xfff;
- const int attr = ttl_vram[BYTE_XOR_BE(tile_index)] >> 12; // Is the palette in all 4 bits?
+ const auto ttl_vram = util::big_endian_cast<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);
}
diff --git a/src/mame/drivers/seta.cpp b/src/mame/drivers/seta.cpp
index 19c28bbe171..66dfa46d243 100644
--- a/src/mame/drivers/seta.cpp
+++ b/src/mame/drivers/seta.cpp
@@ -8935,14 +8935,15 @@ void zombraid_state::machine_start()
void zombraid_state::zombraid(machine_config &config)
{
gundhara(config);
+ driver_device::static_set_callback(config.root_device(), driver_device::CB_MACHINE_START, driver_callback_delegate());
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &zombraid_state::zombraid_map);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
- adc0834_device &adc(ADC0834(config, "adc"));
- adc.set_input_callback(FUNC(zombraid_state::adc_cb));
+ ADC0834(config, m_adc);
+ m_adc->set_input_callback(FUNC(zombraid_state::adc_cb));
m_layers[0]->set_xoffsets(-2, -2); // correct for normal, flip screen not working yet
m_layers[1]->set_xoffsets(-2, -2);
diff --git a/src/mame/drivers/skylncr.cpp b/src/mame/drivers/skylncr.cpp
index bc3bea8700e..39bf6c1ba75 100644
--- a/src/mame/drivers/skylncr.cpp
+++ b/src/mame/drivers/skylncr.cpp
@@ -162,12 +162,14 @@ public:
void mbutrfly(machine_config &config);
void olymp(machine_config &config);
+ void init_butrfly();
void init_leadera();
void init_mbutrfly() { save_item(NAME(m_mbutrfly_prot)); }
void init_miaction();
void init_olymp();
void init_sonikfig();
void init_speedway();
+ void init_speedwaya();
void init_superb2k();
READ_LINE_MEMBER(mbutrfly_prot_r);
@@ -1804,9 +1806,9 @@ ROM_START( skylncr )
ROM_LOAD( "574200.u33", 0x00000, 0x80000, CRC(19b25221) SHA1(2f32d337125a9fd0bc7f50713b05e564fd4f81b2) )
ROM_END
-ROM_START( butrfly )
+ROM_START( butrfly ) // this has original Bordun copyright in ROMs and test mode in Chinese
ROM_REGION( 0x80000, "maincpu", 0 )
- ROM_LOAD( "butterfly.prg", 0x00000, 0x10000, CRC(b35b289c) SHA1(5a02bfb6e1fb608099b9f491c10795ef888a3b36) )
+ ROM_LOAD( "sub-pcb.bin", 0x00000, 0x10000, CRC(f5618f8e) SHA1(390b238821b195f444e69c45786617524e6f5394) )
ROM_REGION( 0x80000, "gfx1", 0 )
ROM_LOAD16_BYTE( "u29", 0x00000, 0x20000, CRC(2ff775ea) SHA1(2219c75cbac2969485607446ab116587bdee7278) )
@@ -1817,6 +1819,23 @@ ROM_START( butrfly )
ROM_REGION( 0x80000, "gfx2", 0 )
ROM_LOAD16_BYTE( "u52", 0x00000, 0x20000, CRC(15051537) SHA1(086c38c05c605f297a7bc470eb51763a7648e72c) )
ROM_LOAD16_BYTE( "u54", 0x00001, 0x20000, CRC(8e34d029) SHA1(ae316f2f34768938a07d62db110ce59d2751abaa) )
+ ROM_LOAD16_BYTE( "u56", 0x40000, 0x20000, CRC(226cb483) SHA1(89efa0e11700bcab0024a6058a5f1ee6b4a09953) )
+ ROM_LOAD16_BYTE( "u58", 0x40001, 0x20000, CRC(a69b5994) SHA1(f7f849c752740089a49dc6693822466d73010ea0) )
+ROM_END
+
+ROM_START( butrflybl ) // this has Bordun copyright removed and test mode in English
+ ROM_REGION( 0x80000, "maincpu", 0 )
+ ROM_LOAD( "butterfly.prg", 0x00000, 0x10000, CRC(b35b289c) SHA1(5a02bfb6e1fb608099b9f491c10795ef888a3b36) ) // Mata Electronic / Sen Xing Trading copyright instead of Bordun
+
+ ROM_REGION( 0x80000, "gfx1", 0 )
+ ROM_LOAD16_BYTE( "u29", 0x00000, 0x20000, CRC(2ff775ea) SHA1(2219c75cbac2969485607446ab116587bdee7278) )
+ ROM_LOAD16_BYTE( "u31", 0x00001, 0x20000, CRC(029d2214) SHA1(cf8256157db0b297ed457b3da6b6517907128843) )
+ ROM_LOAD16_BYTE( "u33", 0x40000, 0x20000, CRC(37bad677) SHA1(c077f0c07b097b376a01e5637446e4c4f82d9e28) )
+ ROM_LOAD16_BYTE( "u35", 0x40001, 0x20000, CRC(d14c7713) SHA1(c229ef64f3b0a04ff8e27bc56cff6a55ca34b80c) )
+
+ ROM_REGION( 0x80000, "gfx2", 0 ) // u56 and u58 are slightly modified to erase the Bordun copyright on the title screen
+ ROM_LOAD16_BYTE( "u52", 0x00000, 0x20000, CRC(15051537) SHA1(086c38c05c605f297a7bc470eb51763a7648e72c) )
+ ROM_LOAD16_BYTE( "u54", 0x00001, 0x20000, CRC(8e34d029) SHA1(ae316f2f34768938a07d62db110ce59d2751abaa) )
ROM_LOAD16_BYTE( "u56", 0x40000, 0x20000, CRC(a53daaef) SHA1(7b88bb986bd5e47576163d6999f8770c720c5bfc) )
ROM_LOAD16_BYTE( "u58", 0x40001, 0x20000, CRC(21ca47f8) SHA1(b192be06a2eb817776309580dc64fd76772a8d50) )
ROM_END
@@ -2204,6 +2223,57 @@ ROM_START( speedway ) // runs on a Rolla PCB with small sub board with main CPU,
ROM_LOAD16_BYTE( "8.u58", 0x40001, 0x20000, CRC(b93b221f) SHA1(efd6962a0f5e150c60d258fea116d726228dc39c) )
ROM_END
+ROM_START( speedwaya ) // runs on a Rolla PCB with small sub board with main CPU, ROM and Altera EPM. All ROMs differ quite a bit from the other set.
+ ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "sub.bin", 0x00000, 0x10000, CRC(78a6a047) SHA1(15b7b7e90ff2d2821edb081880be71fee4e222a8) ) //27C512
+
+ ROM_REGION( 0x80000, "gfx1", 0 )
+ ROM_LOAD16_BYTE( "1 sw.u29", 0x00000, 0x20000, CRC(998afc41) SHA1(509c70eee12a461b660abdc74a9dc8db181b76bd) )
+ ROM_LOAD16_BYTE( "2 sw.u31", 0x00001, 0x20000, CRC(f143376a) SHA1(83913a31c89f5e06cebb686e89246762753131b9) )
+ ROM_LOAD16_BYTE( "3 sw.u33", 0x40000, 0x20000, CRC(dea9a31c) SHA1(108dbee2a36ee2591a18be9a4336a1994370d612) )
+ ROM_LOAD16_BYTE( "4 sw.u35", 0x40001, 0x20000, CRC(3bc35ea6) SHA1(eafd67c2abec810d4a86564f4d5d34059013e6e9) )
+
+ ROM_REGION( 0x80000, "gfx2", 0 )
+ ROM_LOAD16_BYTE( "5 sw.u52", 0x00000, 0x20000, CRC(03af0672) SHA1(87fe8036ab270a5431751cfcccb4094372650173) )
+ ROM_LOAD16_BYTE( "6 sw.u54", 0x00001, 0x20000, CRC(5cc4c0a8) SHA1(4cf01c5f34674ab26834ed8f32751e74fe1df1e7) )
+ ROM_LOAD16_BYTE( "7 sw.u56", 0x40000, 0x20000, CRC(3adf8590) SHA1(7704e6b90567602497c52550bbd8831e876d1e5d) )
+ ROM_LOAD16_BYTE( "8 sw.u58", 0x40001, 0x20000, CRC(da21a487) SHA1(6bf7b97e682da9b97f3165a4d718cfdeeb3d956e) )
+ROM_END
+
+ROM_START( seadevil ) // on a POCKBOY REV.0 PCB
+ ROM_REGION( 0x80000, "maincpu", 0 )
+ ROM_LOAD( "v42 scr scm.u13", 0x00000, 0x10000, CRC(23b6eb48) SHA1(469d9f766ce96d2c850d611cd9a8b48545c71aaf) ) // on sub PCB, M27C512
+
+ ROM_REGION( 0x80000, "gfx1", 0 ) // all AM27C010
+ ROM_LOAD16_BYTE( "1.u26", 0x00000, 0x20000, CRC(e032f4f7) SHA1(accf48ce1447931ca7f7fdabe1684cabed03fe5f) )
+ ROM_LOAD16_BYTE( "2.u28", 0x00001, 0x20000, CRC(b8aa9742) SHA1(6c22ab987db6c10c8ae6c0278a5edc88b22fcb3a) )
+ ROM_LOAD16_BYTE( "3.u22", 0x40000, 0x20000, CRC(84a09db8) SHA1(6487e5bf97f43c6478c5b986587399213d7ff724) )
+ ROM_LOAD16_BYTE( "4.u24", 0x40001, 0x20000, CRC(d02354b9) SHA1(934663853c7d831eb4038c5f511acf2801b8be81) )
+
+ ROM_REGION( 0x80000, "gfx2", 0 ) // all AM27C010
+ ROM_LOAD16_BYTE( "5.u32", 0x00000, 0x20000, CRC(d079830f) SHA1(f12fad5c69545096255a9f79b1cf94bccf85320b) )
+ ROM_LOAD16_BYTE( "6.u36", 0x00001, 0x20000, CRC(4db80352) SHA1(21ebd6e0e9fc712ee2c9bc61d2493b4208410260) )
+ ROM_LOAD16_BYTE( "7.u30", 0x40000, 0x20000, CRC(64997653) SHA1(4328892974cbd2b42b864b01cd5d621a4a550bc6) )
+ ROM_LOAD16_BYTE( "8.u34", 0x40001, 0x20000, CRC(469f8fe2) SHA1(5d271ed0925eceff0d5d095d2443c666de69a58e) )
+ROM_END
+
+ROM_START( spcliner ) // on a ROLLA PCB, might actually be another title, won't know until palette is fixed. GFX ROM loading is wrong.
+ ROM_REGION( 0x80000, "maincpu", 0 )
+ ROM_LOAD( "9.sub", 0x00000, 0x10000, CRC(80f65def) SHA1(a0716d57ae4935a79d32971d0bcb9f40dd9f1d54) ) // on sub PCB
+
+ ROM_REGION( 0x80000, "gfx1", 0 )
+ ROM_LOAD16_BYTE( "5.u22", 0x40000, 0x20000, CRC(522132fb) SHA1(395530f137e19c177a276b6159f14fad66f25f75) )
+ ROM_LOAD16_BYTE( "6.u24", 0x40001, 0x20000, CRC(0ad80e17) SHA1(3a22f19d5aa329e666cc9a5f856723deaa575413) )
+ ROM_LOAD16_BYTE( "7.u26", 0x00000, 0x20000, CRC(1ab7559d) SHA1(57f93fa8da50f5fb6099f6fe0be656accc3eacb1) )
+ ROM_LOAD16_BYTE( "8.u28", 0x00001, 0x20000, CRC(2bdcb2e6) SHA1(08834ff52791934b705b77e59d0b12b3904d27cf) )
+
+ ROM_REGION( 0x80000, "gfx2", 0 )
+ ROM_LOAD16_BYTE( "1.u30", 0x40000, 0x20000, CRC(700831b4) SHA1(6b129a0f16bbae2b0d789ee4023db4e3af2c6b71) )
+ ROM_LOAD16_BYTE( "2.u32", 0x00000, 0x20000, CRC(8b770912) SHA1(89cfcc6f1d76c00b970cadfcc106f0fcd738ffa1) )
+ ROM_LOAD16_BYTE( "3.u34", 0x40001, 0x20000, CRC(c8e64ae1) SHA1(cd5859e857a7771b3b11215f120567eef53f72cb) )
+ ROM_LOAD16_BYTE( "4.u36", 0x00001, 0x20000, CRC(315e7e28) SHA1(c25ca2c9e4bf973cfe9e56a8dc849e53bdc1ebe3) )
+ROM_END
+
/**********************************
* Driver Init *
**********************************/
@@ -2357,6 +2427,16 @@ void skylncr_state::init_speedway() // TODO: complete this. These XORs and range
}
}
+void skylncr_state::init_speedwaya() // this was done by comparing with an ICE dump, should be correct.
+{
+ uint8_t *const ROM = memregion("maincpu")->base();
+
+ for (int x = 0x0000; x < 0x6500; x++)
+ ROM[x] ^= 0x40;
+
+ // 0x6500 - 0xffff isn't xored
+}
+
void skylncr_state::init_leadera()
{
uint8_t *const ROM = memregion("maincpu")->base();
@@ -2373,6 +2453,14 @@ void skylncr_state::init_leadera()
ROM[0x762a] = ROM[0x762b] = 0x00; // TODO: some minor protection? bypass for now
}
+void skylncr_state::init_butrfly()
+{
+ uint8_t *const ROM = memregion("maincpu")->base();
+
+ for (int x = 0x0000; x < 0x10000; x++)
+ ROM[x] = bitswap<8>(ROM[x] ^ 0x1b, 4, 2, 6, 7, 1, 5, 3, 0);
+}
+
} // Anonymous namespace
@@ -2380,22 +2468,26 @@ void skylncr_state::init_leadera()
* Game Drivers *
****************************************************/
-// YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS
-GAME( 1995, skylncr, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Bordun International", "Sky Lancer (Bordun, version U450C)", MACHINE_SUPPORTS_SAVE )
-GAME( 1995, butrfly, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Bordun International", "Butterfly Video Game (version U350C)", MACHINE_SUPPORTS_SAVE )
-GAME( 1999, mbutrfly, 0, mbutrfly, mbutrfly, skylncr_state, init_mbutrfly, ROT0, "Bordun International", "Magical Butterfly (version U350C, protected)", MACHINE_SUPPORTS_SAVE )
-GAME( 1995, madzoo, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Bordun International", "Mad Zoo (version U450C)", MACHINE_SUPPORTS_SAVE )
-GAME( 1995, leader, 0, skylncr, leader, skylncr_state, empty_init, ROT0, "bootleg", "Leader (version Z 2E, Greece)", MACHINE_SUPPORTS_SAVE )
-GAME( 1995, leadera, leader, skylncr, leader, skylncr_state, init_leadera, ROT0, "bootleg", "Leader (version Z 2F, Greece)", MACHINE_UNEMULATED_PROTECTION | MACHINE_SUPPORTS_SAVE ) // Needs correct protection emulation instead of ROM patch
-GAME( 199?, speedway, 0, olymp, leader, skylncr_state, init_speedway, ROT0, "hack (Drivers)", "Speedway", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Incomplete decryption (?)
-GAME( 199?, gallag50, 0, skylncr, gallag50, skylncr_state, empty_init, ROT0, "bootleg", "Gallag Video Game / Petalouda (Butterfly, x50)", MACHINE_SUPPORTS_SAVE )
-GAME( 199?, neraidou, 0, neraidou, neraidou, skylncr_state, empty_init, ROT0, "bootleg", "Neraidoula", MACHINE_SUPPORTS_SAVE )
-GAME( 199?, miaction, 0, skylncr, skylncr, skylncr_state, init_miaction, ROT0, "Vegas", "Missing In Action", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
-GAME( 199?, tigerslt, 0, skylncr, skylncr, skylncr_state, init_miaction, ROT0, "bootleg", "Tiger (slot)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
-GAME( 199?, sstar97, 0, sstar97, sstar97, skylncr_state, empty_init, ROT0, "Bordun International", "Super Star 97 / Ming Xing 97 (version V153B)", MACHINE_SUPPORTS_SAVE )
-GAME( 1995, bdream97, 0, bdream97, skylncr, skylncr_state, empty_init, ROT0, "bootleg (KKK)", "Hudie Meng 97", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
-GAME( 2000?,olymp, 0, olymp, skylncr, skylncr_state, init_olymp, ROT0, "Z Games", "Olympus (Z Games, version 10)", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Still has Bordun International 1992 strings
-GAME( 2000, sonikfig, 0, skylncr, sonikfig, skylncr_state, init_sonikfig, ROT0, "Z Games", "Sonik Fighter (version 02, encrypted)", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
-GAME( 199?, rolla, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Random Games", "unknown 'Rolla' slot machine", MACHINE_IS_SKELETON ) // internal CPU ROM not dumped
-GAME( 2000?,score5, 0, skylncr, score5, skylncr_state, init_sonikfig, ROT0, "Z Games", "Score 5", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // game runs but screen is completely black due to palette mishandling
-GAME( 2000?,superb2k, 0, skylncr, skylncr, skylncr_state, init_superb2k, ROT0, "Random Games", "Super Butterfly 2000", MACHINE_IS_SKELETON ) // encrypted / different CPU type ?
+// YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS
+GAME( 1995, skylncr, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Bordun International", "Sky Lancer (Bordun, version U450C)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, butrfly, 0, skylncr, skylncr, skylncr_state, init_butrfly, ROT0, "Bordun International", "Butterfly Video Game (version A00)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, butrflybl, butrfly, skylncr, skylncr, skylncr_state, empty_init, ROT0, "bootleg", "Butterfly Video Game (version U350C)", MACHINE_SUPPORTS_SAVE )
+GAME( 1999, mbutrfly, 0, mbutrfly, mbutrfly, skylncr_state, init_mbutrfly, ROT0, "Bordun International", "Magical Butterfly (version U350C, protected)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, madzoo, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Bordun International", "Mad Zoo (version U450C)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, leader, 0, skylncr, leader, skylncr_state, empty_init, ROT0, "bootleg", "Leader (version Z 2E, Greece)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, leadera, leader, skylncr, leader, skylncr_state, init_leadera, ROT0, "bootleg", "Leader (version Z 2F, Greece)", MACHINE_UNEMULATED_PROTECTION | MACHINE_SUPPORTS_SAVE ) // Needs correct protection emulation instead of ROM patch
+GAME( 199?, speedway, 0, olymp, leader, skylncr_state, init_speedway, ROT0, "hack (Drivers)", "Speedway (set 1)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Incomplete decryption (?)
+GAME( 199?, speedwaya, speedway, skylncr, leader, skylncr_state, init_speedwaya, ROT0, "hack", "Speedway (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Decryption should be correct (unless ICE dump was bad), but doesn't boot
+GAME( 199?, gallag50, 0, skylncr, gallag50, skylncr_state, empty_init, ROT0, "bootleg", "Gallag Video Game / Petalouda (Butterfly, x50)", MACHINE_SUPPORTS_SAVE )
+GAME( 199?, neraidou, 0, neraidou, neraidou, skylncr_state, empty_init, ROT0, "bootleg", "Neraidoula", MACHINE_SUPPORTS_SAVE )
+GAME( 199?, miaction, 0, skylncr, skylncr, skylncr_state, init_miaction, ROT0, "Vegas", "Missing In Action", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
+GAME( 199?, tigerslt, 0, skylncr, skylncr, skylncr_state, init_miaction, ROT0, "bootleg", "Tiger (slot)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
+GAME( 199?, sstar97, 0, sstar97, sstar97, skylncr_state, empty_init, ROT0, "Bordun International", "Super Star 97 / Ming Xing 97 (version V153B)", MACHINE_SUPPORTS_SAVE )
+GAME( 1995, bdream97, 0, bdream97, skylncr, skylncr_state, empty_init, ROT0, "bootleg (KKK)", "Hudie Meng 97", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
+GAME( 2000?,olymp, 0, olymp, skylncr, skylncr_state, init_olymp, ROT0, "Z Games", "Olympus (Z Games, version 10)", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Still has Bordun International 1992 strings
+GAME( 2000, sonikfig, 0, skylncr, sonikfig, skylncr_state, init_sonikfig, ROT0, "Z Games", "Sonik Fighter (version 02, encrypted)", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
+GAME( 2000, spcliner, 0, skylncr, sonikfig, skylncr_state, init_sonikfig, ROT0, "Z Games", "Space Liner", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // game runs but screen is completely black due to palette mishandling
+GAME( 199?, rolla, 0, skylncr, skylncr, skylncr_state, empty_init, ROT0, "Random Games", "unknown 'Rolla' slot machine", MACHINE_IS_SKELETON ) // internal CPU ROM not dumped
+GAME( 2000?,score5, 0, skylncr, score5, skylncr_state, init_sonikfig, ROT0, "Z Games", "Score 5", MACHINE_WRONG_COLORS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // game runs but screen is completely black due to palette mishandling
+GAME( 2000?,superb2k, 0, skylncr, skylncr, skylncr_state, init_superb2k, ROT0, "Random Games", "Super Butterfly 2000", MACHINE_IS_SKELETON ) // encrypted / different CPU type ?
+GAME( 2000, seadevil, 0, skylncr, score5, skylncr_state, init_sonikfig, ROT0, "Z Games", "Sea Devil", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // GFX ROM loading is wrong, causing severe GFX glitches
diff --git a/src/mame/drivers/sshangha.cpp b/src/mame/drivers/sshangha.cpp
index 1d754b723aa..8694589e4a5 100644
--- a/src/mame/drivers/sshangha.cpp
+++ b/src/mame/drivers/sshangha.cpp
@@ -393,7 +393,9 @@ void sshangha_state::sshangha(machine_config &config)
PALETTE(config, m_palette).set_format(palette_device::xBGR_888, 0x4000/4);
DECO16IC(config, m_tilegen, 0);
- m_tilegen->set_pf1_size(DECO_64x32);
+ // requires pf1 to be 64x64 for the ending screen to be displayed properly
+ // TODO: confirm arrangement, game barely uses scrolling otherwise
+ m_tilegen->set_pf1_size(DECO_64x64);
m_tilegen->set_pf2_size(DECO_64x32);
m_tilegen->set_pf1_col_bank(0x10);
m_tilegen->set_pf2_col_bank(0x30);
@@ -545,14 +547,14 @@ void sshangha_state::init_sshangha()
#if SSHANGHA_HACK
/* This is a hack to allow you to use the extra features
of the first "Unused" Dip Switch (see notes above). */
- uint16_t *RAM = (uint16_t *)memregion("maincpu")->base();
- RAM[0x000384/2] = 0x4e71;
- RAM[0x000386/2] = 0x4e71;
- RAM[0x000388/2] = 0x4e71;
- RAM[0x00038a/2] = 0x4e71;
+ uint16_t *ROM = (uint16_t *)memregion("maincpu")->base();
+ ROM[0x000384/2] = 0x4e71;
+ ROM[0x000386/2] = 0x4e71;
+ ROM[0x000388/2] = 0x4e71;
+ ROM[0x00038a/2] = 0x4e71;
/* To avoid checksum error (only useful for 'sshangha') */
- RAM[0x000428/2] = 0x4e71;
- RAM[0x00042a/2] = 0x4e71;
+ ROM[0x000428/2] = 0x4e71;
+ ROM[0x00042a/2] = 0x4e71;
#endif
}
diff --git a/src/mame/includes/mpu4.h b/src/mame/includes/mpu4.h
index a3f208d3730..30a241d3764 100644
--- a/src/mame/includes/mpu4.h
+++ b/src/mame/includes/mpu4.h
@@ -145,10 +145,8 @@ public:
void init_m4default_big_aux2inv();
void init_m4default_806prot();
- void init_crystali();
void init_m4tst2();
- void init_crystal();
- void init_m_frkstn();
+
void init_m4default_banks();
void init_m4default_reels();
void init_m4_low_volt_alt();
@@ -405,8 +403,7 @@ protected:
void mpu4_ym2413_w(offs_t offset, uint8_t data);
uint8_t mpu4_ym2413_r(offs_t offset);
- uint8_t crystal_sound_r();
- void crystal_sound_w(uint8_t data);
+
void ic3ss_w(offs_t offset, uint8_t data);
DECLARE_WRITE_LINE_MEMBER(cpu0_irq);
DECLARE_WRITE_LINE_MEMBER(ic2_o1_callback);
diff --git a/src/mame/machine/abc1600mac.cpp b/src/mame/machine/abc1600mac.cpp
index 991962e96e1..b8c66c271ae 100644
--- a/src/mame/machine/abc1600mac.cpp
+++ b/src/mame/machine/abc1600mac.cpp
@@ -70,7 +70,7 @@ ROM_START( abc1600_mac )
ROM_LOAD( "boot 6490356-04.1f", 0x0000, 0x4000, CRC(9372f6f2) SHA1(86f0681f7ef8dd190b49eda5e781881582e0c2a4) )
ROM_REGION( 0x104, "plds", 0 )
- ROM_LOAD( "1022 6490351-01.17e", 0x000, 0x104, CRC(5dd00d43) SHA1(a3871f0d796bea9df8f25d41b3169dd4b8ef65ab) ) // PAL16L8 MAC register address decoder
+ ROM_LOAD( "1022 6490351-01.17e", 0x000, 0x104, CRC(5dd00d43) SHA1(a3871f0d796bea9df8f25d41b3169dd4b8ef65ab) ) // X36 SEGMENT-PAGE MAP R/W STROBE HANDLER
ROM_END
diff --git a/src/mame/machine/igs022.cpp b/src/mame/machine/igs022.cpp
index 7340e4eef84..8f6a4291d61 100644
--- a/src/mame/machine/igs022.cpp
+++ b/src/mame/machine/igs022.cpp
@@ -341,6 +341,7 @@ void igs022_device::handle_command_6d()
const u32 res = data1 + data2;
write_reg(dst, res);
+
if (VERBOSE & LOG_CMD_6D)
util::stream_format(stream, "ADD [%04x] = [%04x] + [%04x] (%08x)\n", dst, src1, src2, res);
break;
diff --git a/src/mame/machine/mpu4_characteriser_bootleg.cpp b/src/mame/machine/mpu4_characteriser_bootleg.cpp
index e26205b38dd..62dbb19e9bf 100644
--- a/src/mame/machine/mpu4_characteriser_bootleg.cpp
+++ b/src/mame/machine/mpu4_characteriser_bootleg.cpp
@@ -20,9 +20,7 @@ mpu4_characteriser_bl::mpu4_characteriser_bl(const machine_config &mconfig, cons
}
mpu4_characteriser_bl::mpu4_characteriser_bl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, type, tag, owner, clock),
- m_cpu(*this, finder_base::DUMMY_TAG),
- m_allow_6809_cheat(false)
+ device_t(mconfig, type, tag, owner, clock)
{
}
diff --git a/src/mame/machine/mpu4_characteriser_bootleg.h b/src/mame/machine/mpu4_characteriser_bootleg.h
index 70402a4172b..85496f437ee 100644
--- a/src/mame/machine/mpu4_characteriser_bootleg.h
+++ b/src/mame/machine/mpu4_characteriser_bootleg.h
@@ -20,17 +20,6 @@ class mpu4_characteriser_bl : public device_t
public:
// construction/destruction
mpu4_characteriser_bl(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- mpu4_characteriser_bl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- template <typename T> void set_cpu_tag(T&& tag)
- {
- m_cpu.set_tag(std::forward<T>(tag));
- }
-
- void set_allow_6809_cheat(bool allow)
- {
- m_allow_6809_cheat = allow;
- }
void set_bl_fixed_return(uint8_t ret)
{
@@ -49,12 +38,12 @@ public:
}
protected:
+ mpu4_characteriser_bl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
virtual void device_start() override;
virtual void device_reset() override;
private:
- optional_device<cpu_device> m_cpu; // needed for some of the protection 'cheats'
- bool m_allow_6809_cheat;
uint8_t m_blfixedreturn = 0;
};
diff --git a/src/mame/machine/pgmprot_igs027a_type1.cpp b/src/mame/machine/pgmprot_igs027a_type1.cpp
index ecc4e8e0a22..e871c987868 100644
--- a/src/mame/machine/pgmprot_igs027a_type1.cpp
+++ b/src/mame/machine/pgmprot_igs027a_type1.cpp
@@ -66,58 +66,32 @@
/**************************** EMULATION *******************************/
/* used by photoy2k, kovsh */
-u16 pgm_arm_type1_state::arm7_type1_protlatch_r(offs_t offset)
+u32 pgm_arm_type1_state::arm7_type1_protlatch_r()
{
- if (!machine().side_effects_disabled())
- machine().scheduler().synchronize(); // force resync
-
- if (offset & 1)
- return m_arm_type1_highlatch_68k_w;
- else
- return m_arm_type1_lowlatch_68k_w;
+ return m_arm_type1_latch_68k_w;
}
-void pgm_arm_type1_state::arm7_type1_protlatch_w(offs_t offset, u16 data)
+void pgm_arm_type1_state::arm7_type1_protlatch_w(offs_t, u32 data, u32 mem_mask)
{
- machine().scheduler().synchronize(); // force resync
-
- if (offset & 1)
- {
- m_arm_type1_highlatch_arm_w = data;
- m_arm_type1_highlatch_68k_w = 0;
- }
- else
- {
- m_arm_type1_lowlatch_arm_w = data;
- m_arm_type1_lowlatch_68k_w = 0;
- }
+ COMBINE_DATA(&m_arm_type1_latch_arm_w);
+ m_arm_type1_latch_68k_w &= ~mem_mask;
}
u16 pgm_arm_type1_state::arm7_type1_68k_protlatch_r(offs_t offset)
{
- if (!machine().side_effects_disabled())
- machine().scheduler().synchronize(); // force resync
-
- switch (offset)
- {
- case 1: return m_arm_type1_highlatch_arm_w;
- case 0: return m_arm_type1_lowlatch_arm_w;
- }
- return -1;
+ return offset ? m_arm_type1_latch_arm_w >> 16 : m_arm_type1_latch_arm_w;
}
void pgm_arm_type1_state::arm7_type1_68k_protlatch_w(offs_t offset, u16 data)
{
- machine().scheduler().synchronize(); // force resync
-
switch (offset)
{
case 1:
- m_arm_type1_highlatch_68k_w = data;
+ m_arm_type1_latch_68k_w = (m_arm_type1_latch_68k_w & 0x0000ffff) | (data << 16);
break;
case 0:
- m_arm_type1_lowlatch_68k_w = data;
+ m_arm_type1_latch_68k_w = (m_arm_type1_latch_68k_w & 0xffff0000) | data;
break;
}
}
@@ -176,7 +150,7 @@ void pgm_arm_type1_state::kov_map(address_map &map)
pgm_mem(map);
map(0x100000, 0x4effff).bankr("bank1"); /* Game ROM */
map(0x4f0000, 0x4f003f).rw(FUNC(pgm_arm_type1_state::arm7_type1_ram_r), FUNC(pgm_arm_type1_state::arm7_type1_ram_w)); /* ARM7 Shared RAM */
- map(0x500000, 0x500005).rw(FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_r), FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_w)); /* ARM7 Latch */
+ map(0x500000, 0x500003).rw(FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_r), FUNC(pgm_arm_type1_state::arm7_type1_68k_protlatch_w)); /* ARM7 Latch */
}
void pgm_arm_type1_state::_55857E_arm7_map(address_map &map)
@@ -247,16 +221,12 @@ void pgm_arm_type1_state::pgm_arm_type1_cave(machine_config &config)
void pgm_arm_type1_state::arm7_type1_latch_init()
{
- m_arm_type1_highlatch_arm_w = 0;
- m_arm_type1_lowlatch_arm_w = 0;
- m_arm_type1_highlatch_68k_w = 0;
- m_arm_type1_lowlatch_68k_w = 0;
+ m_arm_type1_latch_arm_w = 0;
+ m_arm_type1_latch_68k_w = 0;
m_arm_type1_counter = 1;
- save_item(NAME(m_arm_type1_highlatch_arm_w));
- save_item(NAME(m_arm_type1_lowlatch_arm_w));
- save_item(NAME(m_arm_type1_highlatch_68k_w));
- save_item(NAME(m_arm_type1_lowlatch_68k_w));
+ save_item(NAME(m_arm_type1_latch_arm_w));
+ save_item(NAME(m_arm_type1_latch_68k_w));
save_item(NAME(m_arm_type1_counter));
}
@@ -294,7 +264,7 @@ void pgm_arm_type1_state::kovshp_asic27a_write_word(offs_t offset, u16 data)
switch (offset)
{
case 0:
- m_arm_type1_lowlatch_68k_w = data;
+ m_arm_type1_latch_68k_w = (m_arm_type1_latch_68k_w & 0xffff0000) |data;
return;
case 1:
@@ -341,7 +311,7 @@ void pgm_arm_type1_state::kovshp_asic27a_write_word(offs_t offset, u16 data)
case 0xf8: asic_cmd = 0xf3; break;
}
- m_arm_type1_highlatch_68k_w = asic_cmd ^ (asic_key | (asic_key << 8));
+ m_arm_type1_latch_68k_w = (m_arm_type1_latch_68k_w & 0x0000ffff) | ((asic_cmd ^ (asic_key | (asic_key << 8))) << 16);
}
return;
}
diff --git a/src/mame/machine/pgmprot_igs027a_type1.h b/src/mame/machine/pgmprot_igs027a_type1.h
index f1cbe7ffb98..3bf5c699550 100644
--- a/src/mame/machine/pgmprot_igs027a_type1.h
+++ b/src/mame/machine/pgmprot_igs027a_type1.h
@@ -64,18 +64,16 @@ private:
pgm_arm_sim_command_handler arm_sim_handler{};
/////////////// emulation
- u16 m_arm_type1_highlatch_arm_w = 0;
- u16 m_arm_type1_lowlatch_arm_w = 0;
- u16 m_arm_type1_highlatch_68k_w = 0;
- u16 m_arm_type1_lowlatch_68k_w = 0;
+ u32 m_arm_type1_latch_arm_w = 0;
+ u32 m_arm_type1_latch_68k_w = 0;
u32 m_arm_type1_counter = 0;
optional_shared_ptr<u32> m_arm7_shareram;
optional_device<cpu_device> m_prot;
DECLARE_MACHINE_START(pgm_arm_type1);
- u16 arm7_type1_protlatch_r(offs_t offset);
- void arm7_type1_protlatch_w(offs_t offset, u16 data);
+ u32 arm7_type1_protlatch_r();
+ void arm7_type1_protlatch_w(offs_t offset, u32 data, u32 mem_mask);
u16 arm7_type1_68k_protlatch_r(offs_t offset);
void arm7_type1_68k_protlatch_w(offs_t offset, u16 data);
u16 arm7_type1_ram_r(offs_t offset, u16 mem_mask = ~0);
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index a64039e77c9..8bef0b4aef6 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -9515,6 +9515,7 @@ mineswpr4 // [1977 Amutech]
@source:blockch.cpp
blockch
+tvgm8080
@source:blockhl.cpp
blockhl // GX973 (c) 1989
@@ -26317,8 +26318,8 @@ m4suptub // Super Tubes (Barcrest)
m4suptuba //
m4suptwo // Super Two (Barcrest)
m4swpnot // Swap-A-Note (Barcrest)
-m4swpnota //
-m4swpnotb //
+m4swpnota //
+m4swpnotb //
m4taj // Taj Mahal (Barcrest)
m4take2 // Take Two (Barcrest)
m4take2a //
@@ -29804,7 +29805,7 @@ m4sss__j //
m4sss__k //
m4sss__l //
m4sstrek // Super Streak (bootleg)
-m4stc //
+m4stc //
m4shv // Super Hyper Viper (Barcrest)
m4shv__0
m4shv__1
@@ -29819,7 +29820,7 @@ m4shv__6
m4shv__7
m4shv__8
m4shv__9
-m4shv__a
+m4shv__a
m4shv__b
m4shv__c
m4shv__d
@@ -39088,6 +39089,7 @@ skykids // (c) 1985
@source:skylncr.cpp
bdream97 // Bootleg?
butrfly // (c) 1995 Bordun International
+butrflybl // Bootleg
gallag50 // Bootleg?
leader // Bootleg?
leadera // Bootleg?
@@ -39098,9 +39100,12 @@ neraidou // Bootleg?
olymp // Z Games
rolla //
score5 // Z Games
+seadevil // Z Games
skylncr // (c) 1995 Bordun International
sonikfig // Z Games
+spcliner // Z Games
speedway //
+speedwaya //
sstar97 // (c) 199? Bordun International
superb2k // Random Games
tigerslt // Bootleg?
diff --git a/src/osd/interface/inputcode.h b/src/osd/interface/inputcode.h
new file mode 100644
index 00000000000..1d5b1156ae5
--- /dev/null
+++ b/src/osd/interface/inputcode.h
@@ -0,0 +1,872 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ inputcode.h
+
+ Codes for representing host inputs
+
+***************************************************************************/
+#ifndef MAME_OSD_INTERFACE_INPUTCODE_H
+#define MAME_OSD_INTERFACE_INPUTCODE_H
+
+#pragma once
+
+#include "osdcomm.h"
+
+#include <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
diff --git a/src/osd/interface/inputman.h b/src/osd/interface/inputman.h
new file mode 100644
index 00000000000..223c9a6926d
--- /dev/null
+++ b/src/osd/interface/inputman.h
@@ -0,0 +1,77 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ inputman.h
+
+ OSD interface to the input manager.
+
+***************************************************************************/
+#ifndef MAME_OSD_INTERFACE_INPUTMAN_H
+#define MAME_OSD_INTERFACE_INPUTMAN_H
+
+#pragma once
+
+#include "inputcode.h"
+
+#include <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
diff --git a/src/osd/interface/inputseq.cpp b/src/osd/interface/inputseq.cpp
new file mode 100644
index 00000000000..da1f2b98b26
--- /dev/null
+++ b/src/osd/interface/inputseq.cpp
@@ -0,0 +1,210 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ inputseq.cpp
+
+ A combination of hosts inputs that can be assigned to a control.
+
+***************************************************************************/
+
+#include "inputseq.h"
+
+
+namespace osd {
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+// additional expanded input codes for sequences
+constexpr input_code input_seq::end_code;
+constexpr input_code input_seq::default_code;
+constexpr input_code input_seq::not_code;
+constexpr input_code input_seq::or_code;
+
+// constant sequences
+const input_seq input_seq::empty_seq;
+
+
+
+//**************************************************************************
+// INPUT SEQ
+//**************************************************************************
+
+//-------------------------------------------------
+// operator+= - append a code to the end of an
+// input sequence
+//-------------------------------------------------
+
+input_seq &input_seq::operator+=(input_code code) noexcept
+{
+ // if not enough room, return false
+ const int curlength = length();
+ if (curlength < m_code.size())
+ {
+ m_code[curlength] = code;
+ if ((curlength + 1) < m_code.size())
+ m_code[curlength + 1] = end_code;
+ }
+ return *this;
+}
+
+
+//-------------------------------------------------
+// operator|= - append a code to a sequence; if
+// the sequence is non-empty, insert an OR
+// before the new code
+//-------------------------------------------------
+
+input_seq &input_seq::operator|=(input_code code) noexcept
+{
+ // overwrite end/default with the new code
+ if (m_code[0] == default_code)
+ {
+ m_code[0] = code;
+ m_code[1] = end_code;
+ }
+ else
+ {
+ // otherwise, append an OR token and then the new code
+ const int curlength = length();
+ if ((curlength + 1) < m_code.size())
+ {
+ m_code[curlength] = or_code;
+ m_code[curlength + 1] = code;
+ if ((curlength + 2) < m_code.size())
+ m_code[curlength + 2] = end_code;
+ }
+ }
+ return *this;
+}
+
+
+//-------------------------------------------------
+// length - return the length of the sequence
+//-------------------------------------------------
+
+int input_seq::length() const noexcept
+{
+ // find the end token; error if none found
+ for (int seqnum = 0; seqnum < m_code.size(); seqnum++)
+ if (m_code[seqnum] == end_code)
+ return seqnum;
+ return m_code.size();
+}
+
+
+//-------------------------------------------------
+// is_valid - return true if a given sequence is
+// valid
+//-------------------------------------------------
+
+bool input_seq::is_valid() const noexcept
+{
+ // "default" can only be of length 1
+ if (m_code[0] == default_code)
+ return m_code[1] == end_code;
+
+ // scan the sequence for valid codes
+ input_item_class lastclass = ITEM_CLASS_INVALID;
+ input_code lastcode = INPUT_CODE_INVALID;
+ decltype(m_code) positive_codes;
+ decltype(m_code) negative_codes;
+ auto positive_codes_end = positive_codes.begin();
+ auto negative_codes_end = negative_codes.begin();
+ for (input_code code : m_code)
+ {
+ // invalid codes are never permitted
+ if (code == INPUT_CODE_INVALID)
+ return false;
+
+ // if we hit an OR or the end, validate the previous chunk
+ if (code == or_code || code == end_code)
+ {
+ // must be at least one positive code
+ if (positive_codes.begin() == positive_codes_end)
+ return false;
+
+ // last code must not have been an internal code
+ if (lastcode.internal())
+ return false;
+
+ // if this is the end, we're ok
+ if (code == end_code)
+ return true;
+
+ // reset the state for the next chunk
+ positive_codes_end = positive_codes.begin();
+ negative_codes_end = negative_codes.begin();
+ lastclass = ITEM_CLASS_INVALID;
+ }
+ else if (code == not_code)
+ {
+ // if we hit a NOT, make sure we don't have a double
+ if (lastcode == not_code)
+ return false;
+ }
+ else
+ {
+ // track positive codes, and don't allow positive and negative for the same code
+ if (lastcode != not_code)
+ {
+ *positive_codes_end++ = code;
+ if (std::find(negative_codes.begin(), negative_codes_end, code) != negative_codes_end)
+ return false;
+ }
+ else
+ {
+ *negative_codes_end++ = code;
+ if (std::find(positive_codes.begin(), positive_codes_end, code) != positive_codes_end)
+ return false;
+ }
+
+ // non-switch items can't have a NOT
+ input_item_class itemclass = code.item_class();
+ if (itemclass != ITEM_CLASS_SWITCH && lastcode == not_code)
+ return false;
+
+ // absolute/relative items must all be the same class
+ if ((lastclass == ITEM_CLASS_ABSOLUTE && itemclass != ITEM_CLASS_ABSOLUTE) ||
+ (lastclass == ITEM_CLASS_RELATIVE && itemclass != ITEM_CLASS_RELATIVE))
+ return false;
+ }
+
+ // remember the last code
+ lastcode = code;
+ }
+
+ // if we got here, we were missing an END token; fail
+ return false;
+}
+
+
+//-------------------------------------------------
+// backspace - "backspace" over the last entry in
+// a sequence
+//-------------------------------------------------
+
+void input_seq::backspace() noexcept
+{
+ // if we have at least one entry, remove it
+ const int curlength = length();
+ if (curlength > 0)
+ m_code[curlength - 1] = end_code;
+}
+
+
+//-------------------------------------------------
+// replace - replace all instances of oldcode
+// with newcode in a sequence
+//-------------------------------------------------
+
+void input_seq::replace(input_code oldcode, input_code newcode) noexcept
+{
+ for (input_code &elem : m_code)
+ if (elem == oldcode)
+ elem = newcode;
+}
+
+} // namespace osd
diff --git a/src/osd/interface/inputseq.h b/src/osd/interface/inputseq.h
new file mode 100644
index 00000000000..62704462d47
--- /dev/null
+++ b/src/osd/interface/inputseq.h
@@ -0,0 +1,107 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ inputseq.h
+
+ A combination of hosts inputs that can be assigned to a control.
+
+***************************************************************************/
+#ifndef MAME_OSD_INTERFACE_INPUTSEQ_H
+#define MAME_OSD_INTERFACE_INPUTSEQ_H
+
+#pragma once
+
+#include "inputcode.h"
+
+#include <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
diff --git a/src/osd/modules/file/posixdir.cpp b/src/osd/modules/file/posixdir.cpp
index 63a02925bf1..efe68c2eda9 100644
--- a/src/osd/modules/file/posixdir.cpp
+++ b/src/osd/modules/file/posixdir.cpp
@@ -193,7 +193,7 @@ bool posix_directory::open_impl(std::string const &dirname)
{
assert(!m_fd);
- osd_subst_env(m_path, dirname);
+ m_path = osd_subst_env(dirname);
m_fd.reset(::opendir(m_path.c_str()));
return bool(m_fd);
}
@@ -224,7 +224,7 @@ directory::ptr directory::open(std::string const &dirname)
// osd_subst_env
//============================================================
-void osd_subst_env(std::string &dst, std::string const &src)
+std::string osd_subst_env(std::string_view src)
{
std::string result, var;
auto start = src.begin();
@@ -292,5 +292,5 @@ void osd_subst_env(std::string &dst, std::string const &src)
}
}
- dst = std::move(result);
+ return result;
}
diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp
index 580288c7d10..3b0e7b4b537 100644
--- a/src/osd/modules/file/posixfile.cpp
+++ b/src/osd/modules/file/posixfile.cpp
@@ -257,7 +257,7 @@ std::error_condition osd_file::open(std::string const &path, std::uint32_t openf
for (auto it = dst.begin(); it != dst.end(); ++it)
*it = (INVPATHSEPCH == *it) ? PATHSEPCH : *it;
#endif
- try { osd_subst_env(dst, dst); }
+ try { dst = osd_subst_env(dst); }
catch (...) { return std::errc::not_enough_memory; }
// attempt to open the file
diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp
index be4fa6f70c3..199537bbdee 100644
--- a/src/osd/modules/file/winfile.cpp
+++ b/src/osd/modules/file/winfile.cpp
@@ -164,7 +164,7 @@ DWORD create_path_recursive(TCHAR *path)
std::error_condition osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize) noexcept
{
std::string path;
- try { osd_subst_env(path, orig_path); }
+ try { path = osd_subst_env(orig_path); }
catch (...) { return std::errc::not_enough_memory; }
if (win_check_socket_path(path))
diff --git a/src/osd/modules/file/winrtfile.cpp b/src/osd/modules/file/winrtfile.cpp
index bc45ead48ae..3de1c19605d 100644
--- a/src/osd/modules/file/winrtfile.cpp
+++ b/src/osd/modules/file/winrtfile.cpp
@@ -163,8 +163,8 @@ DWORD create_path_recursive(TCHAR *path)
osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize)
{
std::string path;
- try { osd_subst_env(path, orig_path); }
- catch (...) { return error::OUT_OF_MEMORY; }
+ try { path = osd_subst_env(orig_path); }
+ catch (...) { return std::errc::not_enough_memory; }
if (win_check_socket_path(path))
return win_open_socket(path, openflags, file, filesize);
diff --git a/src/osd/modules/input/input_common.cpp b/src/osd/modules/input/input_common.cpp
index bb596295ea9..7127a7878fa 100644
--- a/src/osd/modules/input/input_common.cpp
+++ b/src/osd/modules/input/input_common.cpp
@@ -14,6 +14,8 @@
#include "emu.h"
#include "input_common.h"
+#include "inputdev.h" // FIXME: still using concrete input device class in input_module_base::poll
+
// winnt.h defines this
#ifdef DELETE
#undef DELETE
@@ -277,3 +279,46 @@ int input_module_base::init(const osd_options &options)
return 0;
}
+
+void input_module_base::poll(running_machine &machine)
+{
+ // ignore if not enabled
+ if (m_input_enabled)
+ {
+ // grab the current time
+ m_last_poll = m_clock.now();
+
+ before_poll(machine);
+
+ // track if mouse/lightgun is enabled, for mouse hiding purposes
+ m_mouse_enabled = machine.input().device_class(DEVICE_CLASS_MOUSE).enabled();
+ m_lightgun_enabled = machine.input().device_class(DEVICE_CLASS_LIGHTGUN).enabled();
+ }
+
+ // poll all of the devices
+ if (should_poll_devices(machine))
+ {
+ m_devicelist.poll_devices();
+ }
+ else
+ {
+ m_devicelist.reset_devices();
+ }
+}
+
+void input_module_base::pause()
+{
+ // keep track of the paused state
+ m_input_paused = true;
+}
+
+void input_module_base::resume()
+{
+ // keep track of the paused state
+ m_input_paused = false;
+}
+
+void input_module_base::exit()
+{
+ devicelist().free_all_devices();
+}
diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h
index c030d8f17b2..e220445c266 100644
--- a/src/osd/modules/input/input_common.h
+++ b/src/osd/modules/input/input_common.h
@@ -14,7 +14,7 @@
#include "input_module.h"
-#include "inputdev.h"
+#include "interface/inputman.h"
#include <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);
}
}
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp
index fa273e5fdb1..77467f80d59 100644
--- a/src/osd/modules/input/input_dinput.cpp
+++ b/src/osd/modules/input/input_dinput.cpp
@@ -389,9 +389,9 @@ void dinput_mouse_device::poll()
dinput_device::poll_dinput(&mouse);
// scale the axis data
- mouse.lX *= INPUT_RELATIVE_PER_PIXEL;
- mouse.lY *= INPUT_RELATIVE_PER_PIXEL;
- mouse.lZ *= INPUT_RELATIVE_PER_PIXEL;
+ mouse.lX *= osd::INPUT_RELATIVE_PER_PIXEL;
+ mouse.lY *= osd::INPUT_RELATIVE_PER_PIXEL;
+ mouse.lZ *= osd::INPUT_RELATIVE_PER_PIXEL;
}
void dinput_mouse_device::reset()
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index 8547a967dab..94018f9c404 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -347,12 +347,12 @@ public:
if (rawinput.data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
{
- mouse.lX += rawinput.data.mouse.lLastX * INPUT_RELATIVE_PER_PIXEL;
- mouse.lY += rawinput.data.mouse.lLastY * INPUT_RELATIVE_PER_PIXEL;
+ mouse.lX += rawinput.data.mouse.lLastX * osd::INPUT_RELATIVE_PER_PIXEL;
+ mouse.lY += rawinput.data.mouse.lLastY * osd::INPUT_RELATIVE_PER_PIXEL;
// update zaxis
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
- mouse.lZ += static_cast<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;
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 73d722525fa..76f8c494f70 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -526,8 +526,8 @@ public:
switch (sdlevent.type)
{
case SDL_MOUSEMOTION:
- mouse.lX += sdlevent.motion.xrel * INPUT_RELATIVE_PER_PIXEL;
- mouse.lY += sdlevent.motion.yrel * INPUT_RELATIVE_PER_PIXEL;
+ mouse.lX += sdlevent.motion.xrel * osd::INPUT_RELATIVE_PER_PIXEL;
+ mouse.lY += sdlevent.motion.yrel * osd::INPUT_RELATIVE_PER_PIXEL;
{
int cx = -1, cy = -1;
@@ -676,8 +676,8 @@ public:
case SDL_JOYBALLMOTION:
//printf("Ball %d %d\n", sdlevent.jball.xrel, sdlevent.jball.yrel);
- joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * INPUT_RELATIVE_PER_PIXEL;
- joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * INPUT_RELATIVE_PER_PIXEL;
+ joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * osd::INPUT_RELATIVE_PER_PIXEL;
+ joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * osd::INPUT_RELATIVE_PER_PIXEL;
break;
case SDL_JOYHATMOTION:
diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp
index 17128d7c0d6..459e624fcfa 100644
--- a/src/osd/modules/input/input_win32.cpp
+++ b/src/osd/modules/input/input_win32.cpp
@@ -149,8 +149,8 @@ public:
if (!(cursor_info.flags & CURSOR_SHOWING))
{
// We measure the position change from the previously set center position
- mouse.lX = (cursor_info.ptScreenPos.x - win32_mouse.last_point.x) * INPUT_RELATIVE_PER_PIXEL;
- mouse.lY = (cursor_info.ptScreenPos.y - win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL;
+ mouse.lX = (cursor_info.ptScreenPos.x - win32_mouse.last_point.x) * osd::INPUT_RELATIVE_PER_PIXEL;
+ mouse.lY = (cursor_info.ptScreenPos.y - win32_mouse.last_point.y) * osd::INPUT_RELATIVE_PER_PIXEL;
RECT window_pos = {0};
GetWindowRect(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), &window_pos);
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index afbb7a99500..b9bee6d87a8 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -73,8 +73,7 @@ void chain_manager::refresh_available_chains()
m_available_chains.clear();
m_available_chains.push_back(chain_desc("none", ""));
- std::string chains_path;
- osd_subst_env(chains_path, util::string_format("%s" PATH_SEPARATOR "chains", m_options.bgfx_path()));
+ const std::string chains_path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "chains", m_options.bgfx_path()));
find_available_chains(chains_path, "");
destroy_unloaded_chains();
@@ -151,8 +150,7 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index)
{
name = name + ".json";
}
- std::string path;
- osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "chains" PATH_SEPARATOR, m_options.bgfx_path()));
+ std::string path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "chains" PATH_SEPARATOR, m_options.bgfx_path()));
path += name;
bx::FileReader reader;
diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp
index 98bc9a72097..8fc2899482a 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -31,8 +31,7 @@ static bool prepare_effect_document(std::string &name, osd_options &options, rap
full_name = full_name + ".json";
}
- std::string path;
- osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path()));
+ std::string path = osd_subst_env(util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path()));
path += full_name;
bx::FileReader reader;
diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp
index dd131e719a5..484c14c8936 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -116,9 +116,7 @@ std::string shader_manager::make_path_string(osd_options &options, std::string n
fatalerror("Unknown BGFX renderer type %d", bgfx::getRendererType());
}
shader_path += PATH_SEPARATOR;
- osd_subst_env(shader_path, shader_path);
-
- return shader_path;
+ return osd_subst_env(shader_path);
}
const bgfx::Memory* shader_manager::load_mem(std::string name)
diff --git a/src/osd/osdcomm.h b/src/osd/osdcomm.h
index 75370f1b81b..516dd3e681a 100644
--- a/src/osd/osdcomm.h
+++ b/src/osd/osdcomm.h
@@ -71,15 +71,11 @@ using s64 = std::int64_t;
} // namespace OSD
+
/***************************************************************************
FUNDAMENTAL MACROS
***************************************************************************/
-// Concatenate/extract 32-bit halves of 64-bit values
-constexpr uint64_t concat_64(uint32_t hi, uint32_t lo) { return (uint64_t(hi) << 32) | uint32_t(lo); }
-constexpr uint32_t extract_64hi(uint64_t val) { return uint32_t(val >> 32); }
-constexpr uint32_t extract_64lo(uint64_t val) { return uint32_t(val); }
-
// Macros for normalizing data into big or little endian formats
constexpr uint16_t swapendian_int16(uint16_t val) { return (val << 8) | (val >> 8); }
@@ -116,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
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index a7f652470db..ff97f10c7d5 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -390,11 +390,10 @@ void osd_list_network_adapters();
Parameters:
- dst - result pointer
src - source string
-----------------------------------------------------------------------------*/
-void osd_subst_env(std::string &dst, std::string const &src);
+std::string osd_subst_env(std::string_view src);
class osd_gpu
{
diff --git a/src/osd/windows/winutil.cpp b/src/osd/windows/winutil.cpp
index 7d790949178..3a344386a12 100644
--- a/src/osd/windows/winutil.cpp
+++ b/src/osd/windows/winutil.cpp
@@ -101,7 +101,7 @@ BOOL win_is_gui_application()
//============================================================
// osd_subst_env
//============================================================
-void osd_subst_env(std::string &dst, const std::string &src)
+std::string osd_subst_env(std::string_view src)
{
std::wstring const w_src = osd::text::to_wstring(src);
std::vector<wchar_t> buffer(w_src.size() + 2);
@@ -112,10 +112,11 @@ void osd_subst_env(std::string &dst, const std::string &src)
buffer.resize(length + 1);
length = ExpandEnvironmentStringsW(w_src.c_str(), &buffer[0], buffer.size());
}
+
+ std::string dst;
if (length)
osd::text::from_wstring(dst, &buffer[0]);
- else
- dst.clear();
+ return dst;
}
//-------------------------------------------------