diff options
Diffstat (limited to 'src')
38 files changed, 4262 insertions, 1162 deletions
diff --git a/src/emu/inpttype.h b/src/emu/inpttype.h new file mode 100644 index 00000000000..de5b42d0a77 --- /dev/null +++ b/src/emu/inpttype.h @@ -0,0 +1,351 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + inpttype.ipp + + Core-defined input types. + +***************************************************************************/ +#ifndef MAME_EMU_INPTTYPE_H +#define MAME_EMU_INPTTYPE_H + +#pragma once + +#include "interface/inputfwd.h" +#include "osdcomm.h" + + +enum ioport_type : osd::u32 +{ + // pseudo-port types + IPT_INVALID = 0, + IPT_UNUSED, + IPT_END, + IPT_UNKNOWN, + IPT_PORT, + IPT_DIPSWITCH, + IPT_CONFIG, + + // start buttons + IPT_START1, + IPT_START2, + IPT_START3, + IPT_START4, + IPT_START5, + IPT_START6, + IPT_START7, + IPT_START8, + IPT_START9, + IPT_START10, + + // coin slots + IPT_COIN1, + IPT_COIN2, + IPT_COIN3, + IPT_COIN4, + IPT_COIN5, + IPT_COIN6, + IPT_COIN7, + IPT_COIN8, + IPT_COIN9, + IPT_COIN10, + IPT_COIN11, + IPT_COIN12, + IPT_BILL1, + + // service coin + IPT_SERVICE1, + IPT_SERVICE2, + IPT_SERVICE3, + IPT_SERVICE4, + + // tilt inputs + IPT_TILT1, + IPT_TILT2, + IPT_TILT3, + IPT_TILT4, + + // misc other digital inputs + IPT_POWER_ON, + IPT_POWER_OFF, + IPT_SERVICE, + IPT_TILT, + IPT_INTERLOCK, + IPT_MEMORY_RESET, + IPT_VOLUME_UP, + IPT_VOLUME_DOWN, + IPT_START, // use the numbered start button(s) for coin-ops + IPT_SELECT, + IPT_KEYPAD, + IPT_KEYBOARD, + + // digital joystick inputs + IPT_DIGITAL_JOYSTICK_FIRST, + + // use IPT_JOYSTICK for panels where the player has one single joystick + IPT_JOYSTICK_UP, + IPT_JOYSTICK_DOWN, + IPT_JOYSTICK_LEFT, + IPT_JOYSTICK_RIGHT, + + // use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels + IPT_JOYSTICKRIGHT_UP, + IPT_JOYSTICKRIGHT_DOWN, + IPT_JOYSTICKRIGHT_LEFT, + IPT_JOYSTICKRIGHT_RIGHT, + IPT_JOYSTICKLEFT_UP, + IPT_JOYSTICKLEFT_DOWN, + IPT_JOYSTICKLEFT_LEFT, + IPT_JOYSTICKLEFT_RIGHT, + + IPT_DIGITAL_JOYSTICK_LAST, + + // action buttons + IPT_BUTTON1, + IPT_BUTTON2, + IPT_BUTTON3, + IPT_BUTTON4, + IPT_BUTTON5, + IPT_BUTTON6, + IPT_BUTTON7, + IPT_BUTTON8, + IPT_BUTTON9, + IPT_BUTTON10, + IPT_BUTTON11, + IPT_BUTTON12, + IPT_BUTTON13, + IPT_BUTTON14, + IPT_BUTTON15, + IPT_BUTTON16, + + // mahjong inputs + IPT_MAHJONG_FIRST, + + IPT_MAHJONG_A, + IPT_MAHJONG_B, + IPT_MAHJONG_C, + IPT_MAHJONG_D, + IPT_MAHJONG_E, + IPT_MAHJONG_F, + IPT_MAHJONG_G, + IPT_MAHJONG_H, + IPT_MAHJONG_I, + IPT_MAHJONG_J, + IPT_MAHJONG_K, + IPT_MAHJONG_L, + IPT_MAHJONG_M, + IPT_MAHJONG_N, + IPT_MAHJONG_O, + IPT_MAHJONG_P, + IPT_MAHJONG_Q, + IPT_MAHJONG_KAN, + IPT_MAHJONG_PON, + IPT_MAHJONG_CHI, + IPT_MAHJONG_REACH, + IPT_MAHJONG_RON, + IPT_MAHJONG_FLIP_FLOP, + IPT_MAHJONG_BET, + IPT_MAHJONG_SCORE, + IPT_MAHJONG_DOUBLE_UP, + IPT_MAHJONG_BIG, + IPT_MAHJONG_SMALL, + IPT_MAHJONG_LAST_CHANCE, + + IPT_MAHJONG_LAST, + + // hanafuda inputs + IPT_HANAFUDA_FIRST, + + IPT_HANAFUDA_A, + IPT_HANAFUDA_B, + IPT_HANAFUDA_C, + IPT_HANAFUDA_D, + IPT_HANAFUDA_E, + IPT_HANAFUDA_F, + IPT_HANAFUDA_G, + IPT_HANAFUDA_H, + IPT_HANAFUDA_YES, + IPT_HANAFUDA_NO, + + IPT_HANAFUDA_LAST, + + // gambling inputs + IPT_GAMBLING_FIRST, + + IPT_GAMBLE_KEYIN, // attendant + IPT_GAMBLE_KEYOUT, // attendant + IPT_GAMBLE_SERVICE, // attendant + IPT_GAMBLE_BOOK, // attendant + IPT_GAMBLE_DOOR, // attendant + // IPT_GAMBLE_DOOR2, // many gambling games have several doors. + // IPT_GAMBLE_DOOR3, + // IPT_GAMBLE_DOOR4, + // IPT_GAMBLE_DOOR5, + + IPT_GAMBLE_PAYOUT, // player + IPT_GAMBLE_BET, // player + IPT_GAMBLE_DEAL, // player + IPT_GAMBLE_STAND, // player + IPT_GAMBLE_TAKE, // player + IPT_GAMBLE_D_UP, // player + IPT_GAMBLE_HALF, // player + IPT_GAMBLE_HIGH, // player + IPT_GAMBLE_LOW, // player + + // poker-specific inputs + IPT_POKER_HOLD1, + IPT_POKER_HOLD2, + IPT_POKER_HOLD3, + IPT_POKER_HOLD4, + IPT_POKER_HOLD5, + IPT_POKER_CANCEL, + + // slot-specific inputs + IPT_SLOT_STOP1, + IPT_SLOT_STOP2, + IPT_SLOT_STOP3, + IPT_SLOT_STOP4, + IPT_SLOT_STOP_ALL, + + IPT_GAMBLING_LAST, + + // analog inputs + IPT_ANALOG_FIRST, + + IPT_ANALOG_ABSOLUTE_FIRST, + + IPT_AD_STICK_X, // absolute // autocenter + IPT_AD_STICK_Y, // absolute // autocenter + IPT_AD_STICK_Z, // absolute // autocenter + IPT_PADDLE, // absolute // autocenter + IPT_PADDLE_V, // absolute // autocenter + IPT_PEDAL, // absolute // autocenter + IPT_PEDAL2, // absolute // autocenter + IPT_PEDAL3, // absolute // autocenter + IPT_LIGHTGUN_X, // absolute + IPT_LIGHTGUN_Y, // absolute + IPT_POSITIONAL, // absolute // autocenter if not wraps + IPT_POSITIONAL_V, // absolute // autocenter if not wraps + + IPT_ANALOG_ABSOLUTE_LAST, + + IPT_DIAL, // relative + IPT_DIAL_V, // relative + IPT_TRACKBALL_X, // relative + IPT_TRACKBALL_Y, // relative + IPT_MOUSE_X, // relative + IPT_MOUSE_Y, // relative + + IPT_ANALOG_LAST, + + // analog adjuster support + IPT_ADJUSTER, + + // the following are special codes for user interface handling - not to be used by drivers! + IPT_UI_FIRST, + + IPT_UI_MENU, + IPT_UI_SELECT, + IPT_UI_BACK, + IPT_UI_CANCEL, + IPT_UI_CLEAR, + IPT_UI_HELP, + IPT_UI_UP, + IPT_UI_DOWN, + IPT_UI_LEFT, + IPT_UI_RIGHT, + IPT_UI_HOME, + IPT_UI_END, + IPT_UI_PAGE_UP, + IPT_UI_PAGE_DOWN, + IPT_UI_PREV_GROUP, + IPT_UI_NEXT_GROUP, + IPT_UI_ON_SCREEN_DISPLAY, + IPT_UI_TOGGLE_UI, + IPT_UI_DEBUG_BREAK, + IPT_UI_PAUSE, + IPT_UI_PAUSE_SINGLE, + IPT_UI_REWIND_SINGLE, + IPT_UI_SAVE_STATE, + IPT_UI_LOAD_STATE, + IPT_UI_RESET_MACHINE, + IPT_UI_SOFT_RESET, + IPT_UI_SHOW_GFX, + IPT_UI_FRAMESKIP_DEC, + IPT_UI_FRAMESKIP_INC, + IPT_UI_THROTTLE, + IPT_UI_FAST_FORWARD, + IPT_UI_SHOW_FPS, + IPT_UI_SNAPSHOT, + IPT_UI_RECORD_MNG, + IPT_UI_RECORD_AVI, + IPT_UI_TOGGLE_CHEAT, + IPT_UI_DISPLAY_COMMENT, + IPT_UI_ZOOM_IN, + IPT_UI_ZOOM_OUT, + IPT_UI_ZOOM_DEFAULT, + IPT_UI_ROTATE, + IPT_UI_SHOW_PROFILER, + IPT_UI_RELEASE_POINTER, + IPT_UI_PASTE, + IPT_UI_TAPE_START, + IPT_UI_TAPE_STOP, + IPT_UI_FOCUS_NEXT, + IPT_UI_FOCUS_PREV, + IPT_UI_DATS, + IPT_UI_FAVORITES, + IPT_UI_EXPORT, + IPT_UI_AUDIT, + + // additional OSD-specified UI port types (up to 16) + IPT_OSD_1, + IPT_OSD_2, + IPT_OSD_3, + IPT_OSD_4, + IPT_OSD_5, + IPT_OSD_6, + IPT_OSD_7, + IPT_OSD_8, + IPT_OSD_9, + IPT_OSD_10, + IPT_OSD_11, + IPT_OSD_12, + IPT_OSD_13, + IPT_OSD_14, + IPT_OSD_15, + IPT_OSD_16, + + IPT_UI_LAST, + + IPT_OTHER, // not mapped to standard defaults + + IPT_SPECIAL, // uninterpreted characters + IPT_CUSTOM, // handled by custom code + IPT_OUTPUT, + + IPT_COUNT, + + // aliases for some types + IPT_PADDLE_H = IPT_PADDLE, + IPT_PEDAL1 = IPT_PEDAL, + IPT_POSITIONAL_H = IPT_POSITIONAL, + IPT_DIAL_H = IPT_DIAL +}; + +DECLARE_ENUM_INCDEC_OPERATORS(ioport_type) + + +// sequence types for input_port_seq() call +enum input_seq_type : int +{ + SEQ_TYPE_INVALID = -1, + SEQ_TYPE_STANDARD = 0, + SEQ_TYPE_INCREMENT, + SEQ_TYPE_DECREMENT, + SEQ_TYPE_TOTAL +}; + +DECLARE_ENUM_INCDEC_OPERATORS(input_seq_type) + +#endif // MAME_EMU_INPTTYPE_H diff --git a/src/emu/inpttype.ipp b/src/emu/inpttype.ipp index 80e207de034..e5cb81c45fc 100644 --- a/src/emu/inpttype.ipp +++ b/src/emu/inpttype.ipp @@ -19,36 +19,36 @@ namespace { #define CORE_INPUT_TYPES_P1 \ CORE_INPUT_TYPES_BEGIN(p1) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_LSHIFT, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_Z, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(KEYCODE_X, input_seq::or_code, JOYCODE_BUTTON6_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(KEYCODE_C, input_seq::or_code, JOYCODE_BUTTON7_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(KEYCODE_V, input_seq::or_code, JOYCODE_BUTTON8_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(KEYCODE_B, input_seq::or_code, JOYCODE_BUTTON9_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(KEYCODE_N, input_seq::or_code, JOYCODE_BUTTON10_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(KEYCODE_M, input_seq::or_code, JOYCODE_BUTTON11_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(KEYCODE_COMMA, input_seq::or_code, JOYCODE_BUTTON12_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(KEYCODE_STOP, input_seq::or_code, JOYCODE_BUTTON13_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(KEYCODE_SLASH, input_seq::or_code, JOYCODE_BUTTON14_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON15_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_1, input_seq::or_code, JOYCODE_START_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_5, input_seq::or_code, JOYCODE_SELECT_INDEXED(0)) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_UP) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_LEFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq(KEYCODE_I) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq(KEYCODE_K) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq(KEYCODE_J) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKRIGHT_RIGHT, N_p("input-name", "%p Right Stick/Right"), input_seq(KEYCODE_L) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_UP, N_p("input-name", "%p Left Stick/Up"), input_seq(KEYCODE_E) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq(KEYCODE_D) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq(KEYCODE_S) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq(KEYCODE_F) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_LCONTROL, input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(0)) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_LALT, input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(0), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(0)) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_SPACE, input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(0)) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_LSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_Z) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(KEYCODE_X) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(KEYCODE_C) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(KEYCODE_V) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(KEYCODE_B) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(KEYCODE_N) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(KEYCODE_M) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(KEYCODE_COMMA) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(KEYCODE_STOP) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(KEYCODE_SLASH) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(KEYCODE_RSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_1) ) \ + INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_5) ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P1_MAHJONG \ @@ -137,10 +137,10 @@ namespace { #define CORE_INPUT_TYPES_P2 \ CORE_INPUT_TYPES_BEGIN(p2) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_R, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_F, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_D, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_G, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(1)) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_R) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_F) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_D) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_G) ) \ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -149,24 +149,24 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1), input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_W, input_seq::or_code, JOYCODE_BUTTON4_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_E, input_seq::or_code, JOYCODE_BUTTON5_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_2, input_seq::or_code, JOYCODE_START_INDEXED(1)) ) \ - INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_6, input_seq::or_code, JOYCODE_SELECT_INDEXED(1)) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_A, input_seq::or_code, MOUSECODE_BUTTON1_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(1)) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_S, input_seq::or_code, MOUSECODE_BUTTON3_INDEXED(1), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(1)) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_Q, input_seq::or_code, MOUSECODE_BUTTON2_INDEXED(1)) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(KEYCODE_W) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(KEYCODE_E) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_2) ) \ + INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_6) ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P2_MAHJONG \ @@ -218,10 +218,10 @@ namespace { #define CORE_INPUT_TYPES_P3 \ CORE_INPUT_TYPES_BEGIN(p3) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_I, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_K, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_J, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_L, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(2)) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_I) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_K) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_J) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_L) ) \ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -230,24 +230,24 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON1_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2), input_seq::or_code, GUNCODE_BUTTON2_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_3, input_seq::or_code, JOYCODE_START_INDEXED(2)) ) \ - INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_7, input_seq::or_code, JOYCODE_SELECT_INDEXED(2)) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_RCONTROL, input_seq::or_code, GUNCODE_BUTTON1_INDEXED(2)) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_RSHIFT, input_seq::or_code, GUNCODE_BUTTON2_INDEXED(2)) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_3) ) \ + INPUT_PORT_DIGITAL_TYPE( 3, PLAYER3, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_7) ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P3_MAHJONG \ @@ -285,10 +285,10 @@ namespace { #define CORE_INPUT_TYPES_P4 \ CORE_INPUT_TYPES_BEGIN(p4) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_8_PAD, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_2_PAD, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_4_PAD, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_6_PAD, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(3)) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(KEYCODE_8_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(KEYCODE_2_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(KEYCODE_4_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(KEYCODE_6_PAD) ) \ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -297,24 +297,24 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_4, input_seq::or_code, JOYCODE_START_INDEXED(3)) ) \ - INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_8, input_seq::or_code, JOYCODE_SELECT_INDEXED(3)) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(KEYCODE_0_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(KEYCODE_DEL_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(KEYCODE_ENTER_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, START, N_p("input-name", "%p Start"), input_seq(KEYCODE_4) ) \ + INPUT_PORT_DIGITAL_TYPE( 4, PLAYER4, SELECT, N_p("input-name", "%p Select"), input_seq(KEYCODE_8) ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P4_MAHJONG \ @@ -352,10 +352,10 @@ namespace { #define CORE_INPUT_TYPES_P5 \ CORE_INPUT_TYPES_BEGIN(p5) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(4)) ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -364,32 +364,32 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(4)) ) \ - INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(4)) ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 5, PLAYER5, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P6 \ CORE_INPUT_TYPES_BEGIN(p6) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(5)) ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -398,32 +398,32 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(5)) ) \ - INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(5)) ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 6, PLAYER6, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P7 \ CORE_INPUT_TYPES_BEGIN(p7) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(6)) ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -432,32 +432,32 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(6)) ) \ - INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(6)) ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 7, PLAYER7, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P8 \ CORE_INPUT_TYPES_BEGIN(p8) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(7)) ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -466,32 +466,32 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(7)) ) \ - INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(7)) ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 8, PLAYER8, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P9 \ CORE_INPUT_TYPES_BEGIN(p9) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(8)) ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -500,32 +500,32 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(8)) ) \ - INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(8)) ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 9, PLAYER9, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_P10 \ CORE_INPUT_TYPES_BEGIN(p10) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq(JOYCODE_Y_UP_SWITCH_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq(JOYCODE_Y_DOWN_SWITCH_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq(JOYCODE_X_LEFT_SWITCH_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq(JOYCODE_X_RIGHT_SWITCH_INDEXED(9)) ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_UP, N_p("input-name", "%p Up"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_DOWN, N_p("input-name", "%p Down"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_LEFT, N_p("input-name", "%p Left"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICK_RIGHT, N_p("input-name", "%p Right"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_UP, N_p("input-name", "%p Right Stick/Up"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_DOWN, N_p("input-name", "%p Right Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKRIGHT_LEFT, N_p("input-name", "%p Right Stick/Left"), input_seq() ) \ @@ -534,24 +534,24 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_DOWN, N_p("input-name", "%p Left Stick/Down"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_LEFT, N_p("input-name", "%p Left Stick/Left"), input_seq() ) \ INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, JOYSTICKLEFT_RIGHT, N_p("input-name", "%p Left Stick/Right"), input_seq() ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON1, N_p("input-name", "%p Button 1"), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON2, N_p("input-name", "%p Button 2"), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON3, N_p("input-name", "%p Button 3"), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON4, N_p("input-name", "%p Button 4"), input_seq(JOYCODE_BUTTON4_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON5, N_p("input-name", "%p Button 5"), input_seq(JOYCODE_BUTTON5_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON6, N_p("input-name", "%p Button 6"), input_seq(JOYCODE_BUTTON6_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON7, N_p("input-name", "%p Button 7"), input_seq(JOYCODE_BUTTON7_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON8, N_p("input-name", "%p Button 8"), input_seq(JOYCODE_BUTTON8_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON9, N_p("input-name", "%p Button 9"), input_seq(JOYCODE_BUTTON9_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON10, N_p("input-name", "%p Button 10"), input_seq(JOYCODE_BUTTON10_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON11, N_p("input-name", "%p Button 11"), input_seq(JOYCODE_BUTTON11_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON12, N_p("input-name", "%p Button 12"), input_seq(JOYCODE_BUTTON12_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON13, N_p("input-name", "%p Button 13"), input_seq(JOYCODE_BUTTON13_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON14, N_p("input-name", "%p Button 14"), input_seq(JOYCODE_BUTTON14_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON15, N_p("input-name", "%p Button 15"), input_seq(JOYCODE_BUTTON15_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON16, N_p("input-name", "%p Button 16"), input_seq(JOYCODE_BUTTON16_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, START, N_p("input-name", "%p Start"), input_seq(JOYCODE_START_INDEXED(9)) ) \ - INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, SELECT, N_p("input-name", "%p Select"), input_seq(JOYCODE_SELECT_INDEXED(9)) ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON1, N_p("input-name", "%p Button 1"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON2, N_p("input-name", "%p Button 2"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON3, N_p("input-name", "%p Button 3"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON4, N_p("input-name", "%p Button 4"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON5, N_p("input-name", "%p Button 5"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON6, N_p("input-name", "%p Button 6"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON7, N_p("input-name", "%p Button 7"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON8, N_p("input-name", "%p Button 8"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON9, N_p("input-name", "%p Button 9"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON10, N_p("input-name", "%p Button 10"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON11, N_p("input-name", "%p Button 11"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON12, N_p("input-name", "%p Button 12"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON13, N_p("input-name", "%p Button 13"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON14, N_p("input-name", "%p Button 14"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON15, N_p("input-name", "%p Button 15"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, BUTTON16, N_p("input-name", "%p Button 16"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, START, N_p("input-name", "%p Start"), input_seq() ) \ + INPUT_PORT_DIGITAL_TYPE( 10, PLAYER10, SELECT, N_p("input-name", "%p Select"), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_START \ @@ -613,226 +613,226 @@ namespace { #define CORE_INPUT_TYPES_PEDAL \ CORE_INPUT_TYPES_BEGIN(pedal) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0)) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_A, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(1)) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RCONTROL, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(2)) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_0_PAD, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(3)) ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(4)) ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(5)) ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(6)) ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(7)) ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(8)) ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(JOYCODE_Z_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON1_INDEXED(9)) ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq(KEYCODE_LCONTROL) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq(KEYCODE_A) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq(KEYCODE_RCONTROL) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq(KEYCODE_0_PAD) ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL, N_p("input-name", "%p Pedal 1"), input_seq(), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_PEDAL2 \ CORE_INPUT_TYPES_BEGIN(pedal2) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(0)), input_seq(), input_seq(KEYCODE_LALT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(0)) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(1)), input_seq(), input_seq(KEYCODE_S, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(1)) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(2)), input_seq(), input_seq(KEYCODE_RSHIFT, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(2)) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(3)), input_seq(), input_seq(KEYCODE_DEL_PAD, input_seq::or_code, JOYCODE_BUTTON2_INDEXED(3)) ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(4)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(4)) ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(5)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(5)) ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(6)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(6)) ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(7)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(7)) ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(8)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(8)) ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(JOYCODE_W_NEG_ABSOLUTE_INDEXED(9)), input_seq(), input_seq(JOYCODE_BUTTON2_INDEXED(9)) ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq(KEYCODE_LALT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq(KEYCODE_S) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq(KEYCODE_RSHIFT) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq(KEYCODE_DEL_PAD) ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL2, N_p("input-name", "%p Pedal 2"), input_seq(), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_PEDAL3 \ CORE_INPUT_TYPES_BEGIN(pedal3) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_SPACE, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(0)) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_Q, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(1)) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(2)) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER_PAD, input_seq::or_code, JOYCODE_BUTTON3_INDEXED(3)) ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(4)) ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(5)) ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(6)) ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(7)) ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(8)) ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(JOYCODE_BUTTON3_INDEXED(9)) ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_SPACE) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_Q) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq(KEYCODE_ENTER_PAD) ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PEDAL3, N_p("input-name", "%p Pedal 3"), input_seq(), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_PADDLE \ CORE_INPUT_TYPES_BEGIN(paddle) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PADDLE, N_p("input-name", "Paddle"), input_seq(JOYCODE_X_INDEXED(0), input_seq::or_code, MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PADDLE, N_p("input-name", "Paddle 2"), input_seq(JOYCODE_X_INDEXED(1), input_seq::or_code, MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PADDLE, N_p("input-name", "Paddle 3"), input_seq(JOYCODE_X_INDEXED(2), input_seq::or_code, MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PADDLE, N_p("input-name", "Paddle 4"), input_seq(JOYCODE_X_INDEXED(3), input_seq::or_code, MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PADDLE, N_p("input-name", "Paddle 5"), input_seq(JOYCODE_X_INDEXED(4), input_seq::or_code, MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PADDLE, N_p("input-name", "Paddle 6"), input_seq(JOYCODE_X_INDEXED(5), input_seq::or_code, MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PADDLE, N_p("input-name", "Paddle 7"), input_seq(JOYCODE_X_INDEXED(6), input_seq::or_code, MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PADDLE, N_p("input-name", "Paddle 8"), input_seq(JOYCODE_X_INDEXED(7), input_seq::or_code, MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PADDLE, N_p("input-name", "Paddle 9"), input_seq(JOYCODE_X_INDEXED(8), input_seq::or_code, MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PADDLE, N_p("input-name", "Paddle 10"), input_seq(JOYCODE_X_INDEXED(9), input_seq::or_code, MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PADDLE, N_p("input-name", "Paddle"), input_seq(MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PADDLE, N_p("input-name", "Paddle 2"), input_seq(MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PADDLE, N_p("input-name", "Paddle 3"), input_seq(MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PADDLE, N_p("input-name", "Paddle 4"), input_seq(MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PADDLE, N_p("input-name", "Paddle 5"), input_seq(MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PADDLE, N_p("input-name", "Paddle 6"), input_seq(MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PADDLE, N_p("input-name", "Paddle 7"), input_seq(MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PADDLE, N_p("input-name", "Paddle 8"), input_seq(MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PADDLE, N_p("input-name", "Paddle 9"), input_seq(MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PADDLE, N_p("input-name", "Paddle 10"), input_seq(MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_PADDLE_V \ CORE_INPUT_TYPES_BEGIN(paddle_v) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PADDLE_V, N_p("input-name", "Paddle V"), input_seq(JOYCODE_Y_INDEXED(0), input_seq::or_code, MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PADDLE_V, N_p("input-name", "Paddle V 2"), input_seq(JOYCODE_Y_INDEXED(1), input_seq::or_code, MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PADDLE_V, N_p("input-name", "Paddle V 3"), input_seq(JOYCODE_Y_INDEXED(2), input_seq::or_code, MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PADDLE_V, N_p("input-name", "Paddle V 4"), input_seq(JOYCODE_Y_INDEXED(3), input_seq::or_code, MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PADDLE_V, N_p("input-name", "Paddle V 5"), input_seq(JOYCODE_Y_INDEXED(4), input_seq::or_code, MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PADDLE_V, N_p("input-name", "Paddle V 6"), input_seq(JOYCODE_Y_INDEXED(5), input_seq::or_code, MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PADDLE_V, N_p("input-name", "Paddle V 7"), input_seq(JOYCODE_Y_INDEXED(6), input_seq::or_code, MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PADDLE_V, N_p("input-name", "Paddle V 8"), input_seq(JOYCODE_Y_INDEXED(7), input_seq::or_code, MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PADDLE_V, N_p("input-name", "Paddle V 9"), input_seq(JOYCODE_Y_INDEXED(8), input_seq::or_code, MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PADDLE_V, N_p("input-name", "Paddle V 10"), input_seq(JOYCODE_Y_INDEXED(9), input_seq::or_code, MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, PADDLE_V, N_p("input-name", "Paddle V"), input_seq(MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, PADDLE_V, N_p("input-name", "Paddle V 2"), input_seq(MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, PADDLE_V, N_p("input-name", "Paddle V 3"), input_seq(MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, PADDLE_V, N_p("input-name", "Paddle V 4"), input_seq(MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, PADDLE_V, N_p("input-name", "Paddle V 5"), input_seq(MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, PADDLE_V, N_p("input-name", "Paddle V 6"), input_seq(MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, PADDLE_V, N_p("input-name", "Paddle V 7"), input_seq(MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, PADDLE_V, N_p("input-name", "Paddle V 8"), input_seq(MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, PADDLE_V, N_p("input-name", "Paddle V 9"), input_seq(MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, PADDLE_V, N_p("input-name", "Paddle V 10"), input_seq(MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_POSITIONAL \ CORE_INPUT_TYPES_BEGIN(positional) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, POSITIONAL, N_p("input-name", "Positional"), input_seq(MOUSECODE_X_INDEXED(0), input_seq::or_code, JOYCODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, POSITIONAL, N_p("input-name", "Positional 2"), input_seq(MOUSECODE_X_INDEXED(1), input_seq::or_code, JOYCODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, POSITIONAL, N_p("input-name", "Positional 3"), input_seq(MOUSECODE_X_INDEXED(2), input_seq::or_code, JOYCODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, POSITIONAL, N_p("input-name", "Positional 4"), input_seq(MOUSECODE_X_INDEXED(3), input_seq::or_code, JOYCODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, POSITIONAL, N_p("input-name", "Positional 5"), input_seq(MOUSECODE_X_INDEXED(4), input_seq::or_code, JOYCODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, POSITIONAL, N_p("input-name", "Positional 6"), input_seq(MOUSECODE_X_INDEXED(5), input_seq::or_code, JOYCODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, POSITIONAL, N_p("input-name", "Positional 7"), input_seq(MOUSECODE_X_INDEXED(6), input_seq::or_code, JOYCODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, POSITIONAL, N_p("input-name", "Positional 8"), input_seq(MOUSECODE_X_INDEXED(7), input_seq::or_code, JOYCODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, POSITIONAL, N_p("input-name", "Positional 9"), input_seq(MOUSECODE_X_INDEXED(8), input_seq::or_code, JOYCODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, POSITIONAL, N_p("input-name", "Positional 10"), input_seq(MOUSECODE_X_INDEXED(9), input_seq::or_code, JOYCODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, POSITIONAL, N_p("input-name", "Positional"), input_seq(MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, POSITIONAL, N_p("input-name", "Positional 2"), input_seq(MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, POSITIONAL, N_p("input-name", "Positional 3"), input_seq(MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, POSITIONAL, N_p("input-name", "Positional 4"), input_seq(MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, POSITIONAL, N_p("input-name", "Positional 5"), input_seq(MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, POSITIONAL, N_p("input-name", "Positional 6"), input_seq(MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, POSITIONAL, N_p("input-name", "Positional 7"), input_seq(MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, POSITIONAL, N_p("input-name", "Positional 8"), input_seq(MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, POSITIONAL, N_p("input-name", "Positional 9"), input_seq(MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, POSITIONAL, N_p("input-name", "Positional 10"), input_seq(MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_POSITIONAL_V \ CORE_INPUT_TYPES_BEGIN(positional_v) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, POSITIONAL_V, N_p("input-name", "Positional V"), input_seq(MOUSECODE_Y_INDEXED(0), input_seq::or_code, JOYCODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, POSITIONAL_V, N_p("input-name", "Positional V 2"), input_seq(MOUSECODE_Y_INDEXED(1), input_seq::or_code, JOYCODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, POSITIONAL_V, N_p("input-name", "Positional V 3"), input_seq(MOUSECODE_Y_INDEXED(2), input_seq::or_code, JOYCODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, POSITIONAL_V, N_p("input-name", "Positional V 4"), input_seq(MOUSECODE_Y_INDEXED(3), input_seq::or_code, JOYCODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, POSITIONAL_V, N_p("input-name", "Positional V 5"), input_seq(MOUSECODE_Y_INDEXED(4), input_seq::or_code, JOYCODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, POSITIONAL_V, N_p("input-name", "Positional V 6"), input_seq(MOUSECODE_Y_INDEXED(5), input_seq::or_code, JOYCODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, POSITIONAL_V, N_p("input-name", "Positional V 7"), input_seq(MOUSECODE_Y_INDEXED(6), input_seq::or_code, JOYCODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, POSITIONAL_V, N_p("input-name", "Positional V 8"), input_seq(MOUSECODE_Y_INDEXED(7), input_seq::or_code, JOYCODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, POSITIONAL_V, N_p("input-name", "Positional V 9"), input_seq(MOUSECODE_Y_INDEXED(8), input_seq::or_code, JOYCODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, POSITIONAL_V, N_p("input-name", "Positional V 10"), input_seq(MOUSECODE_Y_INDEXED(9), input_seq::or_code, JOYCODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, POSITIONAL_V, N_p("input-name", "Positional V"), input_seq(MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, POSITIONAL_V, N_p("input-name", "Positional V 2"), input_seq(MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, POSITIONAL_V, N_p("input-name", "Positional V 3"), input_seq(MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, POSITIONAL_V, N_p("input-name", "Positional V 4"), input_seq(MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, POSITIONAL_V, N_p("input-name", "Positional V 5"), input_seq(MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, POSITIONAL_V, N_p("input-name", "Positional V 6"), input_seq(MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, POSITIONAL_V, N_p("input-name", "Positional V 7"), input_seq(MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, POSITIONAL_V, N_p("input-name", "Positional V 8"), input_seq(MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, POSITIONAL_V, N_p("input-name", "Positional V 9"), input_seq(MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, POSITIONAL_V, N_p("input-name", "Positional V 10"), input_seq(MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_DIAL \ CORE_INPUT_TYPES_BEGIN(dial) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, DIAL, N_p("input-name", "Dial"), input_seq(MOUSECODE_X_INDEXED(0), input_seq::or_code, JOYCODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, DIAL, N_p("input-name", "Dial 2"), input_seq(MOUSECODE_X_INDEXED(1), input_seq::or_code, JOYCODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, DIAL, N_p("input-name", "Dial 3"), input_seq(MOUSECODE_X_INDEXED(2), input_seq::or_code, JOYCODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, DIAL, N_p("input-name", "Dial 4"), input_seq(MOUSECODE_X_INDEXED(3), input_seq::or_code, JOYCODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, DIAL, N_p("input-name", "Dial 5"), input_seq(MOUSECODE_X_INDEXED(4), input_seq::or_code, JOYCODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, DIAL, N_p("input-name", "Dial 6"), input_seq(MOUSECODE_X_INDEXED(5), input_seq::or_code, JOYCODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, DIAL, N_p("input-name", "Dial 7"), input_seq(MOUSECODE_X_INDEXED(6), input_seq::or_code, JOYCODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, DIAL, N_p("input-name", "Dial 8"), input_seq(MOUSECODE_X_INDEXED(7), input_seq::or_code, JOYCODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, DIAL, N_p("input-name", "Dial 9"), input_seq(MOUSECODE_X_INDEXED(8), input_seq::or_code, JOYCODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, DIAL, N_p("input-name", "Dial 10"), input_seq(MOUSECODE_X_INDEXED(9), input_seq::or_code, JOYCODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, DIAL, N_p("input-name", "Dial"), input_seq(MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, DIAL, N_p("input-name", "Dial 2"), input_seq(MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, DIAL, N_p("input-name", "Dial 3"), input_seq(MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, DIAL, N_p("input-name", "Dial 4"), input_seq(MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, DIAL, N_p("input-name", "Dial 5"), input_seq(MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, DIAL, N_p("input-name", "Dial 6"), input_seq(MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, DIAL, N_p("input-name", "Dial 7"), input_seq(MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, DIAL, N_p("input-name", "Dial 8"), input_seq(MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, DIAL, N_p("input-name", "Dial 9"), input_seq(MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, DIAL, N_p("input-name", "Dial 10"), input_seq(MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_DIAL_V \ CORE_INPUT_TYPES_BEGIN(dial_v) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, DIAL_V, N_p("input-name", "Dial V"), input_seq(MOUSECODE_Y_INDEXED(0), input_seq::or_code, JOYCODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, DIAL_V, N_p("input-name", "Dial V 2"), input_seq(MOUSECODE_Y_INDEXED(1), input_seq::or_code, JOYCODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, DIAL_V, N_p("input-name", "Dial V 3"), input_seq(MOUSECODE_Y_INDEXED(2), input_seq::or_code, JOYCODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, DIAL_V, N_p("input-name", "Dial V 4"), input_seq(MOUSECODE_Y_INDEXED(3), input_seq::or_code, JOYCODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, DIAL_V, N_p("input-name", "Dial V 5"), input_seq(MOUSECODE_Y_INDEXED(4), input_seq::or_code, JOYCODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, DIAL_V, N_p("input-name", "Dial V 6"), input_seq(MOUSECODE_Y_INDEXED(5), input_seq::or_code, JOYCODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, DIAL_V, N_p("input-name", "Dial V 7"), input_seq(MOUSECODE_Y_INDEXED(6), input_seq::or_code, JOYCODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, DIAL_V, N_p("input-name", "Dial V 8"), input_seq(MOUSECODE_Y_INDEXED(7), input_seq::or_code, JOYCODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, DIAL_V, N_p("input-name", "Dial V 9"), input_seq(MOUSECODE_Y_INDEXED(8), input_seq::or_code, JOYCODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, DIAL_V, N_p("input-name", "Dial V 10"), input_seq(MOUSECODE_Y_INDEXED(9), input_seq::or_code, JOYCODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, DIAL_V, N_p("input-name", "Dial V"), input_seq(MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, DIAL_V, N_p("input-name", "Dial V 2"), input_seq(MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, DIAL_V, N_p("input-name", "Dial V 3"), input_seq(MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, DIAL_V, N_p("input-name", "Dial V 4"), input_seq(MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, DIAL_V, N_p("input-name", "Dial V 5"), input_seq(MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, DIAL_V, N_p("input-name", "Dial V 6"), input_seq(MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, DIAL_V, N_p("input-name", "Dial V 7"), input_seq(MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, DIAL_V, N_p("input-name", "Dial V 8"), input_seq(MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, DIAL_V, N_p("input-name", "Dial V 9"), input_seq(MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, DIAL_V, N_p("input-name", "Dial V 10"), input_seq(MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_TRACKBALL_X \ CORE_INPUT_TYPES_BEGIN(trackball_x) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, TRACKBALL_X, N_p("input-name", "Trackball X"), input_seq(MOUSECODE_X_INDEXED(0), input_seq::or_code, JOYCODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, TRACKBALL_X, N_p("input-name", "Trackball X 2"), input_seq(MOUSECODE_X_INDEXED(1), input_seq::or_code, JOYCODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, TRACKBALL_X, N_p("input-name", "Trackball X 3"), input_seq(MOUSECODE_X_INDEXED(2), input_seq::or_code, JOYCODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, TRACKBALL_X, N_p("input-name", "Trackball X 4"), input_seq(MOUSECODE_X_INDEXED(3), input_seq::or_code, JOYCODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, TRACKBALL_X, N_p("input-name", "Trackball X 5"), input_seq(MOUSECODE_X_INDEXED(4), input_seq::or_code, JOYCODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, TRACKBALL_X, N_p("input-name", "Trackball X 6"), input_seq(MOUSECODE_X_INDEXED(5), input_seq::or_code, JOYCODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, TRACKBALL_X, N_p("input-name", "Trackball X 7"), input_seq(MOUSECODE_X_INDEXED(6), input_seq::or_code, JOYCODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, TRACKBALL_X, N_p("input-name", "Trackball X 8"), input_seq(MOUSECODE_X_INDEXED(7), input_seq::or_code, JOYCODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, TRACKBALL_X, N_p("input-name", "Trackball X 9"), input_seq(MOUSECODE_X_INDEXED(8), input_seq::or_code, JOYCODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, TRACKBALL_X, N_p("input-name", "Trackball X 10"), input_seq(MOUSECODE_X_INDEXED(9), input_seq::or_code, JOYCODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, TRACKBALL_X, N_p("input-name", "Trackball X"), input_seq(MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, TRACKBALL_X, N_p("input-name", "Trackball X 2"), input_seq(MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, TRACKBALL_X, N_p("input-name", "Trackball X 3"), input_seq(MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, TRACKBALL_X, N_p("input-name", "Trackball X 4"), input_seq(MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, TRACKBALL_X, N_p("input-name", "Trackball X 5"), input_seq(MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, TRACKBALL_X, N_p("input-name", "Trackball X 6"), input_seq(MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, TRACKBALL_X, N_p("input-name", "Trackball X 7"), input_seq(MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, TRACKBALL_X, N_p("input-name", "Trackball X 8"), input_seq(MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, TRACKBALL_X, N_p("input-name", "Trackball X 9"), input_seq(MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, TRACKBALL_X, N_p("input-name", "Trackball X 10"), input_seq(MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_TRACKBALL_Y \ CORE_INPUT_TYPES_BEGIN(trackball_y) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, TRACKBALL_Y, N_p("input-name", "Trackball Y"), input_seq(MOUSECODE_Y_INDEXED(0), input_seq::or_code, JOYCODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, TRACKBALL_Y, N_p("input-name", "Trackball Y 2"), input_seq(MOUSECODE_Y_INDEXED(1), input_seq::or_code, JOYCODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, TRACKBALL_Y, N_p("input-name", "Trackball Y 3"), input_seq(MOUSECODE_Y_INDEXED(2), input_seq::or_code, JOYCODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, TRACKBALL_Y, N_p("input-name", "Trackball Y 4"), input_seq(MOUSECODE_Y_INDEXED(3), input_seq::or_code, JOYCODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, TRACKBALL_Y, N_p("input-name", "Trackball Y 5"), input_seq(MOUSECODE_Y_INDEXED(4), input_seq::or_code, JOYCODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, TRACKBALL_Y, N_p("input-name", "Trackball Y 6"), input_seq(MOUSECODE_Y_INDEXED(5), input_seq::or_code, JOYCODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, TRACKBALL_Y, N_p("input-name", "Trackball Y 7"), input_seq(MOUSECODE_Y_INDEXED(6), input_seq::or_code, JOYCODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, TRACKBALL_Y, N_p("input-name", "Trackball Y 8"), input_seq(MOUSECODE_Y_INDEXED(7), input_seq::or_code, JOYCODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, TRACKBALL_Y, N_p("input-name", "Trackball Y 9"), input_seq(MOUSECODE_Y_INDEXED(8), input_seq::or_code, JOYCODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, TRACKBALL_Y, N_p("input-name", "Trackball Y 10"), input_seq(MOUSECODE_Y_INDEXED(9), input_seq::or_code, JOYCODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, TRACKBALL_Y, N_p("input-name", "Trackball Y"), input_seq(MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, TRACKBALL_Y, N_p("input-name", "Trackball Y 2"), input_seq(MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, TRACKBALL_Y, N_p("input-name", "Trackball Y 3"), input_seq(MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, TRACKBALL_Y, N_p("input-name", "Trackball Y 4"), input_seq(MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, TRACKBALL_Y, N_p("input-name", "Trackball Y 5"), input_seq(MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, TRACKBALL_Y, N_p("input-name", "Trackball Y 6"), input_seq(MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, TRACKBALL_Y, N_p("input-name", "Trackball Y 7"), input_seq(MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, TRACKBALL_Y, N_p("input-name", "Trackball Y 8"), input_seq(MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, TRACKBALL_Y, N_p("input-name", "Trackball Y 9"), input_seq(MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, TRACKBALL_Y, N_p("input-name", "Trackball Y 10"), input_seq(MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_AD_STICK_X \ CORE_INPUT_TYPES_BEGIN(ad_stick_x) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_X, N_p("input-name", "AD Stick X"), input_seq(JOYCODE_X_INDEXED(0), input_seq::or_code, MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_X, N_p("input-name", "AD Stick X 2"), input_seq(JOYCODE_X_INDEXED(1), input_seq::or_code, MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_X, N_p("input-name", "AD Stick X 3"), input_seq(JOYCODE_X_INDEXED(2), input_seq::or_code, MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_X, N_p("input-name", "AD Stick X 4"), input_seq(JOYCODE_X_INDEXED(3), input_seq::or_code, MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_X, N_p("input-name", "AD Stick X 5"), input_seq(JOYCODE_X_INDEXED(4), input_seq::or_code, MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_X, N_p("input-name", "AD Stick X 6"), input_seq(JOYCODE_X_INDEXED(5), input_seq::or_code, MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_X, N_p("input-name", "AD Stick X 7"), input_seq(JOYCODE_X_INDEXED(6), input_seq::or_code, MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_X, N_p("input-name", "AD Stick X 8"), input_seq(JOYCODE_X_INDEXED(7), input_seq::or_code, MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_X, N_p("input-name", "AD Stick X 9"), input_seq(JOYCODE_X_INDEXED(8), input_seq::or_code, MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_X, N_p("input-name", "AD Stick X 10"), input_seq(JOYCODE_X_INDEXED(9), input_seq::or_code, MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_X, N_p("input-name", "AD Stick X"), input_seq(MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_X, N_p("input-name", "AD Stick X 2"), input_seq(MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_X, N_p("input-name", "AD Stick X 3"), input_seq(MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_X, N_p("input-name", "AD Stick X 4"), input_seq(MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_X, N_p("input-name", "AD Stick X 5"), input_seq(MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_X, N_p("input-name", "AD Stick X 6"), input_seq(MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_X, N_p("input-name", "AD Stick X 7"), input_seq(MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_X, N_p("input-name", "AD Stick X 8"), input_seq(MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_X, N_p("input-name", "AD Stick X 9"), input_seq(MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_X, N_p("input-name", "AD Stick X 10"), input_seq(MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_AD_STICK_Y \ CORE_INPUT_TYPES_BEGIN(ad_stick_y) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_Y, N_p("input-name", "AD Stick Y"), input_seq(JOYCODE_Y_INDEXED(0), input_seq::or_code, MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_Y, N_p("input-name", "AD Stick Y 2"), input_seq(JOYCODE_Y_INDEXED(1), input_seq::or_code, MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_Y, N_p("input-name", "AD Stick Y 3"), input_seq(JOYCODE_Y_INDEXED(2), input_seq::or_code, MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_Y, N_p("input-name", "AD Stick Y 4"), input_seq(JOYCODE_Y_INDEXED(3), input_seq::or_code, MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_Y, N_p("input-name", "AD Stick Y 5"), input_seq(JOYCODE_Y_INDEXED(4), input_seq::or_code, MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_Y, N_p("input-name", "AD Stick Y 6"), input_seq(JOYCODE_Y_INDEXED(5), input_seq::or_code, MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_Y, N_p("input-name", "AD Stick Y 7"), input_seq(JOYCODE_Y_INDEXED(6), input_seq::or_code, MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_Y, N_p("input-name", "AD Stick Y 8"), input_seq(JOYCODE_Y_INDEXED(7), input_seq::or_code, MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_Y, N_p("input-name", "AD Stick Y 9"), input_seq(JOYCODE_Y_INDEXED(8), input_seq::or_code, MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_Y, N_p("input-name", "AD Stick Y 10"), input_seq(JOYCODE_Y_INDEXED(9), input_seq::or_code, MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_Y, N_p("input-name", "AD Stick Y"), input_seq(MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_Y, N_p("input-name", "AD Stick Y 2"), input_seq(MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_Y, N_p("input-name", "AD Stick Y 3"), input_seq(MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_Y, N_p("input-name", "AD Stick Y 4"), input_seq(MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_Y, N_p("input-name", "AD Stick Y 5"), input_seq(MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_Y, N_p("input-name", "AD Stick Y 6"), input_seq(MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_Y, N_p("input-name", "AD Stick Y 7"), input_seq(MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_Y, N_p("input-name", "AD Stick Y 8"), input_seq(MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_Y, N_p("input-name", "AD Stick Y 9"), input_seq(MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_Y, N_p("input-name", "AD Stick Y 10"), input_seq(MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_AD_STICK_Z \ CORE_INPUT_TYPES_BEGIN(ad_stick_z) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_Z, N_p("input-name", "AD Stick Z"), input_seq(JOYCODE_Z_INDEXED(0)), input_seq(KEYCODE_A), input_seq(KEYCODE_Z) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_Z, N_p("input-name", "AD Stick Z 2"), input_seq(JOYCODE_Z_INDEXED(1)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_Z, N_p("input-name", "AD Stick Z 3"), input_seq(JOYCODE_Z_INDEXED(2)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_Z, N_p("input-name", "AD Stick Z 4"), input_seq(JOYCODE_Z_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_Z, N_p("input-name", "AD Stick Z 5"), input_seq(JOYCODE_Z_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_Z, N_p("input-name", "AD Stick Z 6"), input_seq(JOYCODE_Z_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_Z, N_p("input-name", "AD Stick Z 7"), input_seq(JOYCODE_Z_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_Z, N_p("input-name", "AD Stick Z 8"), input_seq(JOYCODE_Z_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_Z, N_p("input-name", "AD Stick Z 9"), input_seq(JOYCODE_Z_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_Z, N_p("input-name", "AD Stick Z 10"), input_seq(JOYCODE_Z_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, AD_STICK_Z, N_p("input-name", "AD Stick Z"), input_seq(), input_seq(KEYCODE_A), input_seq(KEYCODE_Z) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, AD_STICK_Z, N_p("input-name", "AD Stick Z 2"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, AD_STICK_Z, N_p("input-name", "AD Stick Z 3"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, AD_STICK_Z, N_p("input-name", "AD Stick Z 4"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, AD_STICK_Z, N_p("input-name", "AD Stick Z 5"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, AD_STICK_Z, N_p("input-name", "AD Stick Z 6"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, AD_STICK_Z, N_p("input-name", "AD Stick Z 7"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, AD_STICK_Z, N_p("input-name", "AD Stick Z 8"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, AD_STICK_Z, N_p("input-name", "AD Stick Z 9"), input_seq(), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, AD_STICK_Z, N_p("input-name", "AD Stick Z 10"), input_seq(), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_LIGHTGUN_X \ CORE_INPUT_TYPES_BEGIN(lightgun_x) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, LIGHTGUN_X, N_p("input-name", "Lightgun X"), input_seq(GUNCODE_X_INDEXED(0), input_seq::or_code, MOUSECODE_X_INDEXED(0), input_seq::or_code, JOYCODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, LIGHTGUN_X, N_p("input-name", "Lightgun X 2"), input_seq(GUNCODE_X_INDEXED(1), input_seq::or_code, MOUSECODE_X_INDEXED(1), input_seq::or_code, JOYCODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, LIGHTGUN_X, N_p("input-name", "Lightgun X 3"), input_seq(GUNCODE_X_INDEXED(2), input_seq::or_code, MOUSECODE_X_INDEXED(2), input_seq::or_code, JOYCODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, LIGHTGUN_X, N_p("input-name", "Lightgun X 4"), input_seq(GUNCODE_X_INDEXED(3), input_seq::or_code, MOUSECODE_X_INDEXED(3), input_seq::or_code, JOYCODE_X_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, LIGHTGUN_X, N_p("input-name", "Lightgun X 5"), input_seq(GUNCODE_X_INDEXED(4), input_seq::or_code, MOUSECODE_X_INDEXED(4), input_seq::or_code, JOYCODE_X_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, LIGHTGUN_X, N_p("input-name", "Lightgun X 6"), input_seq(GUNCODE_X_INDEXED(5), input_seq::or_code, MOUSECODE_X_INDEXED(5), input_seq::or_code, JOYCODE_X_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, LIGHTGUN_X, N_p("input-name", "Lightgun X 7"), input_seq(GUNCODE_X_INDEXED(6), input_seq::or_code, MOUSECODE_X_INDEXED(6), input_seq::or_code, JOYCODE_X_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, LIGHTGUN_X, N_p("input-name", "Lightgun X 8"), input_seq(GUNCODE_X_INDEXED(7), input_seq::or_code, MOUSECODE_X_INDEXED(7), input_seq::or_code, JOYCODE_X_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, LIGHTGUN_X, N_p("input-name", "Lightgun X 9"), input_seq(GUNCODE_X_INDEXED(8), input_seq::or_code, MOUSECODE_X_INDEXED(8), input_seq::or_code, JOYCODE_X_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, LIGHTGUN_X, N_p("input-name", "Lightgun X 10"), input_seq(GUNCODE_X_INDEXED(9), input_seq::or_code, MOUSECODE_X_INDEXED(9), input_seq::or_code, JOYCODE_X_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, LIGHTGUN_X, N_p("input-name", "Lightgun X"), input_seq(GUNCODE_X_INDEXED(0), input_seq::or_code, MOUSECODE_X_INDEXED(0)), input_seq(KEYCODE_LEFT), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, LIGHTGUN_X, N_p("input-name", "Lightgun X 2"), input_seq(GUNCODE_X_INDEXED(1), input_seq::or_code, MOUSECODE_X_INDEXED(1)), input_seq(KEYCODE_D), input_seq(KEYCODE_G) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, LIGHTGUN_X, N_p("input-name", "Lightgun X 3"), input_seq(GUNCODE_X_INDEXED(2), input_seq::or_code, MOUSECODE_X_INDEXED(2)), input_seq(KEYCODE_J), input_seq(KEYCODE_L) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, LIGHTGUN_X, N_p("input-name", "Lightgun X 4"), input_seq(GUNCODE_X_INDEXED(3), input_seq::or_code, MOUSECODE_X_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, LIGHTGUN_X, N_p("input-name", "Lightgun X 5"), input_seq(GUNCODE_X_INDEXED(4), input_seq::or_code, MOUSECODE_X_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, LIGHTGUN_X, N_p("input-name", "Lightgun X 6"), input_seq(GUNCODE_X_INDEXED(5), input_seq::or_code, MOUSECODE_X_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, LIGHTGUN_X, N_p("input-name", "Lightgun X 7"), input_seq(GUNCODE_X_INDEXED(6), input_seq::or_code, MOUSECODE_X_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, LIGHTGUN_X, N_p("input-name", "Lightgun X 8"), input_seq(GUNCODE_X_INDEXED(7), input_seq::or_code, MOUSECODE_X_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, LIGHTGUN_X, N_p("input-name", "Lightgun X 9"), input_seq(GUNCODE_X_INDEXED(8), input_seq::or_code, MOUSECODE_X_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, LIGHTGUN_X, N_p("input-name", "Lightgun X 10"), input_seq(GUNCODE_X_INDEXED(9), input_seq::or_code, MOUSECODE_X_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_LIGHTGUN_Y \ CORE_INPUT_TYPES_BEGIN(lightgun_y) \ - INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, LIGHTGUN_Y, N_p("input-name", "Lightgun Y"), input_seq(GUNCODE_Y_INDEXED(0), input_seq::or_code, MOUSECODE_Y_INDEXED(0), input_seq::or_code, JOYCODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ - INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 2"), input_seq(GUNCODE_Y_INDEXED(1), input_seq::or_code, MOUSECODE_Y_INDEXED(1), input_seq::or_code, JOYCODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ - INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 3"), input_seq(GUNCODE_Y_INDEXED(2), input_seq::or_code, MOUSECODE_Y_INDEXED(2), input_seq::or_code, JOYCODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ - INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 4"), input_seq(GUNCODE_Y_INDEXED(3), input_seq::or_code, MOUSECODE_Y_INDEXED(3), input_seq::or_code, JOYCODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 5"), input_seq(GUNCODE_Y_INDEXED(4), input_seq::or_code, MOUSECODE_Y_INDEXED(4), input_seq::or_code, JOYCODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 6"), input_seq(GUNCODE_Y_INDEXED(5), input_seq::or_code, MOUSECODE_Y_INDEXED(5), input_seq::or_code, JOYCODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 7"), input_seq(GUNCODE_Y_INDEXED(6), input_seq::or_code, MOUSECODE_Y_INDEXED(6), input_seq::or_code, JOYCODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 8"), input_seq(GUNCODE_Y_INDEXED(7), input_seq::or_code, MOUSECODE_Y_INDEXED(7), input_seq::or_code, JOYCODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 9"), input_seq(GUNCODE_Y_INDEXED(8), input_seq::or_code, MOUSECODE_Y_INDEXED(8), input_seq::or_code, JOYCODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ - INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 10"), input_seq(GUNCODE_Y_INDEXED(9), input_seq::or_code, MOUSECODE_Y_INDEXED(9), input_seq::or_code, JOYCODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 1, PLAYER1, LIGHTGUN_Y, N_p("input-name", "Lightgun Y"), input_seq(GUNCODE_Y_INDEXED(0), input_seq::or_code, MOUSECODE_Y_INDEXED(0)), input_seq(KEYCODE_UP), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_ANALOG_TYPE( 2, PLAYER2, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 2"), input_seq(GUNCODE_Y_INDEXED(1), input_seq::or_code, MOUSECODE_Y_INDEXED(1)), input_seq(KEYCODE_R), input_seq(KEYCODE_F) ) \ + INPUT_PORT_ANALOG_TYPE( 3, PLAYER3, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 3"), input_seq(GUNCODE_Y_INDEXED(2), input_seq::or_code, MOUSECODE_Y_INDEXED(2)), input_seq(KEYCODE_I), input_seq(KEYCODE_K) ) \ + INPUT_PORT_ANALOG_TYPE( 4, PLAYER4, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 4"), input_seq(GUNCODE_Y_INDEXED(3), input_seq::or_code, MOUSECODE_Y_INDEXED(3)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 5, PLAYER5, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 5"), input_seq(GUNCODE_Y_INDEXED(4), input_seq::or_code, MOUSECODE_Y_INDEXED(4)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 6, PLAYER6, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 6"), input_seq(GUNCODE_Y_INDEXED(5), input_seq::or_code, MOUSECODE_Y_INDEXED(5)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 7, PLAYER7, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 7"), input_seq(GUNCODE_Y_INDEXED(6), input_seq::or_code, MOUSECODE_Y_INDEXED(6)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 8, PLAYER8, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 8"), input_seq(GUNCODE_Y_INDEXED(7), input_seq::or_code, MOUSECODE_Y_INDEXED(7)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 9, PLAYER9, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 9"), input_seq(GUNCODE_Y_INDEXED(8), input_seq::or_code, MOUSECODE_Y_INDEXED(8)), input_seq(), input_seq() ) \ + INPUT_PORT_ANALOG_TYPE( 10, PLAYER10, LIGHTGUN_Y, N_p("input-name", "Lightgun Y 10"), input_seq(GUNCODE_Y_INDEXED(9), input_seq::or_code, MOUSECODE_Y_INDEXED(9)), input_seq(), input_seq() ) \ CORE_INPUT_TYPES_END() #define CORE_INPUT_TYPES_MOUSE_X \ @@ -871,12 +871,30 @@ namespace { #define CORE_INPUT_TYPES_UI \ CORE_INPUT_TYPES_BEGIN(ui) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_MENU, N_p("input-name", "Show/Hide Menu"), input_seq(KEYCODE_TAB) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SELECT, N_p("input-name", "UI Select"), input_seq(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT, input_seq::or_code, KEYCODE_ENTER_PAD) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_BACK, N_p("input-name", "UI Back"), input_seq(KEYCODE_ESC) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CANCEL, N_p("input-name", "UI Cancel"), input_seq(KEYCODE_ESC) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CLEAR, N_p("input-name", "UI Clear"), input_seq(KEYCODE_DEL) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_HELP, N_p("input-name", "UI Help"), input_seq(KEYCODE_F1) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, N_p("input-name", "UI Up"), input_seq(KEYCODE_UP) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN, N_p("input-name", "UI Down"), input_seq(KEYCODE_DOWN) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LEFT, N_p("input-name", "UI Left"), input_seq(KEYCODE_LEFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT, N_p("input-name", "UI Right"), input_seq(KEYCODE_RIGHT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_HOME, N_p("input-name", "UI Home"), input_seq(KEYCODE_HOME) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_END, N_p("input-name", "UI End"), input_seq(KEYCODE_END) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_UP, N_p("input-name", "UI Page Up"), input_seq(KEYCODE_PGUP) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_DOWN, N_p("input-name", "UI Page Down"), input_seq(KEYCODE_PGDN) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PREV_GROUP, N_p("input-name", "UI Previous Group"), input_seq(KEYCODE_OPENBRACE) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_NEXT_GROUP, N_p("input-name", "UI Next Group"), input_seq(KEYCODE_CLOSEBRACE) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ON_SCREEN_DISPLAY, N_p("input-name", "On Screen Display"), input_seq(KEYCODE_TILDE, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_UI, N_p("input-name", "Toggle UI Controls"), input_seq(KEYCODE_SCRLOCK, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DEBUG_BREAK, N_p("input-name", "Break in Debugger"), input_seq(KEYCODE_TILDE, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CONFIGURE, N_p("input-name", "Config Menu"), input_seq(KEYCODE_TAB) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAUSE, N_p("input-name", "Pause"), input_seq(KEYCODE_P, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAUSE_SINGLE, N_p("input-name", "Pause - Single Step"), input_seq(KEYCODE_P, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_P, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_REWIND_SINGLE, N_p("input-name", "Rewind - Single Step"), input_seq(KEYCODE_TILDE, KEYCODE_LSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SAVE_STATE, N_p("input-name", "Save State"), input_seq(KEYCODE_F7, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_F7, KEYCODE_RSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LOAD_STATE, N_p("input-name", "Load State"), input_seq(KEYCODE_F7, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RESET_MACHINE, N_p("input-name", "Reset Machine"), input_seq(KEYCODE_F3, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_F3, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SOFT_RESET, N_p("input-name", "Soft Reset"), input_seq(KEYCODE_F3, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_GFX, N_p("input-name", "Show Decoded Graphics"), input_seq(KEYCODE_F4) ) \ @@ -889,36 +907,20 @@ namespace { INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_MNG, N_p("input-name", "Record MNG"), input_seq(KEYCODE_F12, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_LCONTROL) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_AVI, N_p("input-name", "Record AVI"), input_seq(KEYCODE_F12, KEYCODE_LSHIFT, KEYCODE_LCONTROL) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_CHEAT, N_p("input-name", "Toggle Cheat"), input_seq(KEYCODE_F6) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, N_p("input-name", "UI Up"), input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0), input_seq::or_code, JOYCODE_HAT1UP_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN, N_p("input-name", "UI Down"), input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0), input_seq::or_code, JOYCODE_HAT1DOWN_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LEFT, N_p("input-name", "UI Left"), input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0), input_seq::or_code, JOYCODE_HAT1LEFT_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT, N_p("input-name", "UI Right"), input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0), input_seq::or_code, JOYCODE_HAT1RIGHT_INDEXED(0)) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_HOME, N_p("input-name", "UI Home"), input_seq(KEYCODE_HOME) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_END, N_p("input-name", "UI End"), input_seq(KEYCODE_END) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_UP, N_p("input-name", "UI Page Up"), input_seq(KEYCODE_PGUP) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_DOWN, N_p("input-name", "UI Page Down"), input_seq(KEYCODE_PGDN) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_NEXT, N_p("input-name", "UI Focus Next"), input_seq(KEYCODE_TAB, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_PREV, N_p("input-name", "UI Focus Previous"), input_seq(KEYCODE_TAB, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_TAB, KEYCODE_RSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SELECT, N_p("input-name", "UI Select"), input_seq(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, KEYCODE_ENTER_PAD) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CANCEL, N_p("input-name", "UI Cancel"), input_seq(KEYCODE_ESC) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DISPLAY_COMMENT, N_p("input-name", "UI Display Comment"), input_seq(KEYCODE_SPACE) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CLEAR, N_p("input-name", "UI Clear"), input_seq(KEYCODE_DEL) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ZOOM_IN, N_p("input-name", "UI Zoom In"), input_seq(KEYCODE_EQUALS) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ZOOM_OUT, N_p("input-name", "UI Zoom Out"), input_seq(KEYCODE_MINUS) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ZOOM_DEFAULT, N_p("input-name", "UI Default Zoom"), input_seq(KEYCODE_0) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PREV_GROUP, N_p("input-name", "UI Previous Group"), input_seq(KEYCODE_OPENBRACE) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_NEXT_GROUP, N_p("input-name", "UI Next Group"), input_seq(KEYCODE_CLOSEBRACE) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_ROTATE, N_p("input-name", "UI Rotate"), input_seq(KEYCODE_R) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_PROFILER, N_p("input-name", "Show Profiler"), input_seq(KEYCODE_F11, KEYCODE_LSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_UI, N_p("input-name", "UI Toggle"), input_seq(KEYCODE_SCRLOCK, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RELEASE_POINTER, N_p("input-name", "UI Release Pointer"), input_seq(KEYCODE_RCONTROL, KEYCODE_RALT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PASTE, N_p("input-name", "UI Paste Text"), input_seq(KEYCODE_SCRLOCK, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_SCRLOCK, KEYCODE_RSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SAVE_STATE, N_p("input-name", "Save State"), input_seq(KEYCODE_F7, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_F7, KEYCODE_RSHIFT) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LOAD_STATE, N_p("input-name", "Load State"), input_seq(KEYCODE_F7, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TAPE_START, N_p("input-name", "UI (First) Tape Start"), input_seq(KEYCODE_F2, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TAPE_STOP, N_p("input-name", "UI (First) Tape Stop"), input_seq(KEYCODE_F2, KEYCODE_LSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_NEXT, N_p("input-name", "UI Focus Next"), input_seq(KEYCODE_TAB, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_PREV, N_p("input-name", "UI Focus Previous"), input_seq(KEYCODE_TAB, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_TAB, KEYCODE_RSHIFT) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DATS, N_p("input-name", "UI External DAT View"), input_seq(KEYCODE_LALT, KEYCODE_D) ) \ - INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FAVORITES, N_p("input-name", "UI Add/Remove favorite"), input_seq(KEYCODE_LALT, KEYCODE_F) ) \ + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FAVORITES, N_p("input-name", "UI Add/Remove Favorite"), input_seq(KEYCODE_LALT, KEYCODE_F) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_EXPORT, N_p("input-name", "UI Export List"), input_seq(KEYCODE_LALT, KEYCODE_E) ) \ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_AUDIT, N_p("input-name", "UI Audit Media"), input_seq(KEYCODE_F1, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \ CORE_INPUT_TYPES_END() diff --git a/src/emu/ioport.h b/src/emu/ioport.h index f74f1f54f16..0a80e01bd00 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -17,6 +17,8 @@ #ifndef MAME_EMU_IOPORT_H #define MAME_EMU_IOPORT_H +#include "inpttype.h" + #include "ioprocs.h" #include <array> @@ -48,18 +50,6 @@ constexpr char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2; constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2; -// sequence types for input_port_seq() call -enum input_seq_type : int -{ - SEQ_TYPE_INVALID = -1, - SEQ_TYPE_STANDARD = 0, - SEQ_TYPE_INCREMENT, - SEQ_TYPE_DECREMENT, - SEQ_TYPE_TOTAL -}; -DECLARE_ENUM_INCDEC_OPERATORS(input_seq_type) - - // crosshair types enum crosshair_axis_t { @@ -89,323 +79,6 @@ enum ioport_group }; -// various input port types -enum ioport_type : u32 -{ - // pseudo-port types - IPT_INVALID = 0, - IPT_UNUSED, - IPT_END, - IPT_UNKNOWN, - IPT_PORT, - IPT_DIPSWITCH, - IPT_CONFIG, - - // start buttons - IPT_START1, - IPT_START2, - IPT_START3, - IPT_START4, - IPT_START5, - IPT_START6, - IPT_START7, - IPT_START8, - IPT_START9, - IPT_START10, - - // coin slots - IPT_COIN1, - IPT_COIN2, - IPT_COIN3, - IPT_COIN4, - IPT_COIN5, - IPT_COIN6, - IPT_COIN7, - IPT_COIN8, - IPT_COIN9, - IPT_COIN10, - IPT_COIN11, - IPT_COIN12, - IPT_BILL1, - - // service coin - IPT_SERVICE1, - IPT_SERVICE2, - IPT_SERVICE3, - IPT_SERVICE4, - - // tilt inputs - IPT_TILT1, - IPT_TILT2, - IPT_TILT3, - IPT_TILT4, - - // misc other digital inputs - IPT_POWER_ON, - IPT_POWER_OFF, - IPT_SERVICE, - IPT_TILT, - IPT_INTERLOCK, - IPT_MEMORY_RESET, - IPT_VOLUME_UP, - IPT_VOLUME_DOWN, - IPT_START, // use the numbered start button(s) for coin-ops - IPT_SELECT, - IPT_KEYPAD, - IPT_KEYBOARD, - - // digital joystick inputs - IPT_DIGITAL_JOYSTICK_FIRST, - - // use IPT_JOYSTICK for panels where the player has one single joystick - IPT_JOYSTICK_UP, - IPT_JOYSTICK_DOWN, - IPT_JOYSTICK_LEFT, - IPT_JOYSTICK_RIGHT, - - // use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels - IPT_JOYSTICKRIGHT_UP, - IPT_JOYSTICKRIGHT_DOWN, - IPT_JOYSTICKRIGHT_LEFT, - IPT_JOYSTICKRIGHT_RIGHT, - IPT_JOYSTICKLEFT_UP, - IPT_JOYSTICKLEFT_DOWN, - IPT_JOYSTICKLEFT_LEFT, - IPT_JOYSTICKLEFT_RIGHT, - - IPT_DIGITAL_JOYSTICK_LAST, - - // action buttons - IPT_BUTTON1, - IPT_BUTTON2, - IPT_BUTTON3, - IPT_BUTTON4, - IPT_BUTTON5, - IPT_BUTTON6, - IPT_BUTTON7, - IPT_BUTTON8, - IPT_BUTTON9, - IPT_BUTTON10, - IPT_BUTTON11, - IPT_BUTTON12, - IPT_BUTTON13, - IPT_BUTTON14, - IPT_BUTTON15, - IPT_BUTTON16, - - // mahjong inputs - IPT_MAHJONG_FIRST, - - IPT_MAHJONG_A, - IPT_MAHJONG_B, - IPT_MAHJONG_C, - IPT_MAHJONG_D, - IPT_MAHJONG_E, - IPT_MAHJONG_F, - IPT_MAHJONG_G, - IPT_MAHJONG_H, - IPT_MAHJONG_I, - IPT_MAHJONG_J, - IPT_MAHJONG_K, - IPT_MAHJONG_L, - IPT_MAHJONG_M, - IPT_MAHJONG_N, - IPT_MAHJONG_O, - IPT_MAHJONG_P, - IPT_MAHJONG_Q, - IPT_MAHJONG_KAN, - IPT_MAHJONG_PON, - IPT_MAHJONG_CHI, - IPT_MAHJONG_REACH, - IPT_MAHJONG_RON, - IPT_MAHJONG_FLIP_FLOP, - IPT_MAHJONG_BET, - IPT_MAHJONG_SCORE, - IPT_MAHJONG_DOUBLE_UP, - IPT_MAHJONG_BIG, - IPT_MAHJONG_SMALL, - IPT_MAHJONG_LAST_CHANCE, - - IPT_MAHJONG_LAST, - - // hanafuda inputs - IPT_HANAFUDA_FIRST, - - IPT_HANAFUDA_A, - IPT_HANAFUDA_B, - IPT_HANAFUDA_C, - IPT_HANAFUDA_D, - IPT_HANAFUDA_E, - IPT_HANAFUDA_F, - IPT_HANAFUDA_G, - IPT_HANAFUDA_H, - IPT_HANAFUDA_YES, - IPT_HANAFUDA_NO, - - IPT_HANAFUDA_LAST, - - // gambling inputs - IPT_GAMBLING_FIRST, - - IPT_GAMBLE_KEYIN, // attendant - IPT_GAMBLE_KEYOUT, // attendant - IPT_GAMBLE_SERVICE, // attendant - IPT_GAMBLE_BOOK, // attendant - IPT_GAMBLE_DOOR, // attendant - // IPT_GAMBLE_DOOR2, // many gambling games have several doors. - // IPT_GAMBLE_DOOR3, - // IPT_GAMBLE_DOOR4, - // IPT_GAMBLE_DOOR5, - - IPT_GAMBLE_PAYOUT, // player - IPT_GAMBLE_BET, // player - IPT_GAMBLE_DEAL, // player - IPT_GAMBLE_STAND, // player - IPT_GAMBLE_TAKE, // player - IPT_GAMBLE_D_UP, // player - IPT_GAMBLE_HALF, // player - IPT_GAMBLE_HIGH, // player - IPT_GAMBLE_LOW, // player - - // poker-specific inputs - IPT_POKER_HOLD1, - IPT_POKER_HOLD2, - IPT_POKER_HOLD3, - IPT_POKER_HOLD4, - IPT_POKER_HOLD5, - IPT_POKER_CANCEL, - - // slot-specific inputs - IPT_SLOT_STOP1, - IPT_SLOT_STOP2, - IPT_SLOT_STOP3, - IPT_SLOT_STOP4, - IPT_SLOT_STOP_ALL, - - IPT_GAMBLING_LAST, - - // analog inputs - IPT_ANALOG_FIRST, - - IPT_ANALOG_ABSOLUTE_FIRST, - - IPT_AD_STICK_X, // absolute // autocenter - IPT_AD_STICK_Y, // absolute // autocenter - IPT_AD_STICK_Z, // absolute // autocenter - IPT_PADDLE, // absolute // autocenter - IPT_PADDLE_V, // absolute // autocenter - IPT_PEDAL, // absolute // autocenter - IPT_PEDAL2, // absolute // autocenter - IPT_PEDAL3, // absolute // autocenter - IPT_LIGHTGUN_X, // absolute - IPT_LIGHTGUN_Y, // absolute - IPT_POSITIONAL, // absolute // autocenter if not wraps - IPT_POSITIONAL_V, // absolute // autocenter if not wraps - - IPT_ANALOG_ABSOLUTE_LAST, - - IPT_DIAL, // relative - IPT_DIAL_V, // relative - IPT_TRACKBALL_X, // relative - IPT_TRACKBALL_Y, // relative - IPT_MOUSE_X, // relative - IPT_MOUSE_Y, // relative - - IPT_ANALOG_LAST, - - // analog adjuster support - IPT_ADJUSTER, - - // the following are special codes for user interface handling - not to be used by drivers! - IPT_UI_FIRST, - - IPT_UI_CONFIGURE, - IPT_UI_ON_SCREEN_DISPLAY, - IPT_UI_DEBUG_BREAK, - IPT_UI_PAUSE, - IPT_UI_PAUSE_SINGLE, - IPT_UI_REWIND_SINGLE, - IPT_UI_RESET_MACHINE, - IPT_UI_SOFT_RESET, - IPT_UI_SHOW_GFX, - IPT_UI_FRAMESKIP_DEC, - IPT_UI_FRAMESKIP_INC, - IPT_UI_THROTTLE, - IPT_UI_FAST_FORWARD, - IPT_UI_SHOW_FPS, - IPT_UI_SNAPSHOT, - IPT_UI_RECORD_MNG, - IPT_UI_RECORD_AVI, - IPT_UI_TOGGLE_CHEAT, - IPT_UI_UP, - IPT_UI_DOWN, - IPT_UI_LEFT, - IPT_UI_RIGHT, - IPT_UI_HOME, - IPT_UI_END, - IPT_UI_PAGE_UP, - IPT_UI_PAGE_DOWN, - IPT_UI_FOCUS_NEXT, - IPT_UI_FOCUS_PREV, - IPT_UI_SELECT, - IPT_UI_CANCEL, - IPT_UI_DISPLAY_COMMENT, - IPT_UI_CLEAR, - IPT_UI_ZOOM_IN, - IPT_UI_ZOOM_OUT, - IPT_UI_ZOOM_DEFAULT, - IPT_UI_PREV_GROUP, - IPT_UI_NEXT_GROUP, - IPT_UI_ROTATE, - IPT_UI_SHOW_PROFILER, - IPT_UI_TOGGLE_UI, - IPT_UI_RELEASE_POINTER, - IPT_UI_PASTE, - IPT_UI_SAVE_STATE, - IPT_UI_LOAD_STATE, - IPT_UI_TAPE_START, - IPT_UI_TAPE_STOP, - IPT_UI_DATS, - IPT_UI_FAVORITES, - IPT_UI_EXPORT, - IPT_UI_AUDIT, - - // additional OSD-specified UI port types (up to 16) - IPT_OSD_1, - IPT_OSD_2, - IPT_OSD_3, - IPT_OSD_4, - IPT_OSD_5, - IPT_OSD_6, - IPT_OSD_7, - IPT_OSD_8, - IPT_OSD_9, - IPT_OSD_10, - IPT_OSD_11, - IPT_OSD_12, - IPT_OSD_13, - IPT_OSD_14, - IPT_OSD_15, - IPT_OSD_16, - - IPT_UI_LAST, - - IPT_OTHER, // not mapped to standard defaults - - IPT_SPECIAL, // uninterpreted characters - IPT_CUSTOM, // handled by custom code - IPT_OUTPUT, - - IPT_COUNT -}; -DECLARE_ENUM_INCDEC_OPERATORS(ioport_type) -// aliases for some types -#define IPT_PADDLE_H IPT_PADDLE -#define IPT_PEDAL1 IPT_PEDAL -#define IPT_POSITIONAL_H IPT_POSITIONAL -#define IPT_DIAL_H IPT_DIAL - - // input type classes enum ioport_type_class { diff --git a/src/frontend/mame/luaengine_input.cpp b/src/frontend/mame/luaengine_input.cpp index 62e768d0d33..42fe2d49d78 100644 --- a/src/frontend/mame/luaengine_input.cpp +++ b/src/frontend/mame/luaengine_input.cpp @@ -512,16 +512,18 @@ void lua_engine::initialize_input(sol::table &emu) auto uiinput_type = sol().registry().new_usertype<ui_input_manager>("uiinput", sol::no_constructor); - uiinput_type["find_mouse"] = + uiinput_type.set_function("reset", &ui_input_manager::reset); + uiinput_type.set_function( + "find_mouse", [] (ui_input_manager &ui) { int32_t x, y; bool button; render_target *rt = ui.find_mouse(&x, &y, &button); return std::make_tuple(x, y, button, rt); - }; - uiinput_type["pressed"] = &ui_input_manager::pressed; - uiinput_type["pressed_repeat"] = &ui_input_manager::pressed_repeat; + }); + uiinput_type.set_function("pressed", &ui_input_manager::pressed); + uiinput_type.set_function("pressed_repeat", &ui_input_manager::pressed_repeat); uiinput_type["presses_enabled"] = sol::property(&ui_input_manager::presses_enabled, &ui_input_manager::set_presses_enabled); } diff --git a/src/frontend/mame/ui/analogipt.cpp b/src/frontend/mame/ui/analogipt.cpp index ed0daf0b152..fde76f47173 100644 --- a/src/frontend/mame/ui/analogipt.cpp +++ b/src/frontend/mame/ui/analogipt.cpp @@ -11,6 +11,8 @@ #include "emu.h" #include "ui/analogipt.h" +#include "ui/textbox.h" + #include <algorithm> #include <iterator> #include <string> @@ -19,6 +21,20 @@ namespace ui { +namespace { + +char const HELP_TEXT[] = N_p("menu-analoginput", + "Show/hide settings \t\t%1$s\n" + "Decrease value \t\t%2$s\n" + "Increase value \t\t%3$s\n" + "Restore default value \t\t%4$s\n" + "Previous device \t\t%5$s\n" + "Next device \t\t%6$s\n" + "Return to previous menu \t\t%7$s"); + +} // anonymous namespace + + inline menu_analog::item_data::item_data(ioport_field &f, int t) noexcept : field(f) , type(t) @@ -63,7 +79,7 @@ menu_analog::menu_analog(mame_ui_manager &mui, render_container &container) , m_hide_menu(false) { set_process_flags(PROCESS_LR_REPEAT); - set_heading(_("Analog Input Adjustments")); + set_heading(_("menu-analoginput", "Analog Input Adjustments")); } @@ -102,7 +118,7 @@ void menu_analog::custom_render(void *selectedref, float top, float bottom, floa if (m_hide_menu) { if (m_prompt.empty()) - m_prompt = util::string_format(_("Press %s to show menu"), ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY)); + m_prompt = util::string_format(_("menu-analoginput", "Press %s to show settings"), ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY)); draw_text_box( &m_prompt, &m_prompt + 1, boxleft, boxright, y - top, y - top + line_height() + (tb_border() * 2.0f), @@ -221,6 +237,22 @@ void menu_analog::handle(event const *ev) m_hide_menu = !m_hide_menu; set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0)); } + else if (IPT_UI_HELP == ev->iptkey) + { + stack_push<menu_fixed_textbox>( + ui(), + container(), + _("menu-analoginput", "Analog Input Adjustments Help"), + util::string_format( + _(HELP_TEXT), + ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY), + ui().get_general_input_setting(IPT_UI_LEFT), + ui().get_general_input_setting(IPT_UI_RIGHT), + ui().get_general_input_setting(IPT_UI_CLEAR), + ui().get_general_input_setting(IPT_UI_PREV_GROUP), + ui().get_general_input_setting(IPT_UI_NEXT_GROUP), + ui().get_general_input_setting(IPT_UI_BACK))); + } else if (m_hide_menu) { switch (ev->iptkey) @@ -386,22 +418,22 @@ void menu_analog::populate() { default: case ANALOG_ITEM_KEYSPEED: - text = string_format(_("%1$s Increment/Decrement Speed"), field->name()); + text = string_format(_("menu-analoginput", "%1$s Increment/Decrement Speed"), field->name()); data.cur = settings.delta; break; case ANALOG_ITEM_CENTERSPEED: - text = string_format(_("%1$s Auto-centering Speed"), field->name()); + text = string_format(_("menu-analoginput", "%1$s Auto-centering Speed"), field->name()); data.cur = settings.centerdelta; break; case ANALOG_ITEM_REVERSE: - text = string_format(_("%1$s Reverse"), field->name()); + text = string_format(_("menu-analoginput", "%1$s Reverse"), field->name()); data.cur = settings.reverse; break; case ANALOG_ITEM_SENSITIVITY: - text = string_format(_("%1$s Sensitivity"), field->name()); + text = string_format(_("menu-analoginput", "%1$s Sensitivity"), field->name()); data.cur = settings.sensitivity; break; } @@ -416,7 +448,7 @@ void menu_analog::populate() // display a message if there are toggle inputs enabled if (!prev_owner) - item_append(_("[no analog inputs are enabled]"), FLAG_DISABLE, nullptr); + item_append(_("menu-analoginput", "[no analog inputs are enabled]"), FLAG_DISABLE, nullptr); item_append(menu_item_type::SEPARATOR); diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp index 61a20ae8bc8..07f55510ec8 100644 --- a/src/frontend/mame/ui/auditmenu.cpp +++ b/src/frontend/mame/ui/auditmenu.cpp @@ -127,7 +127,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float util::string_format( _("Cancel audit?\n\nPress %1$s to cancel\nPress %2$s to continue"), ui().get_general_input_setting(IPT_UI_SELECT), - ui().get_general_input_setting(IPT_UI_CANCEL)), + ui().get_general_input_setting(IPT_UI_BACK)), text_layout::text_justify::CENTER, 0.5F, 0.5F, UI_RED_COLOR); @@ -136,7 +136,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float } -bool menu_audit::custom_ui_cancel() +bool menu_audit::custom_ui_back() { return m_phase != phase::CONFIRMATION; } @@ -162,7 +162,7 @@ void menu_audit::handle(event const *ev) set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT); m_phase = phase::AUDIT; m_fast = ITEMREF_START_FAST == ev->itemref; - m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_CANCEL)); + m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_BACK)); m_future.resize(std::thread::hardware_concurrency()); for (auto &future : m_future) future = std::async(std::launch::async, [this] () { return do_audit(); }); @@ -185,7 +185,7 @@ void menu_audit::handle(event const *ev) } stack_pop(); } - else if (machine().ui_input().pressed(IPT_UI_CANCEL)) + else if (machine().ui_input().pressed(IPT_UI_BACK)) { if (phase::AUDIT == m_phase) m_phase = phase::CANCELLATION; diff --git a/src/frontend/mame/ui/auditmenu.h b/src/frontend/mame/ui/auditmenu.h index 040316edb5b..f0a37f09fba 100644 --- a/src/frontend/mame/ui/auditmenu.h +++ b/src/frontend/mame/ui/auditmenu.h @@ -31,7 +31,7 @@ public: protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - virtual bool custom_ui_cancel() override; + virtual bool custom_ui_back() override; private: enum class phase { CONFIRMATION, AUDIT, CANCELLATION }; diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp index ffeae2fff38..7d6030ce669 100644 --- a/src/frontend/mame/ui/confswitch.cpp +++ b/src/frontend/mame/ui/confswitch.cpp @@ -190,17 +190,6 @@ void menu_confswitch::handle(event const *ev) switch (ev->iptkey) { - // if selected, reset to default value - case IPT_UI_SELECT: - { - ioport_field::user_settings settings; - field.get_user_settings(settings); - settings.value = field.defvalue(); - field.set_user_settings(settings); - } - changed = true; - break; - // left goes to previous setting case IPT_UI_LEFT: field.select_previous_setting(); @@ -208,11 +197,26 @@ void menu_confswitch::handle(event const *ev) break; // right goes to next setting + case IPT_UI_SELECT: case IPT_UI_RIGHT: field.select_next_setting(); changed = true; break; + // if cleared, reset to default value + case IPT_UI_CLEAR: + { + ioport_field::user_settings settings; + field.get_user_settings(settings); + if (field.defvalue() != settings.value) + { + settings.value = field.defvalue(); + field.set_user_settings(settings); + changed = true; + } + } + break; + // trick to get previous group - depend on headings having null reference case IPT_UI_PREV_GROUP: { diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp index 2f77e98433c..a4000dc68b7 100644 --- a/src/frontend/mame/ui/dirmenu.cpp +++ b/src/frontend/mame/ui/dirmenu.cpp @@ -168,7 +168,7 @@ protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - virtual bool custom_ui_cancel() override { return !m_search.empty(); } + virtual bool custom_ui_back() override { return !m_search.empty(); } private: virtual void populate() override; diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp index 341c19545ba..cf55499ab00 100644 --- a/src/frontend/mame/ui/filecreate.cpp +++ b/src/frontend/mame/ui/filecreate.cpp @@ -117,7 +117,7 @@ menu_file_create::menu_file_create(mame_ui_manager &mui, render_container &conta , m_current_format(nullptr) { m_image = image; - m_ok = true; + m_ok = false; m_filename.reserve(1024); m_filename = core_filename_extract_base(current_file); @@ -158,13 +158,22 @@ void menu_file_create::custom_render(void *selectedref, float top, float bottom, //------------------------------------------------- +// custom_ui_back - override back handling +//------------------------------------------------- + +bool menu_file_create::custom_ui_back() +{ + return (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty(); +} + + +//------------------------------------------------- // populate - populates the file creator menu //------------------------------------------------- void menu_file_create::populate() { std::string buffer; - const image_device_format *format; const std::string *new_image_name; // append the "New Image Name" item @@ -180,9 +189,10 @@ void menu_file_create::populate() item_append(_("New Image Name:"), *new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); // do we support multiple formats? - if (ENABLE_FORMATS) format = m_image->formatlist().front().get(); - if (ENABLE_FORMATS && (format != nullptr)) + image_device_format const *const format = ENABLE_FORMATS ? m_image->formatlist().front().get() : nullptr; + if (format) { + // FIXME: is this in the right order? It reassigns m_current_format after reading it. item_append(_("Image Format:"), m_current_format->description(), 0, ITEMREF_FORMAT); m_current_format = format; } @@ -212,31 +222,38 @@ void menu_file_create::handle(event const *ev) if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1) { m_current_file = m_filename; + m_ok = true; stack_pop(); } else + { ui().popup_time(1, "%s", _("Please enter a file extension too")); + } } break; case IPT_UI_PASTE: - if (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME) + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) { if (paste_text(m_filename, &osd_is_valid_filename_char)) - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_filename + "_"); } break; case IPT_SPECIAL: - if (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME) + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) { if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char)) - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_filename + "_"); } break; case IPT_UI_CANCEL: - m_ok = false; + if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty()) + { + m_filename.clear(); + ev->item->set_subtext("_"); + } break; } } diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h index 629bd24f3ec..c4ef529168b 100644 --- a/src/frontend/mame/ui/filecreate.h +++ b/src/frontend/mame/ui/filecreate.h @@ -49,6 +49,7 @@ public: protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; + virtual bool custom_ui_back() override; private: virtual void populate() override; diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h index 71b2b17e3ad..f8968f798c9 100644 --- a/src/frontend/mame/ui/filesel.h +++ b/src/frontend/mame/ui/filesel.h @@ -46,7 +46,7 @@ public: protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - virtual bool custom_ui_cancel() override { return !m_filename.empty(); } + virtual bool custom_ui_back() override { return !m_filename.empty(); } virtual bool custom_mouse_down() override; private: diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp index 387d3db7423..4fa6ffab25b 100644 --- a/src/frontend/mame/ui/inputmap.cpp +++ b/src/frontend/mame/ui/inputmap.cpp @@ -394,22 +394,12 @@ void menu_input::handle(event const *ev) if (machine().ui_input().pressed(IPT_UI_CANCEL)) { - // if UI_CANCEL is pressed, abort + // if UI_CANCEL is pressed, abort and abandon changes pollingitem = nullptr; set_process_flags(PROCESS_LR_ALWAYS); - if (!seq_poll->modified() || modified_ticks == osd_ticks()) - { - // cancelled immediately - toggle between default and none - record_next = false; - toggle_none_default(item->seq, starting_seq, *item->defseq); - seqchangeditem = item; - } - else - { - // entered something before cancelling - abandon change - invalidate = true; - } + invalidate = true; seq_poll.reset(); + machine().ui_input().reset(); } else if (seq_poll->poll()) // poll again; if finished, update the sequence { @@ -429,6 +419,7 @@ void menu_input::handle(event const *ev) erroritem = item; } seq_poll.reset(); + machine().ui_input().reset(); } } else if (ev && ev->itemref) diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp index 69e75563985..1f00a882a9a 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -950,7 +950,7 @@ void menu::handle_events(uint32_t flags, event &ev) ev.iptkey = IPT_UI_SELECT; if (is_last_selected() && m_needs_prev_menu_item) { - ev.iptkey = IPT_UI_CANCEL; + ev.iptkey = IPT_UI_BACK; stack_pop(); if (is_special_main_menu()) machine().schedule_exit(); @@ -1029,7 +1029,7 @@ void menu::handle_keys(uint32_t flags, int &iptkey) { if (is_last_selected() && m_needs_prev_menu_item) { - iptkey = IPT_UI_CANCEL; + iptkey = IPT_UI_BACK; stack_pop(); if (is_special_main_menu()) machine().schedule_exit(); @@ -1038,7 +1038,7 @@ void menu::handle_keys(uint32_t flags, int &iptkey) } // UI configure hides the menus - if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_CONFIGURE, 0) && !m_global_state.stack_has_special_main_menu()) + if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_MENU, 0) && !m_global_state.stack_has_special_main_menu()) { if (is_one_shot()) stack_pop(); @@ -1051,10 +1051,10 @@ void menu::handle_keys(uint32_t flags, int &iptkey) if (flags & PROCESS_ONLYCHAR) return; - // hitting cancel also pops the stack - if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0)) + // hitting back also pops the stack + if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0)) { - if (!custom_ui_cancel()) + if (!custom_ui_back()) { stack_pop(); if (is_special_main_menu()) diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h index 4126fa66cb5..16223ebebd8 100644 --- a/src/frontend/mame/ui/menu.h +++ b/src/frontend/mame/ui/menu.h @@ -350,7 +350,7 @@ protected: void set_process_flags(uint32_t flags) { m_process_flags = flags; } virtual void handle_events(uint32_t flags, event &ev); virtual void handle_keys(uint32_t flags, int &iptkey); - virtual bool custom_ui_cancel() { return false; } + virtual bool custom_ui_back() { return false; } virtual bool custom_mouse_down() { return false; } virtual bool custom_mouse_scroll(int lines) { return false; } diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp index 3ad7a2ec2c3..bbf3c447087 100644 --- a/src/frontend/mame/ui/pluginopt.cpp +++ b/src/frontend/mame/ui/pluginopt.cpp @@ -103,6 +103,9 @@ void menu_plugin_opt::handle(event const *ev) case IPT_UI_CLEAR: key = "clear"; break; + case IPT_UI_BACK: + key = "back"; + break; case IPT_UI_CANCEL: key = "cancel"; break; @@ -120,7 +123,7 @@ void menu_plugin_opt::handle(event const *ev) set_selection(reinterpret_cast<void *>(uintptr_t(*result.second))); if (result.first) reset(reset_options::REMEMBER_REF); - else if (ev && (ev->iptkey == IPT_UI_CANCEL)) + else if (ev && (ev->iptkey == IPT_UI_BACK)) stack_pop(); } } diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h index 3779cf130c2..1e947a9ccd3 100644 --- a/src/frontend/mame/ui/pluginopt.h +++ b/src/frontend/mame/ui/pluginopt.h @@ -45,7 +45,7 @@ public: virtual ~menu_plugin_opt(); protected: - virtual bool custom_ui_cancel() override { return true; } + virtual bool custom_ui_back() override { return true; } private: virtual void populate() override; diff --git a/src/frontend/mame/ui/quitmenu.cpp b/src/frontend/mame/ui/quitmenu.cpp index 29f12143831..cd1fb4ac59b 100644 --- a/src/frontend/mame/ui/quitmenu.cpp +++ b/src/frontend/mame/ui/quitmenu.cpp @@ -38,7 +38,7 @@ void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom "Press %1$s to quit\n" "Press %2$s to return to emulation"), ui().get_general_input_setting(IPT_UI_SELECT), - ui().get_general_input_setting(IPT_UI_CANCEL)), + ui().get_general_input_setting(IPT_UI_BACK)), text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR); @@ -54,7 +54,7 @@ void menu_confirm_quit::handle(event const *ev) { if (machine().ui_input().pressed(IPT_UI_SELECT)) machine().schedule_exit(); - else if (machine().ui_input().pressed(IPT_UI_CANCEL)) + else if (machine().ui_input().pressed(IPT_UI_BACK)) stack_pop(); } diff --git a/src/frontend/mame/ui/selector.h b/src/frontend/mame/ui/selector.h index 8d504a42e2d..07528364f4d 100644 --- a/src/frontend/mame/ui/selector.h +++ b/src/frontend/mame/ui/selector.h @@ -40,7 +40,7 @@ public: protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - virtual bool custom_ui_cancel() override { return !m_search.empty(); } + virtual bool custom_ui_back() override { return !m_search.empty(); } private: enum { VISIBLE_SEARCH_ITEMS = 200 }; diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index f24eb7b3581..1a0789bc394 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -1450,24 +1450,34 @@ void menu_select_launch::handle_keys(u32 flags, int &iptkey) return; } - if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0)) + if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0)) { if (m_ui_error) { // dismiss error + return; } - else if (!m_search.empty()) + else if (!is_special_main_menu() && m_search.empty()) + { + // pop the stack if this isn't the root session menu + stack_pop(); + return; + } + } + + if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0)) + { + if (!m_search.empty()) { // escape pressed with non-empty search text clears it m_search.clear(); reset(reset_options::REMEMBER_REF); } - else + else if (is_special_main_menu()) { - // otherwise pop the stack + // this is the root session menu, exit stack_pop(); - if (is_special_main_menu()) - machine().schedule_exit(); + machine().schedule_exit(); } return; } @@ -1779,7 +1789,7 @@ void menu_select_launch::handle_events(u32 flags, event &ev) } else if (hover() == HOVER_BACKTRACK) { - ev.iptkey = IPT_UI_CANCEL; + ev.iptkey = IPT_UI_BACK; stack_pop(); if (is_special_main_menu()) machine().schedule_exit(); diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp index 9fd0b5bb177..2c1cb28e29a 100644 --- a/src/frontend/mame/ui/simpleselgame.cpp +++ b/src/frontend/mame/ui/simpleselgame.cpp @@ -124,7 +124,7 @@ void simple_menu_select_game::handle(event const *ev) else { // handle selections - switch(ev->iptkey) + switch (ev->iptkey) { case IPT_UI_SELECT: inkey_select(*ev); diff --git a/src/frontend/mame/ui/simpleselgame.h b/src/frontend/mame/ui/simpleselgame.h index 4f1effa4305..b1f4c1946e3 100644 --- a/src/frontend/mame/ui/simpleselgame.h +++ b/src/frontend/mame/ui/simpleselgame.h @@ -31,7 +31,7 @@ public: protected: virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - virtual bool custom_ui_cancel() override { return !m_search.empty(); } + virtual bool custom_ui_back() override { return !m_search.empty(); } private: enum { VISIBLE_GAMES_IN_LIST = 15 }; diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp index e162ebeee1a..db1dbbe7b66 100644 --- a/src/frontend/mame/ui/sliders.cpp +++ b/src/frontend/mame/ui/sliders.cpp @@ -99,7 +99,6 @@ void menu_sliders::handle(event const *ev) break; // restore default - case IPT_UI_SELECT: case IPT_UI_CLEAR: increment = slider->defval - curvalue; break; diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index 49412c8a244..a7795c0347b 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -262,7 +262,7 @@ void menu_load_save_state_base::handle(event const *ev) _("Delete saved state %1$s?\nPress %2$s to delete\nPress %3$s to cancel"), m_confirm_delete->visible_name(), ui().get_general_input_setting(IPT_UI_SELECT), - ui().get_general_input_setting(IPT_UI_CANCEL)); + ui().get_general_input_setting(IPT_UI_BACK)); } } else if (!m_confirm_delete) @@ -396,7 +396,7 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey) m_keys_released = false; reset(reset_options::REMEMBER_POSITION); } - else if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0)) + else if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0)) { // don't delete it - dismiss the prompt m_switch_poller.reset(); diff --git a/src/frontend/mame/ui/swlist.h b/src/frontend/mame/ui/swlist.h index ce50ad2cfae..ab913373115 100644 --- a/src/frontend/mame/ui/swlist.h +++ b/src/frontend/mame/ui/swlist.h @@ -65,7 +65,7 @@ public: virtual ~menu_software_list() override; protected: - virtual bool custom_ui_cancel() override { return !m_search.empty(); } + virtual bool custom_ui_back() override { return !m_search.empty(); } private: struct entry_info diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 6789686cac7..8f04ae7b980 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -441,7 +441,7 @@ void mame_ui_manager::display_startup_screens(bool first_time) machine().schedule_exit(); return UI_HANDLER_CANCEL; } - else if (machine().ui_input().pressed(IPT_UI_CONFIGURE)) + else if (machine().ui_input().pressed(IPT_UI_MENU)) { config_menu = true; return UI_HANDLER_CANCEL; @@ -1301,7 +1301,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container) } // turn on menus if requested - if (machine().ui_input().pressed(IPT_UI_CONFIGURE)) + if (machine().ui_input().pressed(IPT_UI_MENU)) { show_menu(); return 0; diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp index 59d3ffbc53f..2fcc0949484 100644 --- a/src/frontend/mame/ui/viewgfx.cpp +++ b/src/frontend/mame/ui/viewgfx.cpp @@ -527,7 +527,7 @@ private: } // cancel or graphics viewer dismisses the viewer - if (input.pressed(IPT_UI_CANCEL) || input.pressed(IPT_UI_SHOW_GFX)) + if (input.pressed(IPT_UI_BACK) || input.pressed(IPT_UI_SHOW_GFX)) return cancel(uistate); return uistate; diff --git a/src/osd/modules/input/assignmenthelper.cpp b/src/osd/modules/input/assignmenthelper.cpp new file mode 100644 index 00000000000..c044d4b7aa7 --- /dev/null +++ b/src/osd/modules/input/assignmenthelper.cpp @@ -0,0 +1,592 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// assignmenthelper.cpp - input assignment setup helper +// +//============================================================ + +#include "assignmenthelper.h" + +#include "interface/inputseq.h" + +#include "inpttype.h" + + +namespace osd { + +bool joystick_assignment_helper::add_assignment( + input_device::assignment_vector &assignments, + ioport_type fieldtype, + input_seq_type seqtype, + input_item_class itemclass, + input_item_modifier modifier, + std::initializer_list<input_item_id> items) +{ + for (input_item_id item : items) + { + if (ITEM_ID_INVALID != item) + { + assignments.emplace_back( + fieldtype, + seqtype, + input_seq(input_code(DEVICE_CLASS_JOYSTICK, 0, itemclass, modifier, item))); + return true; + } + } + return false; +} + + +bool joystick_assignment_helper::add_button_assignment( + input_device::assignment_vector &assignments, + ioport_type field_type, + std::initializer_list<input_item_id> items) +{ + return add_assignment( + assignments, + field_type, + SEQ_TYPE_STANDARD, + ITEM_CLASS_SWITCH, + ITEM_MODIFIER_NONE, + items); +} + + +bool joystick_assignment_helper::add_button_pair_assignment( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id button1, + input_item_id button2) +{ + if ((ITEM_ID_INVALID == button1) || (ITEM_ID_INVALID == button2)) + return false; + + assignments.emplace_back( + field1, + SEQ_TYPE_STANDARD, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button1)); + assignments.emplace_back( + field2, + SEQ_TYPE_STANDARD, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button2)); + return true; +} + + +bool joystick_assignment_helper::add_axis_inc_dec_assignment( + input_device::assignment_vector &assignments, + ioport_type field_type, + input_item_id button_dec, + input_item_id button_inc) +{ + if ((ITEM_ID_INVALID == button_dec) || (ITEM_ID_INVALID == button_inc)) + return false; + + assignments.emplace_back( + field_type, + SEQ_TYPE_DECREMENT, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button_dec)); + assignments.emplace_back( + field_type, + SEQ_TYPE_INCREMENT, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button_inc)); + return true; +} + + +bool joystick_assignment_helper::add_axis_pair_assignment( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id axis) +{ + if (ITEM_ID_INVALID == axis) + return false; + + assignments.emplace_back( + field1, + SEQ_TYPE_STANDARD, + make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == axis) ? ITEM_MODIFIER_LEFT : (ITEM_ID_YAXIS == axis) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG, + axis)); + assignments.emplace_back( + field2, + SEQ_TYPE_STANDARD, + make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == axis) ? ITEM_MODIFIER_RIGHT : (ITEM_ID_YAXIS == axis) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS, + axis)); + return true; +} + + +bool joystick_assignment_helper::consume_button_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &button1, + input_item_id &button2) +{ + if (!add_button_pair_assignment(assignments, field1, field2, button1, button2)) + return false; + + button1 = ITEM_ID_INVALID; + button2 = ITEM_ID_INVALID; + return true; +} + + +bool joystick_assignment_helper::consume_trigger_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &axis1, + input_item_id &axis2) +{ + if ((ITEM_ID_INVALID == axis1) || (ITEM_ID_INVALID == axis2)) + return false; + + assignments.emplace_back( + field1, + SEQ_TYPE_STANDARD, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axis1)); + assignments.emplace_back( + field2, + SEQ_TYPE_STANDARD, + make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axis2)); + axis1 = ITEM_ID_INVALID; + axis2 = ITEM_ID_INVALID; + return true; +} + + +bool joystick_assignment_helper::consume_axis_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &axis) +{ + if (!add_axis_pair_assignment(assignments, field1, field2, axis)) + return false; + + axis = ITEM_ID_INVALID; + return true; +} + + +void joystick_assignment_helper::add_directional_assignments( + input_device::assignment_vector &assignments, + input_item_id xaxis, + input_item_id yaxis, + input_item_id leftswitch, + input_item_id rightswitch, + input_item_id upswitch, + input_item_id downswitch) +{ + // see if we have complementary pairs of directional switches + bool const hswitches = (ITEM_ID_INVALID != leftswitch) && (ITEM_ID_INVALID != rightswitch); + bool const vswitches = (ITEM_ID_INVALID != upswitch) && (ITEM_ID_INVALID != downswitch); + + // use X axis if present + if (ITEM_ID_INVALID != xaxis) + { + // use this for horizontal axis movement + input_seq const xseq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, xaxis)); + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_STANDARD, xseq); + + // use it for the main left/right control, too + input_seq leftseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_XAXIS == xaxis) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG, xaxis)); + input_seq rightseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_XAXIS == xaxis) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS, xaxis)); + if (ITEM_ID_INVALID != leftswitch) + { + leftseq += input_seq::or_code; + leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch); + } + if (ITEM_ID_INVALID != rightswitch) + { + rightseq += input_seq::or_code; + rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch); + } + assignments.emplace_back(IPT_JOYSTICK_LEFT, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_JOYSTICK_RIGHT, SEQ_TYPE_STANDARD, rightseq); + + // use for vertical navigation if there's no Y axis, or horizontal otherwise + if (ITEM_ID_INVALID != yaxis) + { + // if left/right are both present but not both up/down, they'll be taken for vertical navigation + if (hswitches && !vswitches) + { + leftseq.backspace(); + if (ITEM_ID_INVALID != upswitch) + leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch); + else + leftseq.backspace(); + + rightseq.backspace(); + if (ITEM_ID_INVALID != downswitch) + rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch); + else + rightseq.backspace(); + } + assignments.emplace_back(IPT_UI_LEFT, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_UI_RIGHT, SEQ_TYPE_STANDARD, rightseq); + } + else + { + // prefer D-pad up/down for vertical navigation if present + if (!hswitches || vswitches) + { + while (leftseq.length() > 1) + leftseq.backspace(); + if (ITEM_ID_INVALID != upswitch) + { + leftseq += input_seq::or_code; + leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch); + } + + while (rightseq.length() > 1) + rightseq.backspace(); + if (ITEM_ID_INVALID != downswitch) + { + rightseq += input_seq::or_code; + rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch); + } + } + assignments.emplace_back(IPT_UI_UP, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_UI_DOWN, SEQ_TYPE_STANDARD, rightseq); + } + } + else + { + // without a primary analog X axis, we still want D-pad left/right controls if possible + add_button_assignment(assignments, IPT_JOYSTICK_LEFT, { leftswitch }); + add_button_assignment(assignments, IPT_JOYSTICK_RIGHT, { rightswitch }); + + // vertical navigation gets first pick on directional controls + add_button_assignment(assignments, IPT_UI_LEFT, { (hswitches && !vswitches) ? upswitch : leftswitch }); + add_button_assignment(assignments, IPT_UI_RIGHT, { (hswitches && !vswitches) ? downswitch : rightswitch }); + } + + // use Y axis if present + if (ITEM_ID_INVALID != yaxis) + { + // use this for vertical axis movement + input_seq const yseq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, yaxis)); + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_STANDARD, yseq); + + // use it for the main up/down control, too + input_seq upseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_YAXIS == yaxis) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG, yaxis)); + input_seq downseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_YAXIS == yaxis) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS, yaxis)); + if (ITEM_ID_INVALID != upswitch) + { + upseq += input_seq::or_code; + upseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch); + } + if (ITEM_ID_INVALID != downswitch) + { + downseq += input_seq::or_code; + downseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch); + } + assignments.emplace_back(IPT_JOYSTICK_UP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_JOYSTICK_DOWN, SEQ_TYPE_STANDARD, downseq); + + // if available, this is used for vertical navigation + if (hswitches && !vswitches) + { + if (upseq.length() > 1) + upseq.backspace(); + else + upseq += input_seq::or_code; + upseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch); + + if (downseq.length() > 1) + downseq.backspace(); + else + downseq += input_seq::or_code; + downseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch); + } + assignments.emplace_back(IPT_UI_UP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_UI_DOWN, SEQ_TYPE_STANDARD, downseq); + } + else + { + // without a primary analog Y axis, we still want D-pad up/down controls if possible + add_button_assignment(assignments, IPT_JOYSTICK_UP, { upswitch }); + add_button_assignment(assignments, IPT_JOYSTICK_DOWN, { downswitch }); + + // vertical navigation may be assigned to X axis if Y axis is not present + bool const dpadflip = (ITEM_ID_INVALID != xaxis) == (!hswitches || vswitches); + add_button_assignment( + assignments, + (ITEM_ID_INVALID != xaxis) ? IPT_UI_LEFT : IPT_UI_UP, + { dpadflip ? leftswitch : upswitch }); + add_button_assignment( + assignments, + (ITEM_ID_INVALID != xaxis) ? IPT_UI_RIGHT : IPT_UI_DOWN, + { dpadflip ? rightswitch : downswitch }); + } + + // if we're missing either primary axis, fall back to D-pad for analog increment/decrement + if ((ITEM_ID_INVALID == xaxis) || (ITEM_ID_INVALID == yaxis)) + { + if (ITEM_ID_INVALID != leftswitch) + { + input_seq const leftseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch)); + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_DECREMENT, leftseq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_DECREMENT, leftseq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_DECREMENT, leftseq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_DECREMENT, leftseq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_DECREMENT, leftseq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_DECREMENT, leftseq); + } + if (ITEM_ID_INVALID != rightswitch) + { + input_seq const rightseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch)); + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_INCREMENT, rightseq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_INCREMENT, rightseq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_INCREMENT, rightseq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_INCREMENT, rightseq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_INCREMENT, rightseq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_INCREMENT, rightseq); + } + if (ITEM_ID_INVALID != upswitch) + { + input_seq const upseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch)); + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_DECREMENT, upseq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_DECREMENT, upseq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_DECREMENT, upseq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_DECREMENT, upseq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_DECREMENT, upseq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_DECREMENT, upseq); + } + if (ITEM_ID_INVALID != downswitch) + { + input_seq const downseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch)); + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_INCREMENT, downseq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_INCREMENT, downseq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_INCREMENT, downseq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_INCREMENT, downseq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_INCREMENT, downseq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_INCREMENT, downseq); + } + } +} + + +void joystick_assignment_helper::add_twin_stick_assignments( + input_device::assignment_vector &assignments, + input_item_id leftx, + input_item_id lefty, + input_item_id rightx, + input_item_id righty, + input_item_id leftleft, + input_item_id leftright, + input_item_id leftup, + input_item_id leftdown, + input_item_id rightleft, + input_item_id rightright, + input_item_id rightup, + input_item_id rightdown) +{ + // we'll add these at the end if they aren't empty + input_seq leftleftseq, leftrightseq, leftupseq, leftdownseq; + input_seq rightleftseq, rightrightseq, rightupseq, rightdownseq; + + // only use axes if there are at least two axes in the same orientation + bool const useaxes = + ((ITEM_ID_INVALID != leftx) && (ITEM_ID_INVALID != rightx)) || + ((ITEM_ID_INVALID != lefty) && (ITEM_ID_INVALID != righty)); + if (useaxes) + { + // left stick + if (ITEM_ID_INVALID != leftx) + { + leftleftseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == leftx) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG, + leftx); + leftrightseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == leftx) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS, + leftx); + } + if (ITEM_ID_INVALID != lefty) + { + leftupseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_YAXIS == lefty) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG, + lefty); + leftdownseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_YAXIS == lefty) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS, + lefty); + } + + // right stick + if (ITEM_ID_INVALID != rightx) + { + rightleftseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == rightx) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG, + rightx); + rightrightseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_XAXIS == rightx) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS, + rightx); + } + if (ITEM_ID_INVALID != righty) + { + rightupseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_YAXIS == righty) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG, + righty); + rightdownseq += make_code( + ITEM_CLASS_SWITCH, + (ITEM_ID_YAXIS == righty) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS, + righty); + } + } + + // only use switches if we have at least one pair of matching opposing directions + bool const lefth = (ITEM_ID_INVALID != leftleft) && (ITEM_ID_INVALID != leftright); + bool const leftv = (ITEM_ID_INVALID != leftup) && (ITEM_ID_INVALID != leftdown); + bool const righth = (ITEM_ID_INVALID != rightleft) && (ITEM_ID_INVALID != rightright); + bool const rightv = (ITEM_ID_INVALID != rightup) && (ITEM_ID_INVALID != rightdown); + if ((lefth && righth) || (leftv && rightv)) + { + // left stick + if (ITEM_ID_INVALID != leftleft) + { + if (!leftleftseq.empty()) + leftleftseq += input_seq::or_code; + leftleftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftleft); + } + if (ITEM_ID_INVALID != leftright) + { + if (!leftrightseq.empty()) + leftrightseq += input_seq::or_code; + leftrightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftright); + } + if (ITEM_ID_INVALID != leftup) + { + if (!leftupseq.empty()) + leftupseq += input_seq::or_code; + leftupseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftup); + } + if (ITEM_ID_INVALID != leftdown) + { + if (!leftdownseq.empty()) + leftdownseq += input_seq::or_code; + leftdownseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftdown); + } + + // right stick + if (ITEM_ID_INVALID != rightleft) + { + if (!rightleftseq.empty()) + rightleftseq += input_seq::or_code; + rightleftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightleft); + } + if (ITEM_ID_INVALID != rightright) + { + if (!rightrightseq.empty()) + rightrightseq += input_seq::or_code; + rightrightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightright); + } + if (ITEM_ID_INVALID != rightup) + { + if (!rightupseq.empty()) + rightupseq += input_seq::or_code; + rightupseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightup); + } + if (ITEM_ID_INVALID != rightdown) + { + if (!rightdownseq.empty()) + rightdownseq += input_seq::or_code; + rightdownseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightdown); + } + } + + // now add collected assignments + if (!leftleftseq.empty()) + assignments.emplace_back(IPT_JOYSTICKLEFT_LEFT, SEQ_TYPE_STANDARD, leftleftseq); + if (!leftrightseq.empty()) + assignments.emplace_back(IPT_JOYSTICKLEFT_RIGHT, SEQ_TYPE_STANDARD, leftrightseq); + if (!leftupseq.empty()) + assignments.emplace_back(IPT_JOYSTICKLEFT_UP, SEQ_TYPE_STANDARD, leftupseq); + if (!leftdownseq.empty()) + assignments.emplace_back(IPT_JOYSTICKLEFT_DOWN, SEQ_TYPE_STANDARD, leftdownseq); + if (!rightleftseq.empty()) + assignments.emplace_back(IPT_JOYSTICKRIGHT_LEFT, SEQ_TYPE_STANDARD, rightleftseq); + if (!rightrightseq.empty()) + assignments.emplace_back(IPT_JOYSTICKRIGHT_RIGHT, SEQ_TYPE_STANDARD, rightrightseq); + if (!rightupseq.empty()) + assignments.emplace_back(IPT_JOYSTICKRIGHT_UP, SEQ_TYPE_STANDARD, rightupseq); + if (!rightdownseq.empty()) + assignments.emplace_back(IPT_JOYSTICKRIGHT_DOWN, SEQ_TYPE_STANDARD, rightdownseq); +} + + +void joystick_assignment_helper::choose_primary_stick( + input_item_id (&stickaxes)[2][2], + input_item_id leftx, + input_item_id lefty, + input_item_id rightx, + input_item_id righty) +{ + if ((ITEM_ID_INVALID != leftx) && (ITEM_ID_INVALID != lefty)) + { + // left stick has both axes, make it primary + stickaxes[0][0] = leftx; + stickaxes[0][1] = lefty; + stickaxes[1][0] = rightx; + stickaxes[1][1] = righty; + } + else if ((ITEM_ID_INVALID != rightx) && (ITEM_ID_INVALID != righty)) + { + // right stick has both axes, make it primary + stickaxes[0][0] = rightx; + stickaxes[0][1] = righty; + stickaxes[1][0] = leftx; + stickaxes[1][1] = lefty; + } + else if (ITEM_ID_INVALID != leftx) + { + // degenerate case - left X and possibly right X or Y + stickaxes[0][0] = leftx; + stickaxes[0][1] = righty; + stickaxes[1][0] = rightx; + stickaxes[1][1] = ITEM_ID_INVALID; + } + else if ((ITEM_ID_INVALID != rightx) || (ITEM_ID_INVALID != lefty)) + { + // degenerate case - right X and possibly left Y, or one or two Y axes + stickaxes[0][0] = rightx; + stickaxes[0][1] = lefty; + stickaxes[1][0] = ITEM_ID_INVALID; + stickaxes[1][1] = righty; + } + else + { + // degenerate case - one Y axis at most + stickaxes[0][0] = ITEM_ID_INVALID; + stickaxes[0][1] = righty; + stickaxes[1][0] = ITEM_ID_INVALID; + stickaxes[1][1] = ITEM_ID_INVALID; + } +} + +} // namespace osd diff --git a/src/osd/modules/input/assignmenthelper.h b/src/osd/modules/input/assignmenthelper.h new file mode 100644 index 00000000000..ff5a9d34072 --- /dev/null +++ b/src/osd/modules/input/assignmenthelper.h @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// assignmenthelper.h - input assignment setup helper +// +//============================================================ +#ifndef MAME_OSD_INPUT_ASSIGNMENTHELPER_H +#define MAME_OSD_INPUT_ASSIGNMENTHELPER_H + +#pragma once + +#include "interface/inputcode.h" +#include "interface/inputdev.h" + +#include <initializer_list> + + +namespace osd { + +class joystick_assignment_helper +{ +protected: + static constexpr input_code make_code( + input_item_class itemclass, + input_item_modifier modifier, + input_item_id item) + { + return input_code(DEVICE_CLASS_JOYSTICK, 0, itemclass, modifier, item); + } + + static bool add_assignment( + input_device::assignment_vector &assignments, + ioport_type fieldtype, + input_seq_type seqtype, + input_item_class itemclass, + input_item_modifier modifier, + std::initializer_list<input_item_id> items); + + static bool add_button_assignment( + input_device::assignment_vector &assignments, + ioport_type field_type, + std::initializer_list<input_item_id> items); + + static bool add_button_pair_assignment( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id button1, + input_item_id button2); + + static bool add_axis_inc_dec_assignment( + input_device::assignment_vector &assignments, + ioport_type field_type, + input_item_id button_dec, + input_item_id button_inc); + + static bool add_axis_pair_assignment( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id axis); + + static bool consume_button_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &button1, + input_item_id &button2); + + static bool consume_trigger_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &axis1, + input_item_id &axis2); + + static bool consume_axis_pair( + input_device::assignment_vector &assignments, + ioport_type field1, + ioport_type field2, + input_item_id &axis); + + static void add_directional_assignments( + input_device::assignment_vector &assignments, + input_item_id xaxis, + input_item_id yaxis, + input_item_id leftswitch, + input_item_id rightswitch, + input_item_id upswitch, + input_item_id downswitch); + + static void add_twin_stick_assignments( + input_device::assignment_vector &assignments, + input_item_id leftx, + input_item_id lefty, + input_item_id rightx, + input_item_id righty, + input_item_id leftleft, + input_item_id leftright, + input_item_id leftup, + input_item_id leftdown, + input_item_id rightleft, + input_item_id rightright, + input_item_id rightup, + input_item_id rightdown); + + static void choose_primary_stick( + input_item_id (&stickaxes)[2][2], + input_item_id leftx, + input_item_id lefty, + input_item_id rightx, + input_item_id righty); +}; + +} // namespace osd + +#endif // MAME_OSD_INPUT_ASSIGNMENTHELPER_H diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index 2ac7c7458fd..8642f693d03 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -1,22 +1,108 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles, Brad Hughes +// copyright-holders:Aaron Giles, Brad Hughes, Vas Crabb //============================================================ // // input_dinput.cpp - Windows DirectInput support // //============================================================ +/* + +DirectInput joystick input is a bit of a mess. It gives eight axes +called X, Y, Z, Rx, Ry, Rz, slider 0 and slider 1. The driver can +assign arbitrary physical axes to these axes. Up to four hat switches +are supported, giving a direction in hundredths of degrees. In theory, +this supports dial-like controls with an arbitrary number of stops. In +practice, it just makes dealing with 8-way hat switches more complicated +and prevents contradictory inputs from being reported altogether. + +You may get a vague indication of the type of controller, and you can +obtain usage information for HID controllers. + +The Windows HID driver supposedly uses the following mappings: + +0x01 Generic Desktop 0x30 X X +0x01 Generic Desktop 0x31 Y Y +0x01 Generic Desktop 0x32 Z Z +0x01 Generic Desktop 0x33 Rx Rx +0x01 Generic Desktop 0x34 Ry Ry +0x01 Generic Desktop 0x35 Rz Rz +0x01 Generic Desktop 0x36 Slider Slider +0x01 Generic Desktop 0x37 Dial Slider +0x01 Generic Desktop 0x39 Hat Switch POV Hat +0x02 Simulation 0xBA Rudder Rz +0x02 Simulation 0xBB Throttle Slider +0x02 Simulation 0xC4 Accelerator Y +0x02 Simulation 0xC5 Brake Rz +0x02 Simulation 0xC8 Steering X + +Anything without an explicit mapping is treated as a button. + +The WinMM driver supposedly uses the following axis mappings: + +X X +Y Y +Z Slider +R Rz +U Slider +V Slider + +The actual mapping used by various controllers doesn't match what you +might expect from the HID mapping. + +Gamepads: + +Axis Logitech Xinput Switch +X Left X Left X Left X +Y Left Y Left Y Left Y +Z Right X Triggers +Rx Right X Right X +Ry Right Y Right Y +Rz Right Y + +Thrustmaster controllers: + +Axis HOTAS Side stick Throttle/Pedals Dual Throttles Triple Throttles Driving +X Aileron Aileron Mini Stick X Left Throttle Right Brake Steering +Y Elevator Elevator Mini stick Y Right Throttle Left Brake Brake +Z Throttle Throttle Flaps Rudder +Rx Right Brake Right Brake Right Brake Left Throttle +Ry Left Brake Left Brake Left Brake Centre Throttle +Rz Twist Rudder Rocker Air Brake Right Throttle Accelerator +Slider 0 Rocker Throttle Antenna Rudder Clutch +Slider 1 Rudder Rudder + +Logitech controllers: + +Axis Pro Wheels +X Steering +Y +Z +Rx Accelerator +Ry Brake +Rz Clutch +Slider 0 +Slider 1 + +MFG Crosswind pedals: + +X Left Brake +Y Right Brake +Rz Rudder + +*/ #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) -// emu -#include "emu.h" // put this here before Windows headers define interface as a macro - #include "input_dinput.h" +#include "interface/inputseq.h" #include "windows/winutil.h" +// emu +#include "inpttype.h" + // lib/util #include "util/corestr.h" @@ -26,6 +112,7 @@ #endif #include <algorithm> +#include <cmath> #include <iterator> #include <memory> @@ -44,8 +131,180 @@ BOOL CALLBACK device_enum_interface_callback(LPCDIDEVICEINSTANCE instance, LPVOI } +std::string guid_to_string(GUID const &guid) +{ + // size of a GUID string with dashes plus NUL terminator + char guid_string[37]; + snprintf( + guid_string, std::size(guid_string), + "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], + guid.Data4[3], guid.Data4[4], guid.Data4[5], + guid.Data4[6], guid.Data4[7]); + + return guid_string; +} + + + //============================================================ -// dinput_module - base directinput module +// dinput_keyboard_device - DirectInput keyboard device +//============================================================ + +class dinput_keyboard_device : public dinput_device +{ +public: + dinput_keyboard_device( + std::string &&name, + std::string &&id, + input_module &module, + Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, + DIDEVCAPS const &caps, + LPCDIDATAFORMAT format); + + virtual void poll() override; + virtual void reset() override; + virtual void configure(input_device &device) override; + +private: + std::mutex m_device_lock; + keyboard_state m_keyboard; +}; + +dinput_keyboard_device::dinput_keyboard_device( + std::string &&name, + std::string &&id, + input_module &module, + Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, + DIDEVCAPS const &caps, + LPCDIDATAFORMAT format) : + dinput_device(std::move(name), std::move(id), module, std::move(device), caps, format), + m_keyboard({ { 0 } }) +{ +} + +void dinput_keyboard_device::poll() +{ + // poll the DirectInput immediate state + std::lock_guard<std::mutex> scope_lock(m_device_lock); + poll_dinput(&m_keyboard.state); +} + +void dinput_keyboard_device::reset() +{ + memset(&m_keyboard.state, 0, sizeof(m_keyboard.state)); +} + +void dinput_keyboard_device::configure(input_device &device) +{ + // populate it + char defname[20]; + for (int keynum = 0; keynum < MAX_KEYS; keynum++) + { + input_item_id itemid = keyboard_trans_table::instance().map_di_scancode_to_itemid(keynum); + + // generate/fetch the name + snprintf(defname, std::size(defname), "Scan%03d", keynum); + + // add the item to the device + device.add_item( + item_name(keynum, defname, nullptr), + strmakeupper(defname), + itemid, + generic_button_get_state<uint8_t>, + &m_keyboard.state[keynum]); + } +} + + +//============================================================ +// dinput_mouse_device - DirectInput mouse device +//============================================================ + +class dinput_mouse_device : public dinput_device +{ +public: + dinput_mouse_device( + std::string &&name, + std::string &&id, + input_module &module, + Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, + DIDEVCAPS const &caps, + LPCDIDATAFORMAT format); + + void poll() override; + void reset() override; + virtual void configure(input_device &device) override; + +private: + mouse_state m_mouse; +}; + +dinput_mouse_device::dinput_mouse_device( + std::string &&name, + std::string &&id, + input_module &module, + Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, + DIDEVCAPS const &caps, + LPCDIDATAFORMAT format) : + dinput_device(std::move(name), std::move(id), module, std::move(device), caps, format), + m_mouse({0}) +{ + // cap the number of axes and buttons based on the format + m_caps.dwAxes = std::min(m_caps.dwAxes, DWORD(3)); + m_caps.dwButtons = std::min(m_caps.dwButtons, DWORD((m_format == &c_dfDIMouse) ? 4 : 8)); +} + +void dinput_mouse_device::poll() +{ + // poll + if (poll_dinput(&m_mouse) == DI_OK) + { + // scale the axis data + m_mouse.lX *= input_device::RELATIVE_PER_PIXEL; + m_mouse.lY *= input_device::RELATIVE_PER_PIXEL; + m_mouse.lZ *= input_device::RELATIVE_PER_PIXEL; + } +} + +void dinput_mouse_device::reset() +{ + memset(&m_mouse, 0, sizeof(m_mouse)); +} + +void dinput_mouse_device::configure(input_device &device) +{ + // populate the axes + for (int axisnum = 0; axisnum < m_caps.dwAxes; axisnum++) + { + // add to the mouse device and optionally to the gun device as well + device.add_item( + item_name(offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr), + std::string_view(), + input_item_id(ITEM_ID_XAXIS + axisnum), + generic_axis_get_state<LONG>, + &m_mouse.lX + axisnum); + } + + // populate the buttons + for (int butnum = 0; butnum < m_caps.dwButtons; butnum++) + { + auto offset = reinterpret_cast<uintptr_t>(&static_cast<DIMOUSESTATE *>(nullptr)->rgbButtons[butnum]); + + // add to the mouse device + device.add_item( + item_name(offset, default_button_name(butnum), nullptr), + std::string_view(), + input_item_id(ITEM_ID_BUTTON1 + butnum), + generic_button_get_state<BYTE>, + &m_mouse.rgbButtons[butnum]); + } +} + + +//============================================================ +// dinput_module - base DirectInput module //============================================================ class dinput_module : public input_module_impl<dinput_device, osd_common_t>, public device_enum_interface @@ -220,7 +479,7 @@ public: //============================================================ -// dinput_device - base directinput device +// dinput_device - base DirectInput device //============================================================ dinput_device::dinput_device( @@ -282,122 +541,6 @@ std::string dinput_device::item_name(int offset, std::string_view defstring, con //============================================================ -// dinput_keyboard_device - directinput keyboard device -//============================================================ - -dinput_keyboard_device::dinput_keyboard_device( - std::string &&name, - std::string &&id, - input_module &module, - Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, - DIDEVCAPS const &caps, - LPCDIDATAFORMAT format) : - dinput_device(std::move(name), std::move(id), module, std::move(device), caps, format), - m_keyboard({ { 0 } }) -{ -} - -void dinput_keyboard_device::poll() -{ - // poll the DirectInput immediate state - std::lock_guard<std::mutex> scope_lock(m_device_lock); - poll_dinput(&m_keyboard.state); -} - -void dinput_keyboard_device::reset() -{ - memset(&m_keyboard.state, 0, sizeof(m_keyboard.state)); -} - -void dinput_keyboard_device::configure(input_device &device) -{ - // populate it - char defname[20]; - for (int keynum = 0; keynum < MAX_KEYS; keynum++) - { - input_item_id itemid = keyboard_trans_table::instance().map_di_scancode_to_itemid(keynum); - - // generate/fetch the name - snprintf(defname, std::size(defname), "Scan%03d", keynum); - - // add the item to the device - device.add_item( - item_name(keynum, defname, nullptr), - strmakeupper(defname), - itemid, - generic_button_get_state<std::uint8_t>, - &m_keyboard.state[keynum]); - } -} - - -//============================================================ -// dinput_mouse_device - directinput mouse device -//============================================================ - -dinput_mouse_device::dinput_mouse_device( - std::string &&name, - std::string &&id, - input_module &module, - Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, - DIDEVCAPS const &caps, - LPCDIDATAFORMAT format) : - dinput_device(std::move(name), std::move(id), module, std::move(device), caps, format), - m_mouse({0}) -{ - // cap the number of axes and buttons based on the format - m_caps.dwAxes = std::min(m_caps.dwAxes, DWORD(3)); - m_caps.dwButtons = std::min(m_caps.dwButtons, DWORD((m_format == &c_dfDIMouse) ? 4 : 8)); -} - -void dinput_mouse_device::poll() -{ - // poll - if (poll_dinput(&m_mouse) == DI_OK) - { - // scale the axis data - m_mouse.lX *= input_device::RELATIVE_PER_PIXEL; - m_mouse.lY *= input_device::RELATIVE_PER_PIXEL; - m_mouse.lZ *= input_device::RELATIVE_PER_PIXEL; - } -} - -void dinput_mouse_device::reset() -{ - memset(&m_mouse, 0, sizeof(m_mouse)); -} - -void dinput_mouse_device::configure(input_device &device) -{ - // populate the axes - for (int axisnum = 0; axisnum < m_caps.dwAxes; axisnum++) - { - // add to the mouse device and optionally to the gun device as well - device.add_item( - item_name(offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr), - std::string_view(), - input_item_id(ITEM_ID_XAXIS + axisnum), - generic_axis_get_state<LONG>, - &m_mouse.lX + axisnum); - } - - // populate the buttons - for (int butnum = 0; butnum < m_caps.dwButtons; butnum++) - { - auto offset = reinterpret_cast<uintptr_t>(&static_cast<DIMOUSESTATE *>(nullptr)->rgbButtons[butnum]); - - // add to the mouse device - device.add_item( - item_name(offset, default_button_name(butnum), nullptr), - std::string_view(), - input_item_id(ITEM_ID_BUTTON1 + butnum), - generic_button_get_state<BYTE>, - &m_mouse.rgbButtons[butnum]); - } -} - - -//============================================================ // dinput_joystick_device - directinput joystick device //============================================================ @@ -431,28 +574,57 @@ void dinput_joystick_device::poll() // normalize axis values for (int axisnum = 0; axisnum < 8; axisnum++) { - LONG *const axis = &m_joystick.state.lX + axisnum; - *axis = normalize_absolute_axis(*axis, m_joystick.rangemin[axisnum], m_joystick.rangemax[axisnum]); + auto const range = m_joystick.rangemax[axisnum] - m_joystick.rangemin[axisnum]; + if (range) + { + // assumes output range is symmetrical + LONG *const axis = &m_joystick.state.lX + axisnum; + double const offset = *axis - m_joystick.rangemin[axisnum]; + double const scaled = offset * double(input_device::ABSOLUTE_MAX - input_device::ABSOLUTE_MIN) / double(range); + *axis = lround(std::clamp<double>(scaled + input_device::ABSOLUTE_MIN, input_device::ABSOLUTE_MIN, input_device::ABSOLUTE_MAX)); + } } } } void dinput_joystick_device::configure(input_device &device) { + input_device::assignment_vector assignments; HRESULT result; + // get device information - it gives clues about axis usage + DIDEVICEINSTANCE info; + info.dwSize = sizeof(info); + result = m_device->GetDeviceInfo(&info); + bool hid = false; + uint8_t type = DI8DEVTYPE_DEVICE; + uint8_t subtype = 0; + if (result == DI_OK) + { + hid = (info.dwDevType & DIDEVTYPE_HID) != 0; + type = info.dwDevType & 0x00ff; + subtype = (info.dwDevType >> 8) & 0x00ff; + osd_printf_verbose( + "DirectInput: Device type=0x%02X subtype=0x%02X HID=%u\n", + type, + subtype, + hid ? "yes" : "no"); + } + // turn off deadzone; we do our own calculations result = dinput_api_helper::set_dword_property(m_device, DIPROP_DEADZONE, 0, DIPH_DEVICE, 0); - if (result != DI_OK && result != DI_PROPNOEFFECT) + if ((result != DI_OK) && (result != DI_PROPNOEFFECT)) osd_printf_warning("DirectInput: Unable to reset deadzone for joystick %s.\n", name()); // turn off saturation; we do our own calculations result = dinput_api_helper::set_dword_property(m_device, DIPROP_SATURATION, 0, DIPH_DEVICE, 10000); - if (result != DI_OK && result != DI_PROPNOEFFECT) + if ((result != DI_OK) && (result != DI_PROPNOEFFECT)) osd_printf_warning("DirectInput: Unable to reset saturation for joystick %s.\n", name()); // populate the axes - for (uint32_t axisnum = 0, axiscount = 0; axiscount < m_caps.dwAxes && axisnum < 8; axisnum++) + input_item_id axisitems[8]; + std::fill(std::begin(axisitems), std::end(axisitems), ITEM_ID_INVALID); + for (uint32_t axisnum = 0, axiscount = 0; (axiscount < m_caps.dwAxes) && (axisnum < 8); axisnum++) { // fetch the range of this axis DIPROPRANGE dipr; @@ -463,6 +635,7 @@ void dinput_joystick_device::configure(input_device &device) result = m_device->GetProperty(DIPROP_RANGE, &dipr.diph); if (result != DI_OK) { + // this is normal when axes are skipped, e.g. X/Y/Z present, rX/rY absent, rZ present osd_printf_verbose("DirectInput: Unable to get properties for joystick %s axis %u.\n", name(), axisnum); continue; } @@ -471,7 +644,7 @@ void dinput_joystick_device::configure(input_device &device) m_joystick.rangemax[axisnum] = dipr.lMax; // populate the item description as well - device.add_item( + axisitems[axisnum] = device.add_item( item_name(offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr), std::string_view(), input_item_id(ITEM_ID_XAXIS + axisnum), @@ -481,38 +654,114 @@ void dinput_joystick_device::configure(input_device &device) axiscount++; } - // populate the POVs + // take a guess at which axes might be pedals depending on type and remap onto negative half of range + input_item_id pedalitems[3] = { ITEM_ID_INVALID, ITEM_ID_INVALID, ITEM_ID_INVALID }; + if (DI8DEVTYPE_FLIGHT == type) + { + // Rx/Ry are often used for brakes + bool const rxpedal = (ITEM_ID_INVALID != axisitems[3]) && !m_joystick.rangemin[3] && (0 < m_joystick.rangemax[3]); + bool const rypedal = (ITEM_ID_INVALID != axisitems[4]) && !m_joystick.rangemin[4] && (0 < m_joystick.rangemax[4]); + if (rxpedal && rypedal) + { + pedalitems[0] = axisitems[3]; + m_joystick.rangemin[3] = m_joystick.rangemax[3]; + m_joystick.rangemax[3] = -m_joystick.rangemax[3]; + + pedalitems[1] = axisitems[4]; + m_joystick.rangemin[4] = m_joystick.rangemax[4]; + m_joystick.rangemax[4] = -m_joystick.rangemax[4]; + } + } + else if (DI8DEVTYPE_DRIVING == type) + { + bool const ypedal = (ITEM_ID_INVALID != axisitems[1]) && !m_joystick.rangemin[1] && (0 < m_joystick.rangemax[1]); + bool const rxpedal = (ITEM_ID_INVALID != axisitems[3]) && !m_joystick.rangemin[3] && (0 < m_joystick.rangemax[3]); + bool const rypedal = (ITEM_ID_INVALID != axisitems[4]) && !m_joystick.rangemin[4] && (0 < m_joystick.rangemax[4]); + bool const rzpedal = (ITEM_ID_INVALID != axisitems[5]) && !m_joystick.rangemin[5] && (0 < m_joystick.rangemax[5]); + bool const s0pedal = (ITEM_ID_INVALID != axisitems[6]) && !m_joystick.rangemin[6] && (0 < m_joystick.rangemax[6]); + if (DI8DEVTYPEDRIVING_DUALPEDALS == subtype) + { + // dual pedals are usually Y and Rz + if (ypedal && rzpedal) + { + pedalitems[0] = axisitems[1]; + m_joystick.rangemin[1] = m_joystick.rangemax[1]; + m_joystick.rangemax[1] = -m_joystick.rangemax[1]; + + pedalitems[1] = axisitems[5]; + m_joystick.rangemin[5] = m_joystick.rangemax[5]; + m_joystick.rangemax[5] = -m_joystick.rangemax[5]; + } + } + else if (DI8DEVTYPEDRIVING_THREEPEDALS == subtype) + { + // triple pedals may be Y, Rz and slider 0, or Rx, Ry and Rz + if (ypedal && rzpedal && s0pedal) + { + pedalitems[0] = axisitems[1]; + m_joystick.rangemin[1] = m_joystick.rangemax[1]; + m_joystick.rangemax[1] = -m_joystick.rangemax[1]; + + pedalitems[1] = axisitems[5]; + m_joystick.rangemin[5] = m_joystick.rangemax[5]; + m_joystick.rangemax[5] = -m_joystick.rangemax[5]; + + pedalitems[2] = axisitems[6]; + m_joystick.rangemin[6] = m_joystick.rangemax[6]; + m_joystick.rangemax[6] = -m_joystick.rangemax[6]; + } + else if (rxpedal && rypedal && rzpedal) + { + pedalitems[0] = axisitems[3]; + m_joystick.rangemin[3] = m_joystick.rangemax[3]; + m_joystick.rangemax[3] = -m_joystick.rangemax[3]; + + pedalitems[1] = axisitems[4]; + m_joystick.rangemin[4] = m_joystick.rangemax[4]; + m_joystick.rangemax[4] = -m_joystick.rangemax[4]; + + pedalitems[2] = axisitems[5]; + m_joystick.rangemin[5] = m_joystick.rangemax[5]; + m_joystick.rangemax[5] = -m_joystick.rangemax[5]; + } + } + } + + // populate the POV hats + input_item_id povitems[4][4]; + for (auto &pov : povitems) + std::fill(std::begin(pov), std::end(pov), ITEM_ID_INVALID); for (uint32_t povnum = 0; povnum < m_caps.dwPOVs; povnum++) { // left - device.add_item( + povitems[povnum][0] = device.add_item( item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Left"), std::string_view(), - input_item_id(povnum * 4 + ITEM_ID_HAT1LEFT), + input_item_id((povnum * 4) + ITEM_ID_HAT1LEFT), &dinput_joystick_device::pov_get_state, reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_LEFT))); // right - device.add_item( + povitems[povnum][1] = device.add_item( item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Right"), std::string_view(), - input_item_id(povnum * 4 + ITEM_ID_HAT1RIGHT), + input_item_id((povnum * 4) + ITEM_ID_HAT1RIGHT), &dinput_joystick_device::pov_get_state, reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_RIGHT))); // up - device.add_item( + povitems[povnum][2] = device.add_item( item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Up"), std::string_view(), - input_item_id(povnum * 4 + ITEM_ID_HAT1UP), + input_item_id((povnum * 4) + ITEM_ID_HAT1UP), &dinput_joystick_device::pov_get_state, reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_UP))); // down - device.add_item( + povitems[povnum][3] = device.add_item( item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Down"), std::string_view(), - input_item_id(povnum * 4 + ITEM_ID_HAT1DOWN), + input_item_id((povnum * 4) + ITEM_ID_HAT1DOWN), &dinput_joystick_device::pov_get_state, reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_DOWN))); } @@ -530,13 +779,386 @@ void dinput_joystick_device::configure(input_device &device) else itemid = ITEM_ID_OTHER_SWITCH; - device.add_item( + input_item_id const actual = device.add_item( item_name(offset, default_button_name(butnum), nullptr), std::string_view(), itemid, generic_button_get_state<BYTE>, &m_joystick.state.rgbButtons[butnum]); + + // there are sixteen action button types + if (butnum < 16) + { + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, actual)); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + butnum), SEQ_TYPE_STANDARD, seq); + + // assign the first few buttons to UI actions and pedals + // TODO: don't map pedals for driving controls that have them present + switch (butnum) + { + case 0: + assignments.emplace_back(IPT_PEDAL, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back(IPT_UI_SELECT, SEQ_TYPE_STANDARD, seq); + break; + case 1: + assignments.emplace_back(IPT_PEDAL2, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back((3 > m_caps.dwButtons) ? IPT_UI_CLEAR : IPT_UI_BACK, SEQ_TYPE_STANDARD, seq); + break; + case 2: + assignments.emplace_back(IPT_PEDAL3, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back(IPT_UI_CLEAR, SEQ_TYPE_STANDARD, seq); + break; + case 3: + assignments.emplace_back(IPT_UI_HELP, SEQ_TYPE_STANDARD, seq); + break; + } + } + } + + // add default assignments depending on type + if (DI8DEVTYPE_FLIGHT == type) + { + if (((ITEM_ID_INVALID == axisitems[0]) || (ITEM_ID_INVALID == axisitems[1])) && (1 <= m_caps.dwPOVs)) + { + // X or Y missing, fall back to using POV hat for navigation + add_directional_assignments( + assignments, + axisitems[0], + axisitems[1], + povitems[0][0], + povitems[0][1], + povitems[0][2], + povitems[0][3]); + + // try using throttle for zoom/focus + if (ITEM_ID_INVALID != axisitems[2]) + { + input_seq const negseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisitems[2])); + input_seq const posseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisitems[2])); + if (ITEM_ID_INVALID != axisitems[5]) + { + assignments.emplace_back(IPT_UI_ZOOM_IN, SEQ_TYPE_STANDARD, posseq); + assignments.emplace_back(IPT_UI_ZOOM_OUT, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_FOCUS_PREV, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_FOCUS_NEXT, SEQ_TYPE_STANDARD, posseq); + } + else + { + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, posseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, negseq); + } + } + + // try using twist/rudder for next/previous group + if (ITEM_ID_INVALID != axisitems[5]) + { + input_seq const negseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisitems[5])); + input_seq const posseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisitems[5])); + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, posseq); + } + } + else + { + // only use stick for primary navigation/movement + add_directional_assignments( + assignments, + axisitems[0], + axisitems[1], + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID); + + // try using hat for secondary navigation functions + if (1 <= m_caps.dwPOVs) + { + input_seq const leftseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, povitems[0][0])); + input_seq const rightseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, povitems[0][1])); + input_seq const upseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, povitems[0][2])); + input_seq const downseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, povitems[0][3])); + if ((ITEM_ID_INVALID != axisitems[2]) || (ITEM_ID_INVALID != axisitems[5])) + { + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, rightseq); + assignments.emplace_back(IPT_UI_PAGE_UP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_UI_PAGE_DOWN, SEQ_TYPE_STANDARD, downseq); + } + else + { + assignments.emplace_back(IPT_UI_FOCUS_PREV, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_UI_FOCUS_NEXT, SEQ_TYPE_STANDARD, rightseq); + assignments.emplace_back(IPT_UI_ZOOM_OUT, SEQ_TYPE_STANDARD, leftseq); + assignments.emplace_back(IPT_UI_ZOOM_IN, SEQ_TYPE_STANDARD, rightseq); + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, downseq); + } + } + + // try using throttle for zoom + if (ITEM_ID_INVALID != axisitems[2]) + { + input_seq const negseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisitems[2])); + input_seq const posseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisitems[2])); + if ((1 <= m_caps.dwPOVs) || (ITEM_ID_INVALID != axisitems[5])) + { + assignments.emplace_back(IPT_UI_ZOOM_IN, SEQ_TYPE_STANDARD, posseq); + assignments.emplace_back(IPT_UI_ZOOM_OUT, SEQ_TYPE_STANDARD, negseq); + if ((1 > m_caps.dwPOVs) || (ITEM_ID_INVALID == axisitems[5])) + { + assignments.emplace_back(IPT_UI_FOCUS_PREV, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_FOCUS_NEXT, SEQ_TYPE_STANDARD, posseq); + } + } + else + { + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, posseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, negseq); + } + } + + // try using twist/rudder for focus next/previous + if (ITEM_ID_INVALID != axisitems[5]) + { + input_seq const negseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisitems[5])); + input_seq const posseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisitems[5])); + if (1 <= m_caps.dwPOVs) + { + assignments.emplace_back(IPT_UI_FOCUS_PREV, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_FOCUS_NEXT, SEQ_TYPE_STANDARD, posseq); + if (ITEM_ID_INVALID == axisitems[2]) + { + assignments.emplace_back(IPT_UI_ZOOM_IN, SEQ_TYPE_STANDARD, posseq); + assignments.emplace_back(IPT_UI_ZOOM_OUT, SEQ_TYPE_STANDARD, negseq); + } + } + else + { + assignments.emplace_back(IPT_UI_PREV_GROUP, SEQ_TYPE_STANDARD, negseq); + assignments.emplace_back(IPT_UI_NEXT_GROUP, SEQ_TYPE_STANDARD, posseq); + } + } + } + + // Z or slider 0 is usually the throttle - use one of them for joystick Z + add_assignment( + assignments, + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NONE, + { axisitems[2], axisitems[6] }); + + // use Z for the first two pedals if present + if (ITEM_ID_INVALID != axisitems[2]) + { + // TODO: use Rx/Ry as well if they appear to be brakes + input_seq const pedal1seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, axisitems[2])); + input_seq const pedal2seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, axisitems[2])); + assignments.emplace_back(IPT_PEDAL, SEQ_TYPE_STANDARD, pedal1seq); + assignments.emplace_back(IPT_PEDAL2, SEQ_TYPE_STANDARD, pedal2seq); + } + } + else if (DI8DEVTYPE_DRIVING == type) + { + // use the wheel and D-pad for navigation and directional controls + add_directional_assignments( + assignments, + axisitems[0], + ITEM_ID_INVALID, + povitems[0][0], + povitems[0][1], + povitems[0][2], + povitems[0][3]); + + // check subtype to determine how pedals should be assigned + if (DI8DEVTYPEDRIVING_COMBINEDPEDALS == subtype) + { + if (ITEM_ID_INVALID != axisitems[1]) + { + // put first two pedals on opposite sides of Y axis + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, axisitems[1]))); + assignments.emplace_back( + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, axisitems[1]))); + + // use for previous/next group as well + assignments.emplace_back( + IPT_UI_NEXT_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisitems[1]))); + assignments.emplace_back( + IPT_UI_PREV_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisitems[1]))); + } + } + else + { + // see if we have individual pedals + if (ITEM_ID_INVALID != pedalitems[0]) + { + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, pedalitems[0]))); + assignments.emplace_back( + IPT_UI_NEXT_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, pedalitems[0]))); + } + if (ITEM_ID_INVALID != pedalitems[1]) + { + assignments.emplace_back( + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, pedalitems[1]))); + assignments.emplace_back( + IPT_UI_PREV_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, pedalitems[1]))); + } + if (ITEM_ID_INVALID != pedalitems[2]) + { + assignments.emplace_back( + IPT_PEDAL3, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, pedalitems[2]))); + assignments.emplace_back( + IPT_UI_FOCUS_NEXT, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, pedalitems[2]))); + } + } + } + else + { + // assume this is a gamepad - see if it looks like it has dual analog sticks + input_item_id stickaxes[2][2] = { + { axisitems[0], axisitems[1] }, + { ITEM_ID_INVALID, ITEM_ID_INVALID } }; + input_item_id pedalaxis = ITEM_ID_INVALID; + if ((ITEM_ID_INVALID != axisitems[3]) && (ITEM_ID_INVALID != axisitems[4])) + { + // assume Rx/Ry are right stick and Z is triggers if present + stickaxes[1][0] = axisitems[3]; + stickaxes[1][1] = axisitems[4]; + pedalaxis = axisitems[2]; + add_twin_stick_assignments( + assignments, + stickaxes[0][0], + stickaxes[0][1], + stickaxes[1][0], + stickaxes[1][1], + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID); + } + else if ((ITEM_ID_INVALID != axisitems[2]) && (ITEM_ID_INVALID != axisitems[5])) + { + // assume Z/Rz are right stick + stickaxes[1][0] = axisitems[2]; + stickaxes[1][1] = axisitems[5]; + add_twin_stick_assignments( + assignments, + stickaxes[0][0], + stickaxes[0][1], + stickaxes[1][0], + stickaxes[1][1], + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID); + } + else + { + // if Z is present, use it as secondary Y + stickaxes[1][1] = axisitems[2]; + } + + // try to find a "complete" stick for primary movement controls + input_item_id diraxis[2][2]; + choose_primary_stick(diraxis, stickaxes[0][0], stickaxes[0][1], stickaxes[1][0], stickaxes[1][1]); + add_directional_assignments( + assignments, + diraxis[0][0], + diraxis[0][1], + povitems[0][0], + povitems[0][1], + povitems[0][2], + povitems[0][3]); + + // assign a secondary stick axis to joystick Z + add_assignment( + assignments, + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NONE, + { diraxis[1][1], diraxis[1][0] }); + + // try to find a suitable axis to use for the first two pedals + add_assignment( + assignments, + IPT_PEDAL, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NEG, + { pedalaxis, diraxis[1][1], diraxis[0][1] }); + add_assignment( + assignments, + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_POS, + { pedalaxis, diraxis[1][1], diraxis[0][1] }); + + // try to choose an axis for previous/next group + if (ITEM_ID_INVALID != pedalaxis) + { + // this is reversed because right trigger is negative direction + assignments.emplace_back( + IPT_UI_PREV_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, pedalaxis))); + assignments.emplace_back( + IPT_UI_NEXT_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, pedalaxis))); + pedalaxis = ITEM_ID_INVALID; + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, diraxis[1][1])) + { + // took secondary Y + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, diraxis[1][0])) + { + // took secondary X + } + + // use secondary Y for page up/down if available + consume_axis_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, diraxis[1][1]); + + // put focus previous/next and zoom on secondary X if available + add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, diraxis[1][0]); + add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, diraxis[1][0]); } + + // set default assignments + device.set_default_assignments(std::move(assignments)); } int32_t dinput_joystick_device::pov_get_state(void *device_internal, void *item_internal) @@ -580,7 +1202,7 @@ dinput_api_helper::~dinput_api_helper() int dinput_api_helper::initialize() { - HRESULT result = DirectInput8Create(GetModuleHandleUni(), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void **>(m_dinput.GetAddressOf()), nullptr); + HRESULT result = DirectInput8Create(GetModuleHandleUni(), DIRECTINPUT_VERSION, IID_IDirectInput8, &m_dinput, nullptr); if (result != DI_OK) { return result; @@ -683,6 +1305,18 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a return std::make_pair(std::move(device), format); } + +std::string dinput_api_helper::make_id(LPCDIDEVICEINSTANCE instance) +{ + // use name, product GUID and instance GUID as identifier + return + text::from_tstring(instance->tszInstanceName) + + " product_" + + guid_to_string(instance->guidProduct) + + " instance_" + + guid_to_string(instance->guidInstance); +} + } // namespace osd diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h index 75fc873d049..a5d6877723e 100644 --- a/src/osd/modules/input/input_dinput.h +++ b/src/osd/modules/input/input_dinput.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles, Brad Hughes +// copyright-holders:Aaron Giles, Brad Hughes, Vas Crabb //============================================================ // // input_dinput.h - Windows DirectInput support @@ -10,6 +10,7 @@ #pragma once +#include "assignmenthelper.h" #include "input_wincommon.h" #include "modules/lib/osdlib.h" @@ -81,16 +82,10 @@ public: if (!callback(device, format)) return nullptr; - // convert instance name to UTF-8 - std::string utf8_instance_name = text::from_tstring(instance->tszInstanceName); - - // set device id to name + product unique identifier + instance unique identifier - std::string utf8_instance_id = utf8_instance_name + " product_" + guid_to_string(instance->guidProduct) + " instance_" + guid_to_string(instance->guidInstance); - // allocate memory for the device object return std::make_unique<TDevice>( - std::move(utf8_instance_name), - std::move(utf8_instance_id), + text::from_tstring(instance->tszInstanceName), + make_id(instance), module, std::move(device), caps, @@ -117,22 +112,6 @@ public: return device->SetProperty(property_guid, &dipdw.diph); } - static std::string guid_to_string(const GUID& guid) - { - // Size of a GUID string with dashes plus null terminator - char guid_string[37]; - - snprintf( - guid_string, std::size(guid_string), - "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid.Data1, guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], - guid.Data4[3], guid.Data4[4], guid.Data4[5], - guid.Data4[6], guid.Data4[7]); - - return guid_string; - } - private: std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> open_device( LPCDIDEVICEINSTANCE instance, @@ -140,6 +119,8 @@ private: LPCDIDATAFORMAT format2, dinput_cooperative_level cooperative_level); + static std::string make_id(LPCDIDEVICEINSTANCE instance); + Microsoft::WRL::ComPtr<IDirectInput8> m_dinput; dynamic_module::ptr m_dinput_dll; }; @@ -167,48 +148,7 @@ protected: }; -class dinput_keyboard_device : public dinput_device -{ -public: - dinput_keyboard_device( - std::string &&name, - std::string &&id, - input_module &module, - Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, - DIDEVCAPS const &caps, - LPCDIDATAFORMAT format); - - virtual void poll() override; - virtual void reset() override; - virtual void configure(input_device &device) override; - -private: - std::mutex m_device_lock; - keyboard_state m_keyboard; -}; - - -class dinput_mouse_device : public dinput_device -{ -public: - dinput_mouse_device( - std::string &&name, - std::string &&id, - input_module &module, - Microsoft::WRL::ComPtr<IDirectInputDevice8> &&device, - DIDEVCAPS const &caps, - LPCDIDATAFORMAT format); - - void poll() override; - void reset() override; - virtual void configure(input_device &device) override; - -private: - mouse_state m_mouse; -}; - - -class dinput_joystick_device : public dinput_device +class dinput_joystick_device : public dinput_device, protected joystick_assignment_helper { public: dinput_joystick_device( diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 4e4f1811e40..ca6522f20e2 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -21,7 +21,7 @@ #include "strconv.h" // MAME headers -#include "emu.h" +#include "inpttype.h" #include <algorithm> #include <cassert> diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp index 6def55c5cc0..68779a151e4 100644 --- a/src/osd/modules/input/input_sdl.cpp +++ b/src/osd/modules/input/input_sdl.cpp @@ -17,6 +17,7 @@ #if defined(OSD_SDL) +#include "assignmenthelper.h" #include "input_common.h" #include "interface/inputseq.h" @@ -24,7 +25,7 @@ #include "sdl/osdsdl.h" // emu -#include "emu.h" +#include "inpttype.h" // standard SDL header #include <SDL2/SDL.h> @@ -759,7 +760,7 @@ private: // sdl_joystick_device_base //============================================================ -class sdl_joystick_device_base : public sdl_device +class sdl_joystick_device_base : public sdl_device, protected joystick_assignment_helper { public: std::optional<std::string> const &serial() const { return m_serial; } @@ -834,6 +835,7 @@ public: virtual void configure(input_device &device) override { + input_device::assignment_vector assignments; char tempname[32]; int const axiscount = SDL_JoystickNumAxes(m_joydevice); @@ -842,6 +844,7 @@ public: int const ballcount = SDL_JoystickNumBalls(m_joydevice); // loop over all axes + input_item_id axisactual[MAX_AXES]; for (int axis = 0; (axis < MAX_AXES) && (axis < axiscount); axis++) { input_item_id itemid; @@ -854,7 +857,7 @@ public: itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE; snprintf(tempname, sizeof(tempname), "A%d", axis + 1); - device.add_item( + axisactual[axis] = device.add_item( tempname, std::string_view(), itemid, @@ -876,22 +879,50 @@ public: else itemid = ITEM_ID_OTHER_SWITCH; - device.add_item( + input_item_id const actual = device.add_item( default_button_name(button), std::string_view(), itemid, generic_button_get_state<s32>, &m_joystick.buttons[button]); + + // there are sixteen action button types + if (button < 16) + { + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, actual)); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button), SEQ_TYPE_STANDARD, seq); + + // assign the first few buttons to UI actions and pedals + switch (button) + { + case 0: + assignments.emplace_back(IPT_PEDAL, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back(IPT_UI_SELECT, SEQ_TYPE_STANDARD, seq); + break; + case 1: + assignments.emplace_back(IPT_PEDAL2, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back((3 > buttoncount) ? IPT_UI_CLEAR : IPT_UI_BACK, SEQ_TYPE_STANDARD, seq); + break; + case 2: + assignments.emplace_back(IPT_PEDAL3, SEQ_TYPE_INCREMENT, seq); + assignments.emplace_back(IPT_UI_CLEAR, SEQ_TYPE_STANDARD, seq); + break; + case 3: + assignments.emplace_back(IPT_UI_HELP, SEQ_TYPE_STANDARD, seq); + break; + } + } } // loop over all hats + input_item_id hatactual[MAX_HATS][4]; for (int hat = 0; (hat < MAX_HATS) && (hat < hatcount); hat++) { input_item_id itemid; snprintf(tempname, sizeof(tempname), "Hat %d Up", hat + 1); itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + (4 * hat) : ITEM_ID_OTHER_SWITCH); - device.add_item( + hatactual[hat][0] = device.add_item( tempname, std::string_view(), itemid, @@ -900,7 +931,7 @@ public: snprintf(tempname, sizeof(tempname), "Hat %d Down", hat + 1); itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + (4 * hat) : ITEM_ID_OTHER_SWITCH); - device.add_item( + hatactual[hat][1] = device.add_item( tempname, std::string_view(), itemid, @@ -909,7 +940,7 @@ public: snprintf(tempname, sizeof(tempname), "Hat %d Left", hat + 1); itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + (4 * hat) : ITEM_ID_OTHER_SWITCH); - device.add_item( + hatactual[hat][2] = device.add_item( tempname, std::string_view(), itemid, @@ -918,7 +949,7 @@ public: snprintf(tempname, sizeof(tempname), "Hat %d Right", hat + 1); itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + (4 * hat) : ITEM_ID_OTHER_SWITCH); - device.add_item( + hatactual[hat][3] = device.add_item( tempname, std::string_view(), itemid, @@ -937,7 +968,7 @@ public: itemid = ITEM_ID_OTHER_AXIS_RELATIVE; snprintf(tempname, sizeof(tempname), "R%d X", ball + 1); - device.add_item( + input_item_id const xactual = device.add_item( tempname, std::string_view(), input_item_id(itemid), @@ -945,13 +976,130 @@ public: &m_joystick.balls[ball * 2]); snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1); - device.add_item( + input_item_id const yactual = device.add_item( tempname, std::string_view(), input_item_id(itemid + 1), generic_axis_get_state<s32>, &m_joystick.balls[ball * 2 + 1]); + + if (0 == ball) + { + // assign the first trackball to dial, trackball, mouse and lightgun inputs + input_seq const xseq(make_code(ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, xactual)); + input_seq const yseq(make_code(ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, yactual)); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_STANDARD, yseq); + assignments.emplace_back(IPT_MOUSE_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_MOUSE_Y, SEQ_TYPE_STANDARD, yseq); + if (2 > axiscount) + { + // use it for joystick inputs if axes are limited + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_STANDARD, xseq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_STANDARD, yseq); + } + else + { + // use for non-centring throttle control + assignments.emplace_back(IPT_AD_STICK_Z, SEQ_TYPE_STANDARD, yseq); + } + } + else if ((1 == ball) && (2 > axiscount)) + { + // provide a non-centring throttle control + input_seq const yseq(make_code(ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, yactual)); + assignments.emplace_back(IPT_AD_STICK_Z, SEQ_TYPE_STANDARD, yseq); + } + } + + // set up default assignments for axes and hats + add_directional_assignments( + assignments, + (1 <= axiscount) ? axisactual[0] : ITEM_ID_INVALID, // assume first axis is X + (2 <= axiscount) ? axisactual[1] : ITEM_ID_INVALID, // assume second axis is Y + (1 <= hatcount) ? hatactual[0][2] : ITEM_ID_INVALID, + (1 <= hatcount) ? hatactual[0][3] : ITEM_ID_INVALID, + (1 <= hatcount) ? hatactual[0][0] : ITEM_ID_INVALID, + (1 <= hatcount) ? hatactual[0][1] : ITEM_ID_INVALID); + if (2 <= axiscount) + { + // put pedals on the last of the second, third or fourth axis + input_item_id const pedalitem = axisactual[(std::min)(axiscount, 4) - 1]; + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, pedalitem))); + assignments.emplace_back( + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, pedalitem))); + } + if (3 <= axiscount) + { + // assign X/Y to one of the twin sticks + assignments.emplace_back( + (4 <= axiscount) ? IPT_JOYSTICKLEFT_LEFT : IPT_JOYSTICKRIGHT_LEFT, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_LEFT, axisactual[0]))); + assignments.emplace_back( + (4 <= axiscount) ? IPT_JOYSTICKLEFT_RIGHT : IPT_JOYSTICKRIGHT_RIGHT, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_RIGHT, axisactual[0]))); + assignments.emplace_back( + (4 <= axiscount) ? IPT_JOYSTICKLEFT_UP : IPT_JOYSTICKRIGHT_UP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_UP, axisactual[1]))); + assignments.emplace_back( + (4 <= axiscount) ? IPT_JOYSTICKLEFT_DOWN : IPT_JOYSTICKRIGHT_DOWN, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_DOWN, axisactual[1]))); + + // use third or fourth axis for Z + input_seq const seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, axisactual[(std::min)(axiscount, 4) - 1])); + assignments.emplace_back(IPT_AD_STICK_Z, SEQ_TYPE_STANDARD, seq); + + // use this for focus next/previous to make system selection menu practical to navigate + input_seq const upseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisactual[2])); + input_seq const downseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisactual[2])); + assignments.emplace_back(IPT_UI_FOCUS_PREV, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_UI_FOCUS_NEXT, SEQ_TYPE_STANDARD, downseq); + if (4 <= axiscount) + { + // use for zoom as well if there's another axis to use for previous/next group + assignments.emplace_back(IPT_UI_ZOOM_IN, SEQ_TYPE_STANDARD, downseq); + assignments.emplace_back(IPT_UI_ZOOM_OUT, SEQ_TYPE_STANDARD, upseq); + } + + // use this for twin sticks, too + assignments.emplace_back((4 <= axiscount) ? IPT_JOYSTICKRIGHT_LEFT : IPT_JOYSTICKLEFT_UP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back((4 <= axiscount) ? IPT_JOYSTICKRIGHT_RIGHT : IPT_JOYSTICKLEFT_DOWN, SEQ_TYPE_STANDARD, downseq); + + // put previous/next group on the last of the third or fourth axis + input_item_id const groupitem = axisactual[(std::min)(axiscount, 4) - 1]; + assignments.emplace_back( + IPT_UI_PREV_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, groupitem))); + assignments.emplace_back( + IPT_UI_NEXT_GROUP, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, groupitem))); + } + if (4 <= axiscount) + { + // use this for twin sticks + input_seq const upseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axisactual[3])); + input_seq const downseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, axisactual[3])); + assignments.emplace_back(IPT_JOYSTICKRIGHT_UP, SEQ_TYPE_STANDARD, upseq); + assignments.emplace_back(IPT_JOYSTICKRIGHT_DOWN, SEQ_TYPE_STANDARD, downseq); } + + // set default assignments + device.set_default_assignments(std::move(assignments)); } ~sdl_joystick_device() @@ -1132,9 +1280,13 @@ public: virtual void configure(input_device &device) override { + input_device::assignment_vector assignments; char const *const *axisnames = CONTROLLER_AXIS_XBOX; char const *const *buttonnames = CONTROLLER_BUTTON_XBOX360; bool digitaltriggers = false; +#if SDL_VERSION_ATLEAST(2, 0, 14) + bool avoidpaddles = false; +#endif #if SDL_VERSION_ATLEAST(2, 0, 12) auto const ctrltype = SDL_GameControllerGetType(m_ctrldevice); switch (ctrltype) @@ -1197,6 +1349,7 @@ public: axisnames = CONTROLLER_AXIS_SWITCH; buttonnames = CONTROLLER_BUTTON_SWITCH; digitaltriggers = true; + avoidpaddles = true; break; #endif default: // default to Xbox 360 names @@ -1205,6 +1358,23 @@ public: } #endif + // keep track of item numbers as we add controls + std::pair<input_item_id, input_item_id> axisitems[SDL_CONTROLLER_AXIS_MAX]; + input_item_id buttonitems[SDL_CONTROLLER_BUTTON_MAX]; + std::tuple<input_item_id, SDL_GameControllerButton, SDL_GameControllerAxis> numberedbuttons[16]; + std::fill( + std::begin(axisitems), + std::end(axisitems), + std::make_pair(ITEM_ID_INVALID, ITEM_ID_INVALID)); + std::fill( + std::begin(buttonitems), + std::end(buttonitems), + ITEM_ID_INVALID); + std::fill( + std::begin(numberedbuttons), + std::end(numberedbuttons), + std::make_tuple(ITEM_ID_INVALID, SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_INVALID)); + // add axes std::tuple<SDL_GameControllerAxis, input_item_id, bool> const axes[]{ { SDL_CONTROLLER_AXIS_LEFTX, ITEM_ID_XAXIS, false }, @@ -1237,7 +1407,7 @@ public: } if (avail) { - device.add_item( + axisitems[axis].first = device.add_item( axisnames[axis], std::string_view(), item, @@ -1247,33 +1417,35 @@ public: } // add automatically numbered buttons - std::tuple<SDL_GameControllerButton, SDL_GameControllerAxis> const generalbuttons[]{ - { SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_Y, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERLEFT }, - { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERRIGHT }, - { SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_AXIS_INVALID }, + std::tuple<SDL_GameControllerButton, SDL_GameControllerAxis, bool> const generalbuttons[]{ + { SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_Y, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERLEFT, true }, + { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, true }, + { SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_AXIS_INVALID, true }, #if SDL_VERSION_ATLEAST(2, 0, 14) - { SDL_CONTROLLER_BUTTON_PADDLE1, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_PADDLE4, SDL_CONTROLLER_AXIS_INVALID }, + { SDL_CONTROLLER_BUTTON_PADDLE1, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_AXIS_INVALID, true }, + { SDL_CONTROLLER_BUTTON_PADDLE4, SDL_CONTROLLER_AXIS_INVALID, true }, #endif - { SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_AXIS_INVALID }, + { SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_AXIS_INVALID, false }, #if SDL_VERSION_ATLEAST(2, 0, 14) - { SDL_CONTROLLER_BUTTON_MISC1, SDL_CONTROLLER_AXIS_INVALID }, - { SDL_CONTROLLER_BUTTON_TOUCHPAD, SDL_CONTROLLER_AXIS_INVALID }, + { SDL_CONTROLLER_BUTTON_MISC1, SDL_CONTROLLER_AXIS_INVALID, false }, + { SDL_CONTROLLER_BUTTON_TOUCHPAD, SDL_CONTROLLER_AXIS_INVALID, false }, #endif }; input_item_id button_item = ITEM_ID_BUTTON1; - for (auto [button, axis] : generalbuttons) + unsigned buttoncount = 0; + for (auto [button, axis, field] : generalbuttons) { bool avail = true; + input_item_id actual = ITEM_ID_INVALID; if (SDL_CONTROLLER_BUTTON_INVALID != button) { #if SDL_VERSION_ATLEAST(2, 0, 14) @@ -1293,12 +1465,14 @@ public: } if (avail) { - device.add_item( + actual = buttonitems[button] = device.add_item( buttonnames[button], std::string_view(), button_item++, generic_button_get_state<s32>, &m_controller.buttons[button]); + if (field && (std::size(numberedbuttons) > buttoncount)) + std::get<1>(numberedbuttons[buttoncount]) = button; } } else @@ -1322,7 +1496,7 @@ public: } if (avail) { - device.add_item( + actual = axisitems[axis].second = device.add_item( axisnames[axis], std::string_view(), button_item++, @@ -1332,8 +1506,17 @@ public: return (*reinterpret_cast<s32 const *>(item_internal) <= -16'384) ? 1 : 0; }, &m_controller.axes[axis]); + if (field && (std::size(numberedbuttons) > buttoncount)) + std::get<2>(numberedbuttons[buttoncount]) = axis; } } + + // add default button assignments + if (field && avail && (std::size(numberedbuttons) > buttoncount)) + { + std::get<0>(numberedbuttons[buttoncount]) = actual; + add_button_assignment(assignments, ioport_type(IPT_BUTTON1 + buttoncount++), { actual }); + } } // add buttons with fixed item IDs @@ -1364,7 +1547,7 @@ public: } if (avail) { - device.add_item( + buttonitems[button] = device.add_item( buttonnames[button], std::string_view(), item, @@ -1372,6 +1555,310 @@ public: &m_controller.buttons[button]); } } + + // try to get a "complete" joystick for primary movement controls + input_item_id diraxis[2][2]; + choose_primary_stick( + diraxis, + axisitems[SDL_CONTROLLER_AXIS_LEFTX].first, + axisitems[SDL_CONTROLLER_AXIS_LEFTY].first, + axisitems[SDL_CONTROLLER_AXIS_RIGHTX].first, + axisitems[SDL_CONTROLLER_AXIS_RIGHTY].first); + + // now set up controls using the primary joystick + add_directional_assignments( + assignments, + diraxis[0][0], + diraxis[0][1], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_LEFT], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_RIGHT], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_UP], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_DOWN]); + + // assign a secondary stick axis to joystick Z if available + bool const zaxis = add_assignment( + assignments, + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NONE, + { diraxis[1][1], diraxis[1][0] }); + if (!zaxis) + { + // if both triggers are present, combine them, or failing that, fall back to a pair of buttons + if ((ITEM_ID_INVALID != axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first) && (ITEM_ID_INVALID != axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first)) + { + assignments.emplace_back( + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + input_seq( + make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first), + make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_REVERSE, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first))); + } + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, buttonitems[SDL_CONTROLLER_BUTTON_LEFTSHOULDER], buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER])) + { + // took shoulder buttons + } + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].second, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].second)) + { + // took trigger buttons + } +#if SDL_VERSION_ATLEAST(2, 0, 14) + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2])) + { + // took P1/P2 + } + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE3], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE4])) + { + // took P3/P4 + } +#endif + } + + // prefer trigger axes for pedals, otherwise take half axes and buttons + unsigned pedalbutton = 0; + if (!add_assignment(assignments, IPT_PEDAL, SEQ_TYPE_STANDARD, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, { axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first })) + { + add_assignment( + assignments, + IPT_PEDAL, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NEG, + { diraxis[1][1], diraxis[0][1] }); + bool const incbutton = add_assignment( + assignments, + IPT_PEDAL, + SEQ_TYPE_INCREMENT, + ITEM_CLASS_SWITCH, + ITEM_MODIFIER_NONE, + { axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].second, buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] }); + if (!incbutton) + { + if (add_assignment(assignments, IPT_PEDAL, SEQ_TYPE_INCREMENT, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, { std::get<0>(numberedbuttons[pedalbutton]) })) + ++pedalbutton; + } + } + if (!add_assignment(assignments, IPT_PEDAL2, SEQ_TYPE_STANDARD, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, { axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first })) + { + add_assignment( + assignments, + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_POS, + { diraxis[1][1], diraxis[0][1] }); + bool const incbutton = add_assignment( + assignments, + IPT_PEDAL2, + SEQ_TYPE_INCREMENT, + ITEM_CLASS_SWITCH, + ITEM_MODIFIER_NONE, + { axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].second, buttonitems[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] }); + if (!incbutton) + { + if (add_assignment(assignments, IPT_PEDAL2, SEQ_TYPE_INCREMENT, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, { std::get<0>(numberedbuttons[pedalbutton]) })) + ++pedalbutton; + } + } + add_assignment(assignments, IPT_PEDAL3, SEQ_TYPE_INCREMENT, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, { std::get<0>(numberedbuttons[pedalbutton]) }); + + // potentially use thumb sticks and/or D-pad and A/B/X/Y diamond for twin sticks + add_twin_stick_assignments( + assignments, + axisitems[SDL_CONTROLLER_AXIS_LEFTX].first, + axisitems[SDL_CONTROLLER_AXIS_LEFTY].first, + axisitems[SDL_CONTROLLER_AXIS_RIGHTX].first, + axisitems[SDL_CONTROLLER_AXIS_RIGHTY].first, + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_LEFT], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_RIGHT], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_UP], + buttonitems[SDL_CONTROLLER_BUTTON_DPAD_DOWN], + buttonitems[SDL_CONTROLLER_BUTTON_X], + buttonitems[SDL_CONTROLLER_BUTTON_B], + buttonitems[SDL_CONTROLLER_BUTTON_Y], + buttonitems[SDL_CONTROLLER_BUTTON_A]); + + // add assignments for buttons with fixed functions + add_button_assignment(assignments, IPT_SELECT, { buttonitems[SDL_CONTROLLER_BUTTON_BACK] }); + add_button_assignment(assignments, IPT_START, { buttonitems[SDL_CONTROLLER_BUTTON_START] }); + add_button_assignment(assignments, IPT_UI_MENU, { buttonitems[SDL_CONTROLLER_BUTTON_GUIDE] }); + + // the first button is always UI select + if (add_button_assignment(assignments, IPT_UI_SELECT, { std::get<0>(numberedbuttons[0]) })) + { + if (SDL_CONTROLLER_BUTTON_INVALID != std::get<1>(numberedbuttons[0])) + buttonitems[std::get<1>(numberedbuttons[0])] = ITEM_ID_INVALID; + if (SDL_CONTROLLER_AXIS_INVALID != std::get<2>(numberedbuttons[0])) + axisitems[std::get<2>(numberedbuttons[0])].second = ITEM_ID_INVALID; + } + + // try to get a matching pair of buttons for previous/next group + if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].second, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].second)) + { + // took digital triggers + } +#if SDL_VERSION_ATLEAST(2, 0, 14) + else if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2])) + { + // took upper paddles + } +#endif + else if (consume_trigger_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first)) + { + // took analog triggers + } +#if SDL_VERSION_ATLEAST(2, 0, 14) + else if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE3], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE4])) + { + // took lower paddles + } +#endif + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, diraxis[1][1])) + { + // took secondary Y + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, diraxis[1][0])) + { + // took secondary X + } + + // try to get a matching pair of buttons for page up/down +#if SDL_VERSION_ATLEAST(2, 0, 14) + if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2])) + { + // took upper paddles + } + else if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE3], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE4])) + { + // took lower paddles + } + else +#endif + if (consume_trigger_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first)) + { + // took analog triggers + } + else if (consume_axis_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, diraxis[1][1])) + { + // took secondary Y + } + + // try to assign X button to UI clear + if (add_button_assignment(assignments, IPT_UI_CLEAR, { buttonitems[SDL_CONTROLLER_BUTTON_X] })) + { + buttonitems[SDL_CONTROLLER_BUTTON_X] = ITEM_ID_INVALID; + } + else + { + // otherwise try to find an unassigned button + for (auto [item, button, axis] : numberedbuttons) + { + if ((SDL_CONTROLLER_BUTTON_INVALID != button) && (ITEM_ID_INVALID != buttonitems[button])) + { + add_button_assignment(assignments, IPT_UI_CLEAR, { item }); + buttonitems[button] = ITEM_ID_INVALID; + break; + } + else if ((SDL_CONTROLLER_AXIS_INVALID != axis) && (ITEM_ID_INVALID != axisitems[axis].second)) + { + add_button_assignment(assignments, IPT_UI_CLEAR, { item }); + axisitems[axis].second = ITEM_ID_INVALID; + break; + } + } + } + + // try to assign B button to UI back + if (add_button_assignment(assignments, IPT_UI_BACK, { buttonitems[SDL_CONTROLLER_BUTTON_B] })) + { + buttonitems[SDL_CONTROLLER_BUTTON_X] = ITEM_ID_INVALID; + } + else + { + // otherwise try to find an unassigned button + for (auto [item, button, axis] : numberedbuttons) + { + if ((SDL_CONTROLLER_BUTTON_INVALID != button) && (ITEM_ID_INVALID != buttonitems[button])) + { + add_button_assignment(assignments, IPT_UI_CLEAR, { item }); + buttonitems[button] = ITEM_ID_INVALID; + break; + } + else if ((SDL_CONTROLLER_AXIS_INVALID != axis) && (ITEM_ID_INVALID != axisitems[axis].second)) + { + add_button_assignment(assignments, IPT_UI_CLEAR, { item }); + axisitems[axis].second = ITEM_ID_INVALID; + break; + } + } + } + + // try to assign Y button to UI help + if (add_button_assignment(assignments, IPT_UI_HELP, { buttonitems[SDL_CONTROLLER_BUTTON_Y] })) + { + buttonitems[SDL_CONTROLLER_BUTTON_Y] = ITEM_ID_INVALID; + } + else + { + // otherwise try to find an unassigned button + for (auto [item, button, axis] : numberedbuttons) + { + if ((SDL_CONTROLLER_BUTTON_INVALID != button) && (ITEM_ID_INVALID != buttonitems[button])) + { + add_button_assignment(assignments, IPT_UI_HELP, { item }); + buttonitems[button] = ITEM_ID_INVALID; + break; + } + else if ((SDL_CONTROLLER_AXIS_INVALID != axis) && (ITEM_ID_INVALID != axisitems[axis].second)) + { + add_button_assignment(assignments, IPT_UI_HELP, { item }); + axisitems[axis].second = ITEM_ID_INVALID; + break; + } + } + } + + // put focus previous/next on the shoulder buttons if available - this can be overloaded with zoom + if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, buttonitems[SDL_CONTROLLER_BUTTON_LEFTSHOULDER], buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER])) + { + // took shoulder buttons + } + else if (add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, diraxis[1][0])) + { + // took secondary X + } + else if (add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, diraxis[1][1])) + { + // took secondary Y + } + + // put zoom on the secondary stick if available, or fall back to shoulder buttons + if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, diraxis[1][0])) + { + // took secondary X + if (axisitems[SDL_CONTROLLER_AXIS_LEFTX].first == diraxis[1][0]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { buttonitems[SDL_CONTROLLER_BUTTON_LEFTSTICK] }); + else if (axisitems[SDL_CONTROLLER_AXIS_RIGHTX].first == diraxis[1][0]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSTICK] }); + diraxis[1][0] = ITEM_ID_INVALID; + } + else if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_IN, IPT_UI_ZOOM_OUT, diraxis[1][1])) + { + // took secondary Y + if (axisitems[SDL_CONTROLLER_AXIS_LEFTY].first == diraxis[1][1]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { buttonitems[SDL_CONTROLLER_BUTTON_LEFTSTICK] }); + else if (axisitems[SDL_CONTROLLER_AXIS_RIGHTY].first == diraxis[1][1]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSTICK] }); + diraxis[1][1] = ITEM_ID_INVALID; + } + else if (consume_button_pair(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, buttonitems[SDL_CONTROLLER_BUTTON_LEFTSHOULDER], buttonitems[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER])) + { + // took shoulder buttons + } + + // set default assignments + device.set_default_assignments(std::move(assignments)); } virtual void reset() override diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index 820650c4b1d..5c584e33d93 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -18,7 +18,7 @@ #include "window.h" // emu -#include "emu.h" +#include "inpttype.h" #include "strconv.h" diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp index 5e42e58e575..90101351a95 100644 --- a/src/osd/modules/input/input_windows.cpp +++ b/src/osd/modules/input/input_windows.cpp @@ -85,7 +85,7 @@ void windows_osd_interface::customize_input_type_list(std::vector<input_type_ent { // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between windows apps) - case IPT_UI_CONFIGURE: + case IPT_UI_MENU: entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; // configurable UI mode switch diff --git a/src/osd/modules/input/input_x11.cpp b/src/osd/modules/input/input_x11.cpp index b1d21d56c86..5230dfd7164 100644 --- a/src/osd/modules/input/input_x11.cpp +++ b/src/osd/modules/input/input_x11.cpp @@ -19,7 +19,7 @@ #include "sdl/osdsdl.h" // MAME headers -#include "emu.h" +#include "inpttype.h" // standard SDL header #include <SDL2/SDL.h> diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp index e8dc0af5e19..783dc720994 100644 --- a/src/osd/modules/input/input_xinput.cpp +++ b/src/osd/modules/input/input_xinput.cpp @@ -144,7 +144,7 @@ A X B LB -Rock band keyboards use axes as bit fields: +Rock Band keyboards use axes as bit fields: LT 7 C LT 6 C# @@ -178,13 +178,16 @@ LSX 15 C #if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) -// emu -#include "emu.h" // put this here before windows.h defines interface as a macro - #include "input_xinput.h" +#include "assignmenthelper.h" + +#include "interface/inputseq.h" #include "modules/lib/osdobj_common.h" +// emu +#include "inpttype.h" + // lib/util #include "util/coretmpl.h" @@ -192,6 +195,7 @@ LSX 15 C #include <algorithm> #include <cstdint> +#include <iterator> #include <string> #include <tuple> #include <utility> @@ -225,14 +229,6 @@ char const *const AXIS_NAMES_WHEEL[]{ "Brake", "Accelerator" }; -char const *const AXIS_NAMES_FLIGHT_STICK[]{ - "Joystick X", - "Joystick Y", - nullptr, - nullptr, - "Rudder", - "Throttle" }; - char const *const AXIS_NAMES_GUITAR[]{ "LSX", "LSY", @@ -249,14 +245,6 @@ input_item_id const AXIS_IDS_GAMEPAD[]{ ITEM_ID_SLIDER1, ITEM_ID_SLIDER2 }; -input_item_id const AXIS_IDS_FLIGHT_STICK[]{ - ITEM_ID_XAXIS, - ITEM_ID_YAXIS, - ITEM_ID_INVALID, - ITEM_ID_INVALID, - ITEM_ID_RZAXIS, - ITEM_ID_ZAXIS }; - char const *const HAT_NAMES_GAMEPAD[]{ "D-pad Up", "D-pad Down", @@ -295,6 +283,16 @@ char const *const BUTTON_NAMES_GAMEPAD[]{ "LSB", "RSB" }; +char const *const BUTTON_NAMES_FLIGHT_STICK[]{ + "A", + "B", + "X", + "Y", + "LB", + "RB", + "LSB", + "RSB" }; + char const *const BUTTON_NAMES_GUITAR[]{ "Fret 1", "Fret 2", @@ -331,7 +329,7 @@ char const *const BUTTON_NAMES_KEYBOARD[]{ // base class for XInput controller handlers //============================================================ -class xinput_device_base : public device_info +class xinput_device_base : public device_info, protected joystick_assignment_helper { protected: xinput_device_base( @@ -366,6 +364,28 @@ protected: bool is_reset() const { return m_reset; } void set_reset() { m_reset = true; } +protected: + template <unsigned M, unsigned N> + static bool assign_ui_button( + input_device::assignment_vector &assignments, + ioport_type type, + unsigned preferred, + input_item_id (&switch_ids)[M], + unsigned const (&numbered_buttons)[N], + unsigned button_count); + + template <unsigned M, unsigned N> + static void assign_ui_actions( + input_device::assignment_vector &assignments, + unsigned preferred_back, + unsigned preferred_clear, + unsigned preferred_help, + unsigned start, + unsigned back, + input_item_id (&switch_ids)[M], + unsigned const (&numbered_buttons)[N], + unsigned button_count); + private: bool probe_extended_type(); @@ -544,6 +564,96 @@ bool xinput_device_base::read_state() } +template <unsigned M, unsigned N> +bool xinput_device_base::assign_ui_button( + input_device::assignment_vector &assignments, + ioport_type type, + unsigned preferred, + input_item_id (&switch_ids)[M], + unsigned const (&numbered_buttons)[N], + unsigned button_count) +{ + assert(N >= button_count); + + // use preferred button if available + if (add_button_assignment(assignments, type, { switch_ids[preferred] })) + { + switch_ids[preferred] = ITEM_ID_INVALID; + return true; + } + + // otherwise find next available button + for (unsigned i = 0; button_count > i; ++i) + { + if (add_button_assignment(assignments, type, { switch_ids[numbered_buttons[i]] })) + { + switch_ids[numbered_buttons[i]] = ITEM_ID_INVALID; + return true; + } + } + + // didn't find a suitable button + return false; +} + + +template <unsigned M, unsigned N> +void xinput_device_base::assign_ui_actions( + input_device::assignment_vector &assignments, + unsigned preferred_back, + unsigned preferred_clear, + unsigned preferred_help, + unsigned start, + unsigned back, + input_item_id (&switch_ids)[M], + unsigned const (&numbered_buttons)[N], + unsigned button_count) +{ + // the first button is always UI select if present, or we can fall back to start + if (1U <= button_count) + { + add_button_assignment(assignments, IPT_UI_SELECT, { switch_ids[numbered_buttons[0]] }); + switch_ids[numbered_buttons[0]] = ITEM_ID_INVALID; + } + else if (add_button_assignment(assignments, IPT_UI_SELECT, { switch_ids[start] })) + { + switch_ids[start] = ITEM_ID_INVALID; + } + + // UI clear is usually X + assign_ui_button( + assignments, + IPT_UI_CLEAR, + preferred_clear, + switch_ids, + numbered_buttons, + button_count); + + // UI back can fall back from B to the back button + bool const assigned_back = assign_ui_button( + assignments, + IPT_UI_BACK, + preferred_back, + switch_ids, + numbered_buttons, + button_count); + if (!assigned_back) + { + if (add_button_assignment(assignments, IPT_UI_BACK, { switch_ids[back] })) + switch_ids[back] = ITEM_ID_INVALID; + } + + // help takes Y if present + assign_ui_button( + assignments, + IPT_UI_HELP, + preferred_help, + switch_ids, + numbered_buttons, + button_count); +} + + bool xinput_device_base::probe_extended_type() { switch (m_capabilities.Gamepad.sThumbLX) @@ -645,11 +755,6 @@ private: SWITCH_DPAD_LEFT, SWITCH_DPAD_RIGHT, - SWITCH_HAT_UP, // for flight stick with POV hat as right stick - SWITCH_HAT_DOWN, - SWITCH_HAT_LEFT, - SWITCH_HAT_RIGHT, - SWITCH_LT, // for arcade stick/pad with LT/RT buttons SWITCH_RT, @@ -666,12 +771,21 @@ private: AXIS_RSX, AXIS_RSY, - AXIS_RUDDER, // LT/RT mapped differently for flight sticks - AXIS_THROTTLE, - AXIS_TOTAL }; + static bool assign_pedal( + input_device::assignment_vector &assignments, + bool fallback_shoulder, + ioport_type type, + input_item_id preferred_axis, + input_item_id fallback_axis1, + input_item_id fallback_axis2, + input_item_modifier fallback_axis_modifier, + input_item_id trigger_button, + input_item_id shoulder_button, + input_item_id numbered_button); + u8 m_switches[SWITCH_TOTAL]; s32 m_axes[AXIS_TOTAL]; }; @@ -714,16 +828,6 @@ void xinput_joystick_device::poll() // translate LT/RT switches for arcade sticks/pads m_switches[SWITCH_LT] = (0x80 <= trigger_left()) ? 0xff : 0x00; m_switches[SWITCH_RT] = (0x80 <= trigger_right()) ? 0xff : 0x00; - - // translate POV hat for flight sticks - m_switches[SWITCH_HAT_UP] = (16'384 <= thumb_right_y()) ? 0xff : 0x00; - m_switches[SWITCH_HAT_DOWN] = (-16'384 >= thumb_right_y()) ? 0xff : 0x00; - m_switches[SWITCH_HAT_LEFT] = (-16'384 >= thumb_right_x()) ? 0xff : 0x00; - m_switches[SWITCH_HAT_RIGHT] = (16'384 <= thumb_right_x()) ? 0xff : 0x00; - - // translate rudder and throttle for flight sticks - m_axes[AXIS_RUDDER] = normalize_absolute_axis(trigger_left(), 0, 255); - m_axes[AXIS_THROTTLE] = normalize_absolute_axis(trigger_right(), 0, 255); } @@ -740,11 +844,11 @@ void xinput_joystick_device::configure(input_device &device) // TODO: proper support for dance mat controllers // default characteristics for a gamepad + bool button_diamond = true; + bool pedal_fallback_shoulder = true; bool lt_rt_button = false; - bool lt_rt_fullaxis = false; - bool rstick_hat = false; char const *const *axis_names = AXIS_NAMES_GAMEPAD; - input_item_id const *axis_ids = AXIS_IDS_GAMEPAD; + input_item_id const *preferred_axis_ids = AXIS_IDS_GAMEPAD; char const *const *hat_names = HAT_NAMES_GAMEPAD; char const *const *button_names = BUTTON_NAMES_GAMEPAD; @@ -755,47 +859,53 @@ void xinput_joystick_device::configure(input_device &device) switch (device_subtype()) { case XINPUT_DEVSUBTYPE_WHEEL: + pedal_fallback_shoulder = false; axis_names = AXIS_NAMES_WHEEL; break; case XINPUT_DEVSUBTYPE_ARCADE_STICK: + button_diamond = false; lt_rt_button = true; hat_names = HAT_NAMES_ARCADE_STICK; break; - case 0x04: // XINPUT_DEVSUBTYPE_FLIGHT_STICK: work around MinGW header issues - lt_rt_fullaxis = true; - rstick_hat = true; - axis_names = AXIS_NAMES_FLIGHT_STICK; - axis_ids = AXIS_IDS_FLIGHT_STICK; - break; case XINPUT_DEVSUBTYPE_DANCE_PAD: // TODO: proper support + button_diamond = false; break; case XINPUT_DEVSUBTYPE_ARCADE_PAD: + button_diamond = false; lt_rt_button = true; break; } break; } + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id axis_ids[AXIS_TOTAL]; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + // add bidirectional axes bool const axis_caps[]{ has_thumb_left_x(), has_thumb_left_y(), - !rstick_hat && has_thumb_right_x(), - !rstick_hat && has_thumb_right_y(), - lt_rt_fullaxis && has_trigger_left(), - lt_rt_fullaxis && has_trigger_right() }; + has_thumb_right_x(), + has_thumb_right_y() }; for (unsigned i = 0; std::size(axis_caps) > i; ++i) { if (axis_caps[i]) { - device.add_item( + axis_ids[AXIS_LSX + i] = device.add_item( axis_names[i], std::string_view(), - axis_ids[i], + preferred_axis_ids[i], generic_axis_get_state<s32>, &m_axes[AXIS_LSX + i]); } + else + { + axis_ids[AXIS_LSX + i] = ITEM_ID_INVALID; + } } // add hats @@ -803,16 +913,12 @@ void xinput_joystick_device::configure(input_device &device) has_button(XINPUT_GAMEPAD_DPAD_UP), has_button(XINPUT_GAMEPAD_DPAD_DOWN), has_button(XINPUT_GAMEPAD_DPAD_LEFT), - has_button(XINPUT_GAMEPAD_DPAD_RIGHT), - rstick_hat && has_thumb_right_x(), - rstick_hat && has_thumb_right_x(), - rstick_hat && has_thumb_right_y(), - rstick_hat && has_thumb_right_y() }; - for (unsigned i = 0; (SWITCH_HAT_RIGHT - SWITCH_DPAD_UP) >= i; ++i) + has_button(XINPUT_GAMEPAD_DPAD_RIGHT) }; + for (unsigned i = 0; (SWITCH_DPAD_RIGHT - SWITCH_DPAD_UP) >= i; ++i) { if (hat_caps[i]) { - device.add_item( + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( hat_names[i], std::string_view(), input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order @@ -834,56 +940,764 @@ void xinput_joystick_device::configure(input_device &device) { SWITCH_LSB, has_button(XINPUT_GAMEPAD_LEFT_THUMB) }, { SWITCH_RSB, has_button(XINPUT_GAMEPAD_RIGHT_THUMB) } }; input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_RSB - SWITCH_A + 1]; for (unsigned i = 0; std::size(button_caps) > i; ++i) { auto const [offset, supported] = button_caps[i]; if (supported) { - device.add_item( + switch_ids[offset] = device.add_item( button_names[i], std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[offset]); + numbered_buttons[button_count] = offset; + + // use these for automatically numbered buttons + assignments.emplace_back( + ioport_type(IPT_BUTTON1 + button_count++), + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[offset]))); } } // add start/back if (has_button(XINPUT_GAMEPAD_START)) { - device.add_item( + switch_ids[SWITCH_START] = device.add_item( "Start", std::string_view(), ITEM_ID_START, generic_button_get_state<u8>, &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); } if (has_button(XINPUT_GAMEPAD_BACK)) { - device.add_item( + switch_ids[SWITCH_BACK] = device.add_item( "Back", std::string_view(), ITEM_ID_SELECT, generic_button_get_state<u8>, &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); } // add triggers/pedals - if (!lt_rt_button && !lt_rt_fullaxis) + if (!lt_rt_button) { for (unsigned i = 0; (AXIS_RT - AXIS_LT) >= i; ++i) { if (i ? has_trigger_right() : has_trigger_left()) { - device.add_item( - axis_names[4 + i], + axis_ids[AXIS_LT + i] = device.add_item( + axis_names[std::size(axis_caps) + i], std::string_view(), - axis_ids[4 + i], + preferred_axis_ids[std::size(axis_caps) + i], generic_axis_get_state<s32>, &m_axes[AXIS_LT + i]); } + else + { + axis_ids[AXIS_LT + i] = ITEM_ID_INVALID; + } + } + } + + // try to get a "complete" joystick for primary movement controls + input_item_id directional_axes[2][2]; + choose_primary_stick( + directional_axes, + axis_ids[AXIS_LSX], + axis_ids[AXIS_LSY], + axis_ids[AXIS_RSX], + axis_ids[AXIS_RSY]); + + // now set up controls using the primary joystick + add_directional_assignments( + assignments, + directional_axes[0][0], + directional_axes[0][1], + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN]); + + // assign a secondary stick axis to joystick Z if available + bool const stick_z = add_assignment( + assignments, + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NONE, + { directional_axes[1][1], directional_axes[1][0] }); + if (!stick_z) + { + // if both triggers are present, combine them, or failing that, fall back to a pair of buttons + if ((ITEM_ID_INVALID != axis_ids[AXIS_LT]) && (ITEM_ID_INVALID != axis_ids[AXIS_RT])) + { + assignments.emplace_back( + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + input_seq( + make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, axis_ids[AXIS_LT]), + make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_REVERSE, axis_ids[AXIS_RT]))); + } + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, switch_ids[SWITCH_LB], switch_ids[SWITCH_RB])) + { + // took shoulder buttons + } + else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, switch_ids[SWITCH_LT], switch_ids[SWITCH_RT])) + { + // took trigger buttons + } + } + + // prefer trigger axes for pedals, otherwise take half axes and buttons + unsigned pedal_button = 0; + bool const pedal1_numbered_button = assign_pedal( + assignments, + pedal_fallback_shoulder, + IPT_PEDAL, + axis_ids[AXIS_RT], + directional_axes[1][1], + directional_axes[0][1], + ITEM_MODIFIER_NEG, + switch_ids[SWITCH_RT], + switch_ids[SWITCH_RB], + (pedal_button < button_count) + ? switch_ids[numbered_buttons[pedal_button]] + : ITEM_ID_INVALID); + if (pedal1_numbered_button) + ++pedal_button; + bool const pedal2_numbered_button = assign_pedal( + assignments, + pedal_fallback_shoulder, + IPT_PEDAL2, + axis_ids[AXIS_LT], + directional_axes[1][1], + directional_axes[0][1], + ITEM_MODIFIER_POS, + switch_ids[SWITCH_LT], + switch_ids[SWITCH_LB], + (pedal_button < button_count) + ? switch_ids[numbered_buttons[pedal_button]] + : ITEM_ID_INVALID); + if (pedal2_numbered_button) + ++pedal_button; + if (pedal_button < button_count) + { + input_item_id const pedal_button_id = switch_ids[numbered_buttons[pedal_button]]; + assignments.emplace_back( + IPT_PEDAL3, + SEQ_TYPE_INCREMENT, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, pedal_button_id))); + } + + // potentially use thumb sticks and/or D-pad and A/B/X/Y diamond for twin sticks + add_twin_stick_assignments( + assignments, + axis_ids[AXIS_LSX], + axis_ids[AXIS_LSY], + axis_ids[AXIS_RSX], + axis_ids[AXIS_RSY], + button_diamond ? switch_ids[SWITCH_DPAD_LEFT] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_DPAD_RIGHT] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_DPAD_UP] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_DPAD_DOWN] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_X] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_B] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_Y] : ITEM_ID_INVALID, + button_diamond ? switch_ids[SWITCH_A] : ITEM_ID_INVALID); + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + button_count); + + // try to get a matching pair of buttons for previous/next group + if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_LT], switch_ids[SWITCH_RT])) + { + // took digital triggers + } + else if (consume_trigger_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axis_ids[AXIS_LT], axis_ids[AXIS_RT])) + { + // took analog triggers + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, directional_axes[1][1])) + { + // took secondary Y + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, directional_axes[1][0])) + { + // took secondary X + } + + // try to assign secondary stick to page up/down + consume_axis_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, directional_axes[1][1]); + + // put focus previous/next on the shoulder buttons if available - this can be overloaded with zoom + if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_LB], switch_ids[SWITCH_RB])) + { + // took shoulder buttons + } + else if (add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, directional_axes[1][0])) + { + // took secondary X + } + + // put zoom on the secondary stick if available, or fall back to shoulder buttons + if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, directional_axes[1][0])) + { + // took secondary X + if (axis_ids[AXIS_LSX] == directional_axes[1][0]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { switch_ids[SWITCH_LSB] }); + else if (axis_ids[AXIS_RSX] == directional_axes[1][0]) + add_button_assignment(assignments, IPT_UI_ZOOM_DEFAULT, { switch_ids[SWITCH_RSB] }); + directional_axes[1][0] = ITEM_ID_INVALID; + } + else if (consume_button_pair(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_LB], switch_ids[SWITCH_RB])) + { + // took shoulder buttons + } + + // set default assignments + device.set_default_assignments(std::move(assignments)); +} + + +bool xinput_joystick_device::assign_pedal( + input_device::assignment_vector &assignments, + bool fallback_shoulder, + ioport_type type, + input_item_id preferred_axis, + input_item_id fallback_axis1, + input_item_id fallback_axis2, + input_item_modifier fallback_axis_modifier, + input_item_id trigger_button, + input_item_id shoulder_button, + input_item_id numbered_button) +{ + // first try the preferred trigger/pedal axis + if (ITEM_ID_INVALID != preferred_axis) + { + assignments.emplace_back( + type, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, preferred_axis))); + return false; + } + + // try adding half a joystick axis + add_assignment( + assignments, + type, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + fallback_axis_modifier, + { fallback_axis1, fallback_axis2 }); + + // try a trigger button + if (ITEM_ID_INVALID != trigger_button) + { + assignments.emplace_back( + type, + SEQ_TYPE_INCREMENT, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, trigger_button))); + return false; + } + + // try a shoulder button if appropriate + if (fallback_shoulder && (ITEM_ID_INVALID != shoulder_button)) + { + assignments.emplace_back( + type, + SEQ_TYPE_INCREMENT, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, shoulder_button))); + return false; + } + + // if no numbered button, nothing can be done + if (ITEM_ID_INVALID == numbered_button) + return false; + + // last resort + assignments.emplace_back( + type, + SEQ_TYPE_INCREMENT, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, numbered_button))); + return true; +} + + + +//============================================================ +// XInput flight stick handler +//============================================================ + +class xinput_flight_stick_device : public xinput_device_base +{ +public: + xinput_flight_stick_device( + std::string &&name, + std::string &&id, + input_module &module, + u32 player, + XINPUT_CAPABILITIES const &caps, + xinput_api_helper const &helper); + + virtual void poll() override; + virtual void reset() override; + virtual void configure(input_device &device) override; + +private: + static inline constexpr USHORT SWITCH_BITS[] = + { + XINPUT_GAMEPAD_A, + XINPUT_GAMEPAD_B, + XINPUT_GAMEPAD_X, + XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_LEFT_SHOULDER, + XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_LEFT_THUMB, + XINPUT_GAMEPAD_RIGHT_THUMB, + XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, + + XINPUT_GAMEPAD_DPAD_UP, + XINPUT_GAMEPAD_DPAD_DOWN, + XINPUT_GAMEPAD_DPAD_LEFT, + XINPUT_GAMEPAD_DPAD_RIGHT + }; + + enum + { + SWITCH_A, // button bits + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_LB, + SWITCH_RB, + SWITCH_LSB, + SWITCH_RSB, + SWITCH_START, + SWITCH_BACK, + + SWITCH_DPAD_UP, // D-pad bits + SWITCH_DPAD_DOWN, + SWITCH_DPAD_LEFT, + SWITCH_DPAD_RIGHT, + + SWITCH_HAT_UP, // for POV hat as right stick + SWITCH_HAT_DOWN, + SWITCH_HAT_LEFT, + SWITCH_HAT_RIGHT, + + SWITCH_TOTAL + }; + + enum + { + AXIS_RUDDER, // LT/RT mapped as bidirectional axes + AXIS_THROTTLE, + + AXIS_X, // full-precision axes + AXIS_Y, + + AXIS_TOTAL + }; + + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; +}; + + +xinput_flight_stick_device::xinput_flight_stick_device( + std::string &&name, + std::string &&id, + input_module &module, + u32 player, + XINPUT_CAPABILITIES const &caps, + xinput_api_helper const &helper) : + xinput_device_base(std::move(name), std::move(id), module, player, caps, helper) +{ + std::fill(std::begin(m_switches), std::end(m_switches), 0); + std::fill(std::begin(m_axes), std::end(m_axes), 0); +} + + +void xinput_flight_stick_device::poll() +{ + // poll the device first, and skip if nothing changed + if (!read_state()) + return; + + // translate button bits + for (unsigned i = 0; std::size(SWITCH_BITS) > i; ++i) + m_switches[SWITCH_A + i] = (buttons() & SWITCH_BITS[i]) ? 0xff : 0x00; + + // translate rudder and throttle + m_axes[AXIS_RUDDER] = normalize_absolute_axis(trigger_left(), 0, 255); + m_axes[AXIS_THROTTLE] = normalize_absolute_axis(trigger_right(), 0, 255); + + // translate full-precision axes - Y direction is opposite to what MAME uses + m_axes[AXIS_X] = normalize_absolute_axis(thumb_left_x(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); + m_axes[AXIS_Y] = normalize_absolute_axis(-thumb_left_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); + + // translate right stick as POV hat + m_switches[SWITCH_HAT_UP] = (16'384 <= thumb_right_y()) ? 0xff : 0x00; + m_switches[SWITCH_HAT_DOWN] = (-16'384 >= thumb_right_y()) ? 0xff : 0x00; + m_switches[SWITCH_HAT_LEFT] = (-16'384 >= thumb_right_x()) ? 0xff : 0x00; + m_switches[SWITCH_HAT_RIGHT] = (16'384 <= thumb_right_x()) ? 0xff : 0x00; +} + + +void xinput_flight_stick_device::reset() +{ + set_reset(); + std::fill(std::begin(m_switches), std::end(m_switches), 0); + std::fill(std::begin(m_axes), std::end(m_axes), 0); +} + + +void xinput_flight_stick_device::configure(input_device &device) +{ + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + + // add bidirectional axes + std::tuple<input_item_id, char const *, bool> const axis_caps[]{ + { ITEM_ID_RZAXIS, "Rudder", has_trigger_left() }, + { ITEM_ID_ZAXIS, "Throttle", has_trigger_right() }, + { ITEM_ID_XAXIS, "Joystick X", has_thumb_left_x() }, + { ITEM_ID_YAXIS, "Joystick Y", has_thumb_left_y() } }; + input_item_id axis_ids[AXIS_TOTAL]; + for (unsigned i = 0; AXIS_TOTAL > i; ++i) + { + auto const [id, name, supported] = axis_caps[i]; + if (supported) + { + axis_ids[i] = device.add_item( + name, + std::string_view(), + id, + generic_axis_get_state<s32>, + &m_axes[i]); + } + else + { + axis_ids[i] = ITEM_ID_INVALID; + } + } + + // add hats + bool const hat_caps[]{ + has_button(XINPUT_GAMEPAD_DPAD_UP), + has_button(XINPUT_GAMEPAD_DPAD_DOWN), + has_button(XINPUT_GAMEPAD_DPAD_LEFT), + has_button(XINPUT_GAMEPAD_DPAD_RIGHT), + has_thumb_right_x(), + has_thumb_right_x(), + has_thumb_right_y(), + has_thumb_right_y() }; + for (unsigned i = 0; (SWITCH_HAT_RIGHT - SWITCH_DPAD_UP) >= i; ++i) + { + if (hat_caps[i]) + { + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( + HAT_NAMES_GAMEPAD[i], + std::string_view(), + input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order + generic_button_get_state<u8>, + &m_switches[SWITCH_DPAD_UP + i]); + } + } + + // add buttons + input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_RSB - SWITCH_A + 1]; + for (unsigned i = 0; (SWITCH_RSB - SWITCH_A) >= i; ++i) + { + if (has_button(SWITCH_BITS[i])) + { + switch_ids[SWITCH_A + i] = device.add_item( + BUTTON_NAMES_FLIGHT_STICK[i], + std::string_view(), + button_id++, + generic_button_get_state<u8>, + &m_switches[SWITCH_A + i]); + numbered_buttons[button_count] = SWITCH_A + i; + + // use these for automatically numbered buttons and pedals + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_A + i])); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button_count), SEQ_TYPE_STANDARD, seq); + if (3 > button_count) + assignments.emplace_back(ioport_type(IPT_PEDAL + button_count), SEQ_TYPE_INCREMENT, seq); + ++button_count; + } + } + + // add start/back + if (has_button(XINPUT_GAMEPAD_START)) + { + switch_ids[SWITCH_START] = device.add_item( + "Start", + std::string_view(), + ITEM_ID_START, + generic_button_get_state<u8>, + &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); + } + if (has_button(XINPUT_GAMEPAD_BACK)) + { + switch_ids[SWITCH_BACK] = device.add_item( + "Back", + std::string_view(), + ITEM_ID_SELECT, + generic_button_get_state<u8>, + &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); + } + + // use throttle for joystick Z, or rudder if it isn't available + add_assignment( + assignments, + IPT_AD_STICK_Z, + SEQ_TYPE_STANDARD, + ITEM_CLASS_ABSOLUTE, + ITEM_MODIFIER_NONE, + { axis_ids[AXIS_THROTTLE], axis_ids[AXIS_RUDDER] }); + + // if throttle is available, use it for first two pedals, too + if (ITEM_ID_INVALID != axis_ids[AXIS_THROTTLE]) + { + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, axis_ids[AXIS_THROTTLE]))); + assignments.emplace_back( + IPT_PEDAL2, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, axis_ids[AXIS_THROTTLE]))); + } + + // find something to use for directional controls and navigation + bool const axis_missing = (ITEM_ID_INVALID == axis_ids[AXIS_X]) || (ITEM_ID_INVALID == axis_ids[AXIS_Y]); + bool const hat_complete = has_thumb_right_x() && has_thumb_right_y(); + if (axis_missing && hat_complete) + { + // X or Y missing - rely on POV hat + add_directional_assignments( + assignments, + axis_ids[AXIS_X], + axis_ids[AXIS_Y], + switch_ids[SWITCH_HAT_LEFT], + switch_ids[SWITCH_HAT_RIGHT], + switch_ids[SWITCH_HAT_UP], + switch_ids[SWITCH_HAT_DOWN]); + + // choose something for previous/next group + if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axis_ids[AXIS_RUDDER])) + { + // took rudder + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axis_ids[AXIS_THROTTLE])) + { + // took throttle + } + + // choose something for zoom and focus previous/next + if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, axis_ids[AXIS_THROTTLE])) + { + if (!add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, axis_ids[AXIS_RUDDER])) + add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, axis_ids[AXIS_THROTTLE]); + } + else if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, axis_ids[AXIS_RUDDER])) + { + add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, axis_ids[AXIS_RUDDER]); + } + else if (add_button_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + consume_button_pair(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT]); + } + } + else + { + // only use stick for the primary directional controls + add_directional_assignments( + assignments, + axis_ids[AXIS_X], + axis_ids[AXIS_Y], + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID); + + // assign the POV hat differently depending on whether rudder and/or throttle are present + if ((ITEM_ID_INVALID != axis_ids[AXIS_RUDDER]) || (ITEM_ID_INVALID != axis_ids[AXIS_THROTTLE])) + { + // previous/next group + if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_HAT_LEFT], switch_ids[SWITCH_HAT_RIGHT])) + { + // took hat left/right + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_HAT_UP], switch_ids[SWITCH_HAT_DOWN])) + { + // took hat up/down + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axis_ids[AXIS_RUDDER])) + { + // took rudder + } + else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axis_ids[AXIS_THROTTLE])) + { + // took throttle + } + + // page up/down + if (consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, switch_ids[SWITCH_HAT_UP], switch_ids[SWITCH_HAT_DOWN])) + { + // took hat up/down + } + else if (consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + + // home/end + if (consume_button_pair(assignments, IPT_UI_HOME, IPT_UI_END, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_button_pair(assignments, IPT_UI_HOME, IPT_UI_END, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + + // assign something for zoom - this can overlap with focus previous/next + if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, axis_ids[AXIS_THROTTLE])) + { + // took throttle + } + else if (add_button_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + else if (add_axis_pair_assignment(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, axis_ids[AXIS_RUDDER])) + { + // took rudder + } + + // assign something for focus previous/next + if (add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, axis_ids[AXIS_RUDDER])) + { + // took rudder + } + else if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + else if (add_axis_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, axis_ids[AXIS_THROTTLE])) + { + // took throttle + } + } + else + { + // previous/next group + if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_HAT_UP], switch_ids[SWITCH_HAT_DOWN])) + { + // took hat up/down + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_HAT_LEFT], switch_ids[SWITCH_HAT_RIGHT])) + { + // took hat left/right + } + else if (consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + + // try to choose something for focus previous/next + if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_HAT_LEFT], switch_ids[SWITCH_HAT_RIGHT])) + { + // took hat left/right - use it for zoom as well + consume_button_pair(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_HAT_LEFT], switch_ids[SWITCH_HAT_RIGHT]); + } + else if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right - use it for zoom as well + consume_button_pair(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT]); + } + else if (add_button_pair_assignment(assignments, IPT_UI_FOCUS_PREV, IPT_UI_FOCUS_NEXT, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad left/right - use it for zoom as well + consume_button_pair(assignments, IPT_UI_ZOOM_OUT, IPT_UI_ZOOM_IN, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN]); + } + + // use D-pad for page up/down and home/end if it's still available + if (consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, switch_ids[SWITCH_DPAD_UP], switch_ids[SWITCH_DPAD_DOWN])) + { + // took D-pad up/down + } + else if (consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT])) + { + // took D-pad left/right + } + consume_button_pair(assignments, IPT_UI_HOME, IPT_UI_END, switch_ids[SWITCH_DPAD_LEFT], switch_ids[SWITCH_DPAD_RIGHT]); } } + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + button_count); + + // set default assignments + device.set_default_assignments(std::move(assignments)); } @@ -1019,6 +1833,11 @@ void xinput_guitar_device::configure(input_device &device) { // TODO: does subtype 0x06 indicate digital neck orientation sensor or lack of three-axis accelerometer? + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + // add axes std::tuple<input_item_id, char const *, bool> const axis_caps[]{ { ITEM_ID_RXAXIS, "Neck Slider", has_thumb_left_x() }, @@ -1028,17 +1847,22 @@ void xinput_guitar_device::configure(input_device &device) { ITEM_ID_XAXIS, "Bridge Orientation", has_trigger_left() && has_trigger_right() }, { ITEM_ID_ZAXIS, "Body Orientation", has_trigger_right() }, { ITEM_ID_SLIDER2, "Pickup Selector", has_trigger_left() && !has_trigger_right() } }; - for (unsigned i = 0; (AXIS_PICKUP - AXIS_SLIDER) >= i; ++i) + input_item_id axis_ids[AXIS_TOTAL]; + for (unsigned i = 0; AXIS_TOTAL > i; ++i) { auto const [item, name, supported] = axis_caps[i]; if (supported) { - device.add_item( + axis_ids[i] = device.add_item( name, std::string_view(), item, generic_axis_get_state<s32>, - &m_axes[AXIS_SLIDER + i]); + &m_axes[i]); + } + else + { + axis_ids[i] = ITEM_ID_INVALID; } } @@ -1047,7 +1871,7 @@ void xinput_guitar_device::configure(input_device &device) { if (has_button(SWITCH_BITS[SWITCH_DPAD_UP + i])) { - device.add_item( + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( HAT_NAMES_GUITAR[i], std::string_view(), input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order @@ -1058,38 +1882,107 @@ void xinput_guitar_device::configure(input_device &device) // add buttons input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_FRET5 - SWITCH_FRET1 + 1]; for (unsigned i = 0; (SWITCH_RSB - SWITCH_FRET1) >= i; ++i) { if (has_button(SWITCH_BITS[i])) { - device.add_item( + switch_ids[SWITCH_FRET1 + i] = device.add_item( BUTTON_NAMES_GUITAR[i], std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[SWITCH_FRET1 + i]); + + // use fret buttons for automatically numbered buttons and pedals + if ((SWITCH_FRET5 - SWITCH_FRET1) >= i) + { + numbered_buttons[button_count] = SWITCH_FRET1 + i; + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_FRET1 + i])); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button_count), SEQ_TYPE_STANDARD, seq); + if (((ITEM_ID_INVALID != axis_ids[AXIS_WHAMMY]) ? 2 : 3) > button_count) + { + ioport_type const first_pedal = (ITEM_ID_INVALID != axis_ids[AXIS_WHAMMY]) + ? IPT_PEDAL2 + : IPT_PEDAL; + assignments.emplace_back( + ioport_type(first_pedal + button_count), + SEQ_TYPE_INCREMENT, + seq); + } + ++button_count; + } } } // add start/back if (has_button(XINPUT_GAMEPAD_START)) { - device.add_item( + switch_ids[SWITCH_START] = device.add_item( "Start", std::string_view(), ITEM_ID_START, generic_button_get_state<u8>, &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); } if (has_button(XINPUT_GAMEPAD_BACK)) { - device.add_item( + switch_ids[SWITCH_BACK] = device.add_item( "Back", std::string_view(), ITEM_ID_SELECT, generic_button_get_state<u8>, &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); } + + // use the D-pad for directional controls - accelerometers are an annoyance + add_directional_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN]); + + // use the whammy bar for the first pedal and focus next if present + if (ITEM_ID_INVALID != axis_ids[AXIS_WHAMMY]) + { + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, axis_ids[AXIS_WHAMMY]))); + assignments.emplace_back( + IPT_UI_FOCUS_NEXT, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axis_ids[AXIS_WHAMMY]))); + } + + // use the neck slider for a couple of things if it's present + if (ITEM_ID_INVALID != axis_ids[AXIS_SLIDER]) + { + input_seq const seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, axis_ids[AXIS_SLIDER])); + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_STANDARD, seq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_STANDARD, seq); + } + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_FRET2, + SWITCH_FRET3, + SWITCH_FRET4, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + button_count); + + // set default assignments + device.set_default_assignments(std::move(assignments)); } @@ -1215,6 +2108,11 @@ void xinput_drumkit_device::reset() void xinput_drumkit_device::configure(input_device &device) { + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + // add axes std::tuple<input_item_id, char const *, bool> const axis_caps[]{ { ITEM_ID_XAXIS, "Green Velocity", has_thumb_left_y() }, @@ -1242,7 +2140,7 @@ void xinput_drumkit_device::configure(input_device &device) { if (has_button(SWITCH_BITS[SWITCH_DPAD_UP + i])) { - device.add_item( + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( HAT_NAMES_GAMEPAD[i], std::string_view(), input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order @@ -1252,39 +2150,95 @@ void xinput_drumkit_device::configure(input_device &device) } // add buttons - input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_RSB - SWITCH_GREEN + 1]; for (unsigned i = 0; (SWITCH_RSB - SWITCH_GREEN) >= i; ++i) { if (has_button(SWITCH_BITS[i])) { - device.add_item( + switch_ids[SWITCH_GREEN + i] = device.add_item( BUTTON_NAMES_DRUMKIT[i], std::string_view(), - button_id++, + input_item_id(ITEM_ID_BUTTON1 + button_count), generic_button_get_state<u8>, &m_switches[SWITCH_GREEN + i]); + numbered_buttons[button_count] = SWITCH_GREEN + i; + + // use these for automatically numbered buttons and pedals + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_GREEN + i])); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button_count), SEQ_TYPE_STANDARD, seq); + if (3 > button_count) + assignments.emplace_back(ioport_type(IPT_PEDAL + button_count), SEQ_TYPE_INCREMENT, seq); + ++button_count; } } // add start/back if (has_button(XINPUT_GAMEPAD_START)) { - device.add_item( + switch_ids[SWITCH_START] = device.add_item( "Start", std::string_view(), ITEM_ID_START, generic_button_get_state<u8>, &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); } if (has_button(XINPUT_GAMEPAD_BACK)) { - device.add_item( + switch_ids[SWITCH_BACK] = device.add_item( "Back", std::string_view(), ITEM_ID_SELECT, generic_button_get_state<u8>, &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); } + + // use the D-pad for directional controls + add_directional_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN]); + + // use the D-pad and A/B/X/Y diamond for twin sticks + add_twin_stick_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN], + switch_ids[SWITCH_BLUE], + switch_ids[SWITCH_RED], + switch_ids[SWITCH_YELLOW], + switch_ids[SWITCH_GREEN]); + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_RED, + SWITCH_BLUE, + SWITCH_YELLOW, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + button_count); + + // use bass drum pedal for focus next if available to make the system selection menu usable + if (add_button_assignment(assignments, IPT_UI_FOCUS_NEXT, { switch_ids[SWITCH_BASS_DRUM] })) + switch_ids[SWITCH_BASS_DRUM] = ITEM_ID_INVALID; + + // set default assignments + device.set_default_assignments(std::move(assignments)); } @@ -1432,20 +2386,25 @@ void xinput_turntable_device::reset() void xinput_turntable_device::configure(input_device &device) { + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + // add axes - device.add_item( + input_item_id const turntable_id = device.add_item( "Turntable", std::string_view(), ITEM_ID_ADD_RELATIVE1, generic_axis_get_state<s32>, &m_axes[AXIS_TURNTABLE]); - device.add_item( + input_item_id const effect_id = device.add_item( "Effect", std::string_view(), ITEM_ID_ADD_RELATIVE2, generic_axis_get_state<s32>, &m_axes[AXIS_EFFECT]); - device.add_item( + input_item_id const crossfade_id = device.add_item( "Crossfade", std::string_view(), ITEM_ID_XAXIS, @@ -1457,7 +2416,7 @@ void xinput_turntable_device::configure(input_device &device) { if (has_button(SWITCH_BITS[SWITCH_DPAD_UP + i])) { - device.add_item( + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( HAT_NAMES_GAMEPAD[i], std::string_view(), input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order @@ -1468,31 +2427,43 @@ void xinput_turntable_device::configure(input_device &device) // add buttons input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_RSB - SWITCH_A + 1]; for (unsigned i = 0; (SWITCH_RSB - SWITCH_A) >= i; ++i) { if (has_button(SWITCH_BITS[i])) { - device.add_item( + switch_ids[SWITCH_A + i] = device.add_item( BUTTON_NAMES_KEYBOARD[i], std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[SWITCH_A + i]); + numbered_buttons[button_count] = SWITCH_A + i; + + // use these for automatically numbered buttons and pedals + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_A + i])); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button_count), SEQ_TYPE_STANDARD, seq); + if (3 > button_count) + assignments.emplace_back(ioport_type(IPT_PEDAL + button_count), SEQ_TYPE_INCREMENT, seq); + ++button_count; } } - device.add_item( + + // turntable buttons activate these as well as A/B/X + switch_ids[SWITCH_GREEN] = device.add_item( "Green", std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[SWITCH_GREEN]); - device.add_item( + switch_ids[SWITCH_RED] = device.add_item( "Red", std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[SWITCH_RED]); - device.add_item( + switch_ids[SWITCH_BLUE] = device.add_item( "Blue", std::string_view(), button_id++, @@ -1502,22 +2473,197 @@ void xinput_turntable_device::configure(input_device &device) // add start/back if (has_button(XINPUT_GAMEPAD_START)) { - device.add_item( + switch_ids[SWITCH_START] = device.add_item( "Start", std::string_view(), ITEM_ID_START, generic_button_get_state<u8>, &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); } if (has_button(XINPUT_GAMEPAD_BACK)) { - device.add_item( + switch_ids[SWITCH_BACK] = device.add_item( "Back", std::string_view(), ITEM_ID_SELECT, generic_button_get_state<u8>, &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); + } + + // use D-pad and A/B/X/Y diamond for twin sticks + add_twin_stick_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN], + switch_ids[SWITCH_X], + switch_ids[SWITCH_B], + switch_ids[SWITCH_Y], + switch_ids[SWITCH_A]); + + // for most analog player controls, use turntable for X and effect for Y + input_seq const turntable_seq(make_code(ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, turntable_id)); + input_seq const effect_seq(make_code(ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, effect_id)); + input_seq const crossfade_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, crossfade_id)); + input_seq joystick_left_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, turntable_id)); + input_seq joystick_right_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, turntable_id)); + input_seq joystick_up_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, effect_id)); + input_seq joystick_down_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, effect_id)); + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_STANDARD, crossfade_seq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_AD_STICK_Z, SEQ_TYPE_STANDARD, crossfade_seq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_STANDARD, effect_seq); + assignments.emplace_back(IPT_MOUSE_X, SEQ_TYPE_STANDARD, turntable_seq); + assignments.emplace_back(IPT_MOUSE_Y, SEQ_TYPE_STANDARD, effect_seq); + + // use D-pad for analog controls as well if present + bool const have_dpad_left = ITEM_ID_INVALID != switch_ids[SWITCH_DPAD_LEFT]; + bool const have_dpad_right = ITEM_ID_INVALID != switch_ids[SWITCH_DPAD_RIGHT]; + bool const have_dpad_up = ITEM_ID_INVALID != switch_ids[SWITCH_DPAD_UP]; + bool const have_dpad_down = ITEM_ID_INVALID != switch_ids[SWITCH_DPAD_DOWN]; + if (have_dpad_left) + { + input_code const code(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_LEFT])); + input_seq const left_seq(code); + joystick_left_seq += input_seq::or_code; + joystick_left_seq += code; + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_DECREMENT, left_seq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_DECREMENT, left_seq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_DECREMENT, left_seq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_DECREMENT, left_seq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_DECREMENT, left_seq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_DECREMENT, left_seq); + } + if (have_dpad_right) + { + input_code const code(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_RIGHT])); + input_seq const right_seq(code); + joystick_right_seq += input_seq::or_code; + joystick_right_seq += code; + assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_INCREMENT, right_seq); + assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_INCREMENT, right_seq); + assignments.emplace_back(IPT_DIAL, SEQ_TYPE_INCREMENT, right_seq); + assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_INCREMENT, right_seq); + assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_INCREMENT, right_seq); + assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_INCREMENT, right_seq); + } + if (have_dpad_up) + { + input_code const code(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_UP])); + input_seq const up_seq(code); + joystick_up_seq += input_seq::or_code; + joystick_up_seq += code; + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_DECREMENT, up_seq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_DECREMENT, up_seq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_DECREMENT, up_seq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_DECREMENT, up_seq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_DECREMENT, up_seq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_DECREMENT, up_seq); + } + if (have_dpad_down) + { + input_code const code(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_DOWN])); + input_seq const down_seq(code); + joystick_down_seq += input_seq::or_code; + joystick_down_seq += code; + assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_INCREMENT, down_seq); + assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_INCREMENT, down_seq); + assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_INCREMENT, down_seq); + assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_INCREMENT, down_seq); + assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_INCREMENT, down_seq); + assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_INCREMENT, down_seq); + } + assignments.emplace_back(IPT_JOYSTICK_LEFT, SEQ_TYPE_STANDARD, joystick_left_seq); + assignments.emplace_back(IPT_JOYSTICK_RIGHT, SEQ_TYPE_STANDARD, joystick_right_seq); + assignments.emplace_back(IPT_JOYSTICK_UP, SEQ_TYPE_STANDARD, joystick_up_seq); + assignments.emplace_back(IPT_JOYSTICK_DOWN, SEQ_TYPE_STANDARD, joystick_down_seq); + + // choose navigation controls + input_seq ui_up_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, turntable_id)); + input_seq ui_down_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, turntable_id)); + input_seq ui_left_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, effect_id)); + input_seq ui_right_seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, effect_id)); + if ((have_dpad_up && have_dpad_down) || !have_dpad_left || !have_dpad_right) + { + if (have_dpad_up) + { + ui_up_seq += input_seq::or_code; + ui_up_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_UP]); + } + if (have_dpad_down) + { + ui_down_seq += input_seq::or_code; + ui_down_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_DOWN]); + } + if (have_dpad_left) + { + ui_left_seq += input_seq::or_code; + ui_left_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_LEFT]); + } + if (have_dpad_right) + { + ui_right_seq += input_seq::or_code; + ui_right_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_RIGHT]); + } } + else + { + if (have_dpad_left) + { + ui_up_seq += input_seq::or_code; + ui_up_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_LEFT]); + } + if (have_dpad_right) + { + ui_down_seq += input_seq::or_code; + ui_down_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_RIGHT]); + } + if (have_dpad_up) + { + ui_left_seq += input_seq::or_code; + ui_left_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_UP]); + } + if (have_dpad_down) + { + ui_right_seq += input_seq::or_code; + ui_right_seq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_DPAD_DOWN]); + } + } + assignments.emplace_back(IPT_UI_UP, SEQ_TYPE_STANDARD, ui_up_seq); + assignments.emplace_back(IPT_UI_DOWN, SEQ_TYPE_STANDARD, ui_down_seq); + assignments.emplace_back(IPT_UI_LEFT, SEQ_TYPE_STANDARD, ui_left_seq); + assignments.emplace_back(IPT_UI_RIGHT, SEQ_TYPE_STANDARD, ui_right_seq); + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + std::min<unsigned>(button_count, 4)); + + // set default assignments + device.set_default_assignments(std::move(assignments)); } @@ -1650,6 +2796,11 @@ void xinput_keyboard_device::reset() void xinput_keyboard_device::configure(input_device &device) { + // track item IDs for setting up default assignments + input_device::assignment_vector assignments; + input_item_id switch_ids[SWITCH_TOTAL]; + std::fill(std::begin(switch_ids), std::end(switch_ids), ITEM_ID_INVALID); + // add axes device.add_item( "Velocity", @@ -1657,19 +2808,23 @@ void xinput_keyboard_device::configure(input_device &device) ITEM_ID_SLIDER1, generic_axis_get_state<s32>, &m_axes[AXIS_VELOCITY]); - device.add_item( + input_item_id const pedal_id = device.add_item( "Pedal", std::string_view(), ITEM_ID_SLIDER2, generic_axis_get_state<s32>, &m_axes[AXIS_PEDAL]); + assignments.emplace_back( + IPT_PEDAL, + SEQ_TYPE_STANDARD, + input_seq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, pedal_id))); // add hats for (unsigned i = 0; (SWITCH_DPAD_RIGHT - SWITCH_DPAD_UP) >= i; ++i) { if (has_button(SWITCH_BITS[SWITCH_DPAD_UP + i])) { - device.add_item( + switch_ids[SWITCH_DPAD_UP + i] = device.add_item( HAT_NAMES_GAMEPAD[i], std::string_view(), input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order @@ -1680,51 +2835,137 @@ void xinput_keyboard_device::configure(input_device &device) // add buttons input_item_id button_id = ITEM_ID_BUTTON1; + unsigned button_count = 0; + unsigned numbered_buttons[SWITCH_RSB - SWITCH_A + 1]; for (unsigned i = 0; (SWITCH_RSB - SWITCH_A) >= i; ++i) { if (has_button(SWITCH_BITS[i])) { - device.add_item( + switch_ids[SWITCH_A + i] = device.add_item( BUTTON_NAMES_KEYBOARD[i], std::string_view(), button_id++, generic_button_get_state<u8>, &m_switches[SWITCH_A + i]); + numbered_buttons[button_count] = SWITCH_A + i; + + // use these for automatically numbered buttons and pedals + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_A + i])); + assignments.emplace_back(ioport_type(IPT_BUTTON1 + button_count), SEQ_TYPE_STANDARD, seq); + if (3 > button_count) + assignments.emplace_back(ioport_type(IPT_PEDAL + button_count), SEQ_TYPE_INCREMENT, seq); + ++button_count; } } // add keys char const *const key_formats[]{ "C %d", "C# %d", "D %d", "D# %d", "E %d", "F %d", "F# %d", "G %d", "G# %d", "A %d", "A# %d", "B %d" }; + std::pair<ioport_type, ioport_type> const key_ids[]{ + { IPT_MAHJONG_A, IPT_HANAFUDA_A }, // C + { IPT_MAHJONG_SCORE, IPT_INVALID }, // C# + { IPT_MAHJONG_B, IPT_HANAFUDA_B }, // D + { IPT_MAHJONG_DOUBLE_UP, IPT_INVALID }, // D# + { IPT_MAHJONG_C, IPT_HANAFUDA_C }, // E + { IPT_MAHJONG_D, IPT_HANAFUDA_D }, // F + { IPT_MAHJONG_BIG, IPT_INVALID }, // F# + { IPT_MAHJONG_E, IPT_HANAFUDA_E }, // G + { IPT_MAHJONG_SMALL, IPT_INVALID }, // G# + { IPT_MAHJONG_F, IPT_HANAFUDA_F }, // A + { IPT_MAHJONG_LAST_CHANCE, IPT_INVALID }, // A# + { IPT_MAHJONG_G, IPT_HANAFUDA_G }, // B + { IPT_MAHJONG_H, IPT_HANAFUDA_H }, // C + { IPT_MAHJONG_KAN, IPT_INVALID }, // C# + { IPT_MAHJONG_I, IPT_INVALID }, // D + { IPT_MAHJONG_PON, IPT_INVALID }, // D# + { IPT_MAHJONG_J, IPT_INVALID }, // E + { IPT_MAHJONG_K, IPT_INVALID }, // F + { IPT_MAHJONG_CHI, IPT_INVALID }, // F# + { IPT_MAHJONG_L, IPT_INVALID }, // G + { IPT_MAHJONG_REACH, IPT_INVALID }, // G# + { IPT_MAHJONG_M, IPT_HANAFUDA_YES }, // A + { IPT_MAHJONG_RON, IPT_INVALID }, // A# + { IPT_MAHJONG_N, IPT_HANAFUDA_NO }, // B + { IPT_MAHJONG_O, IPT_INVALID } }; // C for (unsigned i = 0; (SWITCH_C3 - SWITCH_C1) >= i; ++i) { - device.add_item( + switch_ids[SWITCH_C1 + i] = device.add_item( util::string_format(key_formats[i % 12], (i / 12) + 1), std::string_view(), (ITEM_ID_BUTTON32 >= button_id) ? button_id++ : ITEM_ID_OTHER_SWITCH, generic_button_get_state<u8>, &m_switches[SWITCH_C1 + i]); + + // add mahjong/hanafuda control assignments + input_seq const seq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, switch_ids[SWITCH_C1 + i])); + if (IPT_INVALID != key_ids[i].first) + assignments.emplace_back(key_ids[i].first, SEQ_TYPE_STANDARD, seq); + if (IPT_INVALID != key_ids[i].second) + assignments.emplace_back(key_ids[i].second, SEQ_TYPE_STANDARD, seq); } // add start/back if (has_button(XINPUT_GAMEPAD_START)) { - device.add_item( + switch_ids[SWITCH_START] = device.add_item( "Start", std::string_view(), ITEM_ID_START, generic_button_get_state<u8>, &m_switches[SWITCH_START]); + add_button_assignment(assignments, IPT_START, { switch_ids[SWITCH_START] }); } if (has_button(XINPUT_GAMEPAD_BACK)) { - device.add_item( + switch_ids[SWITCH_BACK] = device.add_item( "Back", std::string_view(), ITEM_ID_SELECT, generic_button_get_state<u8>, &m_switches[SWITCH_BACK]); + add_button_assignment(assignments, IPT_SELECT, { switch_ids[SWITCH_BACK] }); } + + // use the D-pad for directional controls + add_directional_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN]); + + // use the D-pad and A/B/X/Y diamond for twin sticks + add_twin_stick_assignments( + assignments, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + ITEM_ID_INVALID, + switch_ids[SWITCH_DPAD_LEFT], + switch_ids[SWITCH_DPAD_RIGHT], + switch_ids[SWITCH_DPAD_UP], + switch_ids[SWITCH_DPAD_DOWN], + switch_ids[SWITCH_X], + switch_ids[SWITCH_B], + switch_ids[SWITCH_Y], + switch_ids[SWITCH_A]); + + // assign UI select/back/clear/help + assign_ui_actions( + assignments, + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_START, + SWITCH_BACK, + switch_ids, + numbered_buttons, + button_count); + + // set default assignments + device.set_default_assignments(std::move(assignments)); } @@ -1832,6 +3073,14 @@ std::unique_ptr<device_info> xinput_api_helper::create_xinput_device( case XINPUT_DEVTYPE_GAMEPAD: switch (caps.SubType) { + case 0x04: // XINPUT_DEVSUBTYPE_FLIGHT_STICK: work around MinGW header issues + return std::make_unique<xinput_flight_stick_device>( + device_name, + device_name, + module, + index, + caps, + *this); case XINPUT_DEVSUBTYPE_GUITAR: case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE: case XINPUT_DEVSUBTYPE_GUITAR_BASS: @@ -1842,7 +3091,6 @@ std::unique_ptr<device_info> xinput_api_helper::create_xinput_device( index, caps, *this); - break; case XINPUT_DEVSUBTYPE_DRUM_KIT: return std::make_unique<xinput_drumkit_device>( device_name, @@ -1851,7 +3099,6 @@ std::unique_ptr<device_info> xinput_api_helper::create_xinput_device( index, caps, *this); - break; case 0x0f: return std::make_unique<xinput_keyboard_device>( device_name, @@ -1860,7 +3107,6 @@ std::unique_ptr<device_info> xinput_api_helper::create_xinput_device( index, caps, *this); - break; case 0x17: return std::make_unique<xinput_turntable_device>( device_name, @@ -1869,9 +3115,7 @@ std::unique_ptr<device_info> xinput_api_helper::create_xinput_device( index, caps, *this); - break; } - break; } // create default general-purpose device diff --git a/src/osd/sdl/osdsdl.cpp b/src/osd/sdl/osdsdl.cpp index 260fd74891a..3a6fdda3052 100644 --- a/src/osd/sdl/osdsdl.cpp +++ b/src/osd/sdl/osdsdl.cpp @@ -401,7 +401,7 @@ void sdl_osd_interface::customize_input_type_list(std::vector<input_type_entry> // disable the config menu if the ALT key is down // (allows ALT-TAB to switch between apps) - case IPT_UI_CONFIGURE: + case IPT_UI_MENU: entry.defseq(SEQ_TYPE_STANDARD).set(KEYCODE_TAB, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT); break; |