diff options
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 ×lice_time, const at emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback) { - return &m_timer_allocator.alloc()->init(machine(), std::move(callback), false); -} - - -//------------------------------------------------- -// timer_set - allocate an anonymous non-device -// timer and set it to go off after the given -// amount of time -//------------------------------------------------- - -void device_scheduler::timer_set(const attotime &duration, timer_expired_delegate callback, int param) -{ - m_timer_allocator.alloc()->init(machine(), std::move(callback), true).adjust(duration, param); + return &m_timer_allocator.alloc()->init(machine(), std::move(callback), attotime::never, 0, false); } @@ -597,19 +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; } //------------------------------------------------- |