/***************************************************************************

  inptport.c

  Input ports handling

TODO:	remove the 1 analog device per port limitation
		support for inputports producing interrupts
		support for extra "real" hardware (PC throttle's, spinners etc)

***************************************************************************/

#include "driver.h"
#include <math.h>

#ifdef MAME_NET
#include "network.h"

static unsigned short input_port_defaults[MAX_INPUT_PORTS];
static int default_player;
static int analog_player_port[MAX_INPUT_PORTS];
#endif /* MAME_NET */

/* header identifying the version of the game.cfg file */
/* mame 0.36b11 */
#define MAMECFGSTRING_V5 "MAMECFG\5"
#define MAMEDEFSTRING_V5 "MAMEDEF\4"

/* mame 0.36b12 with multi key/joy extension */
#define MAMECFGSTRING_V6 "MAMECFG\6"
#define MAMEDEFSTRING_V6 "MAMEDEF\5"

/* mame 0.36b13 with and/or/not combination */
#define MAMECFGSTRING_V7 "MAMECFG\7"
#define MAMEDEFSTRING_V7 "MAMEDEF\6"

/* mame 0.36b16 with key/joy merge */
#define MAMECFGSTRING_V8 "MAMECFG\x8"
#define MAMEDEFSTRING_V8 "MAMEDEF\7"

extern void *record;
extern void *playback;
#ifdef JMAME // PLAYBACK_FIX
static int pback;
#endif

extern unsigned int dispensed_tickets;
extern unsigned int coins[COIN_COUNTERS];
extern unsigned int lastcoin[COIN_COUNTERS];
extern unsigned int coinlockedout[COIN_COUNTERS];

static unsigned short input_port_value[MAX_INPUT_PORTS];
static unsigned short input_vblank[MAX_INPUT_PORTS];

/* Assuming a maxium of one analog input device per port BW 101297 */
static struct InputPort *input_analog[MAX_INPUT_PORTS];
static int input_analog_current_value[MAX_INPUT_PORTS],input_analog_previous_value[MAX_INPUT_PORTS];
static int input_analog_init[MAX_INPUT_PORTS];
static int input_analog_scale[MAX_INPUT_PORTS];

static InputCode analogjoy_input[OSD_MAX_JOY_ANALOG][MAX_ANALOG_AXES];	/* [player#][mame axis#] array */

static int mouse_delta_axis[OSD_MAX_JOY_ANALOG][MAX_ANALOG_AXES];
static int lightgun_delta_axis[OSD_MAX_JOY_ANALOG][MAX_ANALOG_AXES];
static int analog_current_axis[OSD_MAX_JOY_ANALOG][MAX_ANALOG_AXES];
static int analog_previous_axis[OSD_MAX_JOY_ANALOG][MAX_ANALOG_AXES];

#if 0
static int mouse_delta_x[OSD_MAX_JOY_ANALOG], mouse_delta_y[OSD_MAX_JOY_ANALOG];			/* replaced by mouse_delta_axis[][] */
static int lightgun_delta_x[OSD_MAX_JOY_ANALOG], lightgun_delta_y[OSD_MAX_JOY_ANALOG];			/* replaced by lightgun_delta_axis[][] */
static int analog_current_x[OSD_MAX_JOY_ANALOG], analog_current_y[OSD_MAX_JOY_ANALOG];		/* replaced by analog_current_axis[][] */
static int analog_previous_x[OSD_MAX_JOY_ANALOG], analog_previous_y[OSD_MAX_JOY_ANALOG];	/* replaced by analog_previous_axis[][] */
#endif

#ifdef JMAME // AUTO_FIRE
#define MAX_INPUT_BITS  1024
static int auto_pressed(InputSeq *seq, UINT32 type, int bit);
static UINT8  autopressed[MAX_INPUT_BITS];
static UINT32 autofire_enable;
#endif

#ifdef JMAME // VOLUME_AUTO_ADJUST
extern INT32 volume_multiplier;
#endif

/***************************************************************************

  Configuration load/save

***************************************************************************/

/* this must match the enum in inptport.h */
const char ipdn_defaultstrings[][MAX_DEFSTR_LEN] =
{
#ifdef JAPANESE
	"OFF",
	"ON",
	"いいえ",
	"はい",
	"ライフ",
	"ボーナスライフ",
	"難易度",
	"デモサウンド",
	"コイン投入数",
	"コインA",
	"コインB",
	"9コイン/1クレジット",
	"8コイン/1クレジット",
	"7コイン/1クレジット",
	"6コイン/1クレジット",
	"5コイン/1クレジット",
	"4コイン/1クレジット",
	"3コイン/1クレジット",
	"8コイン/3クレジット",
	"4コイン/2クレジット",
	"2コイン/1クレジット",
	"5コイン/3クレジット",
	"3コイン/2クレジット",
	"4コイン/3クレジット",
	"4コイン/4クレジット",
	"3コイン/3クレジット",
	"2コイン/2クレジット",
	"1コイン/1クレジット",
	"4コイン/5クレジット",
	"3コイン/4クレジット",
	"2コイン/3クレジット",
	"4コイン/7クレジット",
	"2コイン/4クレジット",
	"1コイン/2クレジット",
	"2コイン/5クレジット",
	"2コイン/6クレジット",
	"1コイン/3クレジット",
	"2コイン/7クレジット",
	"2コイン/8クレジット",
	"1コイン/4クレジット",
	"1コイン/5クレジット",
	"1コイン/6クレジット",
	"1コイン/7クレジット",
	"1コイン/8クレジット",
	"1コイン/9クレジット",
	"フリープレイ",
	"筐体",
	"アップライト",
	"カクテル",
	"画面反転",
	"サービスモード",
	"未使用",
	"不明"
#else
	"Off",
	"On",
	"No",
	"Yes",
	"Lives",
	"Bonus Life",
	"Difficulty",
	"Demo Sounds",
	"Coinage",
	"Coin A",
	"Coin B",
	"9 Coins/1 Credit",
	"8 Coins/1 Credit",
	"7 Coins/1 Credit",
	"6 Coins/1 Credit",
	"5 Coins/1 Credit",
	"4 Coins/1 Credit",
	"3 Coins/1 Credit",
	"8 Coins/3 Credits",
	"4 Coins/2 Credits",
	"2 Coins/1 Credit",
	"5 Coins/3 Credits",
	"3 Coins/2 Credits",
	"4 Coins/3 Credits",
	"4 Coins/4 Credits",
	"3 Coins/3 Credits",
	"2 Coins/2 Credits",
	"1 Coin/1 Credit",
	"4 Coins/5 Credits",
	"3 Coins/4 Credits",
	"2 Coins/3 Credits",
	"4 Coins/7 Credits",
	"2 Coins/4 Credits",
	"1 Coin/2 Credits",
	"2 Coins/5 Credits",
	"2 Coins/6 Credits",
	"1 Coin/3 Credits",
	"2 Coins/7 Credits",
	"2 Coins/8 Credits",
	"1 Coin/4 Credits",
	"1 Coin/5 Credits",
	"1 Coin/6 Credits",
	"1 Coin/7 Credits",
	"1 Coin/8 Credits",
	"1 Coin/9 Credits",
	"Free Play",
	"Cabinet",
	"Upright",
	"Cocktail",
	"Flip Screen",
	"Service Mode",
	"Unused",
	"Unknown"
#endif
};

struct ipd inputport_defaults[] =
{
#ifdef JAPANESE
	{ IPT_UI_CONFIGURE,         "設定メニュー",			SEQ_DEF_1(KEYCODE_TAB) },
#ifdef JMAME
	{ IPT_UI_ON_SCREEN_DISPLAY, "オンスクリーンディスプレイ",	SEQ_DEF_1(KEYCODE_OPENBRACE) },
#else
	{ IPT_UI_ON_SCREEN_DISPLAY, "オンスクリーンディスプレイ",	SEQ_DEF_1(KEYCODE_TILDE) },
#endif
	{ IPT_UI_PAUSE,             "一時停止",				SEQ_DEF_1(KEYCODE_P) },
	{ IPT_UI_RESET_MACHINE,     "ゲームをリセットする",		SEQ_DEF_1(KEYCODE_F3) },
	{ IPT_UI_SHOW_GFX,          "グラフィックデータ表示",		SEQ_DEF_1(KEYCODE_F4) },
	{ IPT_UI_FRAMESKIP_DEC,     "フレームスキップ数減少",		SEQ_DEF_1(KEYCODE_F8) },
	{ IPT_UI_FRAMESKIP_INC,     "フレームスキップ数増加",		SEQ_DEF_1(KEYCODE_F9) },
	{ IPT_UI_THROTTLE,          "スロットル 有効/無効",		SEQ_DEF_1(KEYCODE_F10) },
	{ IPT_UI_SHOW_FPS,          "FPS表示",				SEQ_DEF_5(KEYCODE_F11, CODE_NOT, KEYCODE_LCONTROL, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_SHOW_PROFILER,     "プロファイラ表示",			SEQ_DEF_2(KEYCODE_F11, KEYCODE_LSHIFT) },
#ifdef MESS
	{ IPT_UI_TOGGLE_UI,         "UI 表示切り替え",			SEQ_DEF_1(KEYCODE_SCRLOCK) },
#endif
	{ IPT_UI_SNAPSHOT,          "スナップショット保存",		SEQ_DEF_1(KEYCODE_F12) },
	{ IPT_UI_TOGGLE_CHEAT,      "チート 有効/無効",			SEQ_DEF_1(KEYCODE_F6) },
#ifdef JMAME // AUTO_FIRE
	{ IPT_UI_TOGGLE_AUTOFIRE,   "連射 有効/無効",			SEQ_DEF_1(KEYCODE_COLON) },
#endif
#ifdef COMMAND_LIST
	{ IPT_UI_COMMAND,           "コマンド一覧/操作説明の表示",	SEQ_DEF_1(KEYCODE_END) },
#endif
#ifdef JMAME // CHEAT_LIST
	{ IPT_UI_CHEAT,             "チートリストの表示",		SEQ_DEF_1(KEYCODE_PGDN) },
#endif
	{ IPT_UI_UP,                "UI 上",				SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ IPT_UI_DOWN,              "UI 下",				SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_UI_LEFT,              "UI 左",				SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ IPT_UI_RIGHT,             "UI 右",				SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_UI_SELECT,            "UI 決定",				SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_1_BUTTON1) },
#ifdef JMAME // EMULATION_CLOSE
	{ IPT_UI_CANCEL,            "UI キャンセル",			SEQ_DEF_3(KEYCODE_ESC, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_CLOSE,             "エミュレーション終了",		SEQ_DEF_2(KEYCODE_ESC, KEYCODE_LSHIFT) },
#else
	{ IPT_UI_CANCEL,            "UI キャンセル",			SEQ_DEF_1(KEYCODE_ESC) },
#endif
#ifndef JMAME
	{ IPT_UI_PAN_UP,            "画面を上に移動",			SEQ_DEF_3(KEYCODE_PGUP, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_DOWN,          "画面を下に移動",			SEQ_DEF_3(KEYCODE_PGDN, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_LEFT,          "画面を左に移動",			SEQ_DEF_2(KEYCODE_PGUP, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_RIGHT,         "画面を右に移動",			SEQ_DEF_2(KEYCODE_PGDN, KEYCODE_LSHIFT) },
#endif
#ifdef MAME_DEBUG
	{ IPT_UI_TOGGLE_DEBUG,      "デバッガ表示切り替え",		SEQ_DEF_1(KEYCODE_F5) },
#endif
	{ IPT_UI_SAVE_STATE,        "プレイ状態のセーブ",		SEQ_DEF_2(KEYCODE_F7, KEYCODE_LSHIFT) },
	{ IPT_UI_LOAD_STATE,        "プレイ状態のロード",		SEQ_DEF_3(KEYCODE_F7, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_ADD_CHEAT,		"チート追加",			SEQ_DEF_1(KEYCODE_A) },
	{ IPT_UI_DELETE_CHEAT,		"チート削除",			SEQ_DEF_1(KEYCODE_D) },
	{ IPT_UI_SAVE_CHEAT,		"チート保存",			SEQ_DEF_1(KEYCODE_S) },
	{ IPT_UI_WATCH_VALUE,		"ウォッチの値表示",		SEQ_DEF_1(KEYCODE_W) },
	{ IPT_UI_EDIT_CHEAT,		"チート作成",			SEQ_DEF_1(KEYCODE_E) },
	{ IPT_UI_TOGGLE_CROSSHAIR,	"ライトガン用照準 有効/無効",	SEQ_DEF_1(KEYCODE_F1) },
	{ IPT_START1, "P1 スタート",             SEQ_DEF_3(KEYCODE_1, CODE_OR, JOYCODE_1_START) },
	{ IPT_START2, "P2 スタート",             SEQ_DEF_3(KEYCODE_2, CODE_OR, JOYCODE_2_START) },
	{ IPT_START3, "P3 スタート",             SEQ_DEF_3(KEYCODE_3, CODE_OR, JOYCODE_3_START) },
	{ IPT_START4, "P4 スタート",             SEQ_DEF_3(KEYCODE_4, CODE_OR, JOYCODE_4_START) },
	{ IPT_COIN1,  "P1 コイン投入",           SEQ_DEF_3(KEYCODE_5, CODE_OR, JOYCODE_1_SELECT) },
	{ IPT_COIN2,  "P2 コイン投入",           SEQ_DEF_3(KEYCODE_6, CODE_OR, JOYCODE_2_SELECT) },
	{ IPT_COIN3,  "P3 コイン投入",           SEQ_DEF_3(KEYCODE_7, CODE_OR, JOYCODE_3_SELECT) },
	{ IPT_COIN4,  "P4 コイン投入",           SEQ_DEF_3(KEYCODE_8, CODE_OR, JOYCODE_4_SELECT) },
	{ IPT_SERVICE1, "P1 サービスボタン",     SEQ_DEF_1(KEYCODE_9) },
	{ IPT_SERVICE2, "P2 サービスボタン",     SEQ_DEF_1(KEYCODE_0) },
	{ IPT_SERVICE3, "P3 サービスボタン",     SEQ_DEF_1(KEYCODE_MINUS) },
	{ IPT_SERVICE4, "P4 サービスボタン",     SEQ_DEF_1(KEYCODE_EQUALS) },
#ifndef MESS
	{ IPT_TILT,   "ティルト",                SEQ_DEF_1(KEYCODE_T) },
#else
	{ IPT_TILT,   "ティルト",                SEQ_DEF_0 },
#endif

	{ IPT_JOYSTICK_UP         | IPF_PLAYER1, "P1 上",          SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER1, "P1 下",          SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER1, "P1 左",          SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER1, "P1 右",          SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER1, "P1 ボタン1",     SEQ_DEF_5(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1, CODE_OR, JOYCODE_MOUSE_1_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER1, "P1 ボタン2",     SEQ_DEF_5(KEYCODE_LALT, CODE_OR, JOYCODE_1_BUTTON2, CODE_OR, JOYCODE_MOUSE_1_BUTTON3) },
	{ IPT_BUTTON3             | IPF_PLAYER1, "P1 ボタン3",     SEQ_DEF_5(KEYCODE_SPACE, CODE_OR, JOYCODE_1_BUTTON3, CODE_OR, JOYCODE_MOUSE_1_BUTTON2) },
	{ IPT_BUTTON4             | IPF_PLAYER1, "P1 ボタン4",     SEQ_DEF_3(KEYCODE_LSHIFT, CODE_OR, JOYCODE_1_BUTTON4) },
	{ IPT_BUTTON5             | IPF_PLAYER1, "P1 ボタン5",     SEQ_DEF_3(KEYCODE_Z, CODE_OR, JOYCODE_1_BUTTON5) },
	{ IPT_BUTTON6             | IPF_PLAYER1, "P1 ボタン6",     SEQ_DEF_3(KEYCODE_X, CODE_OR, JOYCODE_1_BUTTON6) },
	{ IPT_BUTTON7             | IPF_PLAYER1, "P1 ボタン7",     SEQ_DEF_1(KEYCODE_C) },
	{ IPT_BUTTON8             | IPF_PLAYER1, "P1 ボタン8",     SEQ_DEF_1(KEYCODE_V) },
	{ IPT_BUTTON9             | IPF_PLAYER1, "P1 ボタン9",     SEQ_DEF_1(KEYCODE_B) },
	{ IPT_BUTTON10            | IPF_PLAYER1, "P1 ボタン10",    SEQ_DEF_1(KEYCODE_N) },
	{ IPT_JOYSTICKRIGHT_UP    | IPF_PLAYER1, "P1 右レバー/上", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_1_BUTTON2) },
	{ IPT_JOYSTICKRIGHT_DOWN  | IPF_PLAYER1, "P1 右レバー/下", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_1_BUTTON3) },
	{ IPT_JOYSTICKRIGHT_LEFT  | IPF_PLAYER1, "P1 右レバー/左", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_1_BUTTON1) },
	{ IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER1, "P1 右レバー/右", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_1_BUTTON4) },
	{ IPT_JOYSTICKLEFT_UP     | IPF_PLAYER1, "P1 左レバー/上", SEQ_DEF_3(KEYCODE_E, CODE_OR, JOYCODE_1_UP) },
	{ IPT_JOYSTICKLEFT_DOWN   | IPF_PLAYER1, "P1 左レバー/下", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_JOYSTICKLEFT_LEFT   | IPF_PLAYER1, "P1 左レバー/左", SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_1_LEFT) },
	{ IPT_JOYSTICKLEFT_RIGHT  | IPF_PLAYER1, "P1 左レバー/右", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_1_RIGHT) },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER2, "P2 上",          SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER2, "P2 下",          SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER2, "P2 左",          SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER2, "P2 右",          SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER2, "P2 ボタン1",     SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER2, "P2 ボタン2",     SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_2_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER2, "P2 ボタン3",     SEQ_DEF_3(KEYCODE_Q, CODE_OR, JOYCODE_2_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER2, "P2 ボタン4",     SEQ_DEF_3(KEYCODE_W, CODE_OR, JOYCODE_2_BUTTON4) },
	{ IPT_BUTTON5             | IPF_PLAYER2, "P2 ボタン5",     SEQ_DEF_1(JOYCODE_2_BUTTON5) },
	{ IPT_BUTTON6             | IPF_PLAYER2, "P2 ボタン6",     SEQ_DEF_1(JOYCODE_2_BUTTON6) },
	{ IPT_BUTTON7             | IPF_PLAYER2, "P2 ボタン7",     SEQ_DEF_0 },
	{ IPT_BUTTON8             | IPF_PLAYER2, "P2 ボタン8",     SEQ_DEF_0 },
	{ IPT_BUTTON9             | IPF_PLAYER2, "P2 ボタン9",     SEQ_DEF_0 },
	{ IPT_BUTTON10            | IPF_PLAYER2, "P2 ボタン10",    SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_UP    | IPF_PLAYER2, "P2 右レバー/上", SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_DOWN  | IPF_PLAYER2, "P2 右レバー/下", SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_LEFT  | IPF_PLAYER2, "P2 右レバー/左", SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER2, "P2 右レバー/右", SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_UP     | IPF_PLAYER2, "P2 左レバー/上", SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_DOWN   | IPF_PLAYER2, "P2 左レバー/下", SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_LEFT   | IPF_PLAYER2, "P2 左レバー/左", SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_RIGHT  | IPF_PLAYER2, "P2 左レバー/右", SEQ_DEF_0 },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER3, "P3 上",          SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER3, "P3 下",          SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER3, "P3 左",          SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER3, "P3 右",          SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER3, "P3 ボタン1",     SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER3, "P3 ボタン2",     SEQ_DEF_3(KEYCODE_RSHIFT, CODE_OR, JOYCODE_3_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER3, "P3 ボタン3",     SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_3_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER3, "P3 ボタン4",     SEQ_DEF_1(JOYCODE_3_BUTTON4) },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER4, "P4 上",          SEQ_DEF_1(JOYCODE_4_UP) },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER4, "P4 下",          SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER4, "P4 左",          SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER4, "P4 右",          SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER4, "P4 ボタン1",     SEQ_DEF_1(JOYCODE_4_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER4, "P4 ボタン2",     SEQ_DEF_1(JOYCODE_4_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER4, "P4 ボタン3",     SEQ_DEF_1(JOYCODE_4_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER4, "P4 ボタン4",     SEQ_DEF_1(JOYCODE_4_BUTTON4) },

	{ IPT_PEDAL	            | IPF_PLAYER1, "P1 ペダル1",     SEQ_DEF_3(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER1, "P1 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER2, "P2 ペダル1",     SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER2, "P2 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER3, "P3 ペダル1",     SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER3, "P3 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER4, "P4 ペダル1",     SEQ_DEF_1(JOYCODE_4_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER4, "P4 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },

	{ IPT_PEDAL2	             | IPF_PLAYER1, "P1 ペダル2",    SEQ_DEF_1(JOYCODE_1_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER1, "P1 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER2, "P2 ペダル2",    SEQ_DEF_1(JOYCODE_2_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER2, "P2 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER3, "P3 ペダル2",    SEQ_DEF_1(JOYCODE_3_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER3, "P3 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER4, "P4 ペダル2",    SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER4, "P4 自動リリース <Y/N>", SEQ_DEF_1(KEYCODE_Y) },

	{ IPT_PADDLE | IPF_PLAYER1,  "パドル1",      SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER1)+IPT_EXTENSION,             "パドル1",      SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT)  },
	{ IPT_PADDLE | IPF_PLAYER2,  "パドル2",      SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER2)+IPT_EXTENSION,             "パドル2",      SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_PADDLE | IPF_PLAYER3,  "パドル3",      SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER3)+IPT_EXTENSION,             "パドル3",      SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_PADDLE | IPF_PLAYER4,  "パドル4",      SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER4)+IPT_EXTENSION,             "パドル4",      SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_PADDLE_V | IPF_PLAYER1,  "パドルV1",        SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER1)+IPT_EXTENSION,             "パドルV1",      SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER2,  "パドルV2",        SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER2)+IPT_EXTENSION,             "パドルV2",      SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER3,  "パドルV3",        SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER3)+IPT_EXTENSION,             "パドルV3",      SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER4,  "パドルV4",        SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER4)+IPT_EXTENSION,             "パドルV4",      SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ IPT_DIAL | IPF_PLAYER1,    "ダイアル1",        SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER1)+IPT_EXTENSION,               "ダイアル1",      SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER2,    "ダイアル2",        SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER2)+IPT_EXTENSION,               "ダイアル2",      SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER3,    "ダイアル3",        SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER3)+IPT_EXTENSION,               "ダイアル3",      SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER4,    "ダイアル4",        SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER4)+IPT_EXTENSION,               "ダイアル4",      SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_DIAL_V | IPF_PLAYER1,  "ダイアルV1",        SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER1)+IPT_EXTENSION,             "ダイアルV1",      SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER2,  "ダイアルV2",        SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER2)+IPT_EXTENSION,             "ダイアルV2",      SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER3,  "ダイアルV3",        SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER3)+IPT_EXTENSION,             "ダイアルV3",      SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER4,  "ダイアルV4",        SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER4)+IPT_EXTENSION,             "ダイアルV4",      SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_TRACKBALL_X | IPF_PLAYER1, "トラックX1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER1)+IPT_EXTENSION,                 "トラックX1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER2, "トラックX2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER2)+IPT_EXTENSION,                 "トラックX2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER3, "トラックX3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER3)+IPT_EXTENSION,                 "トラックX3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER4, "トラックX4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER4)+IPT_EXTENSION,                 "トラックX4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_TRACKBALL_Y | IPF_PLAYER1, "トラックY1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER1)+IPT_EXTENSION,                 "トラックY1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER2, "トラックY2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER2)+IPT_EXTENSION,                 "トラックY2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER3, "トラックY3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER3)+IPT_EXTENSION,                 "トラックY3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER4, "トラックY4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER4)+IPT_EXTENSION,                 "トラックY4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_AD_STICK_X | IPF_PLAYER1, "ADスティックX1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER1)+IPT_EXTENSION,                "ADスティックX1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER2, "ADスティックX2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER2)+IPT_EXTENSION,                "ADスティックX2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER3, "ADスティックX3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER3)+IPT_EXTENSION,                "ADスティックX3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER4, "ADスティックX4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER4)+IPT_EXTENSION,                "ADスティックX4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_AD_STICK_Y | IPF_PLAYER1, "ADスティックY1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER1)+IPT_EXTENSION,                "ADスティックY1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER2, "ADスティックY2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER2)+IPT_EXTENSION,                "ADスティックY2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER3, "ADスティックY3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER3)+IPT_EXTENSION,                "ADスティックY3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER4, "ADスティックY4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER4)+IPT_EXTENSION,                "ADスティックY4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_AD_STICK_Z | IPF_PLAYER1, "ADスティックZ1", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER1)+IPT_EXTENSION,                "ADスティックZ1", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER2, "ADスティックZ2", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER2)+IPT_EXTENSION,                "ADスティックZ2", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER3, "ADスティックZ3", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER3)+IPT_EXTENSION,                "ADスティックZ3", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER4, "ADスティックZ4", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER4)+IPT_EXTENSION,                "ADスティックZ4", SEQ_DEF_0 },

	{ IPT_LIGHTGUN_X | IPF_PLAYER1, "ライトガンX1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER1)+IPT_EXTENSION,                "ライトガンX1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER2, "ライトガンX2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER2)+IPT_EXTENSION,                "ライトガンX2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER3, "ライトガンX3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER3)+IPT_EXTENSION,                "ライトガンX3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER4, "ライトガンX4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER4)+IPT_EXTENSION,                "ライトガンX4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_LIGHTGUN_Y | IPF_PLAYER1, "ライトガンY1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER1)+IPT_EXTENSION,                "ライトガンY1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER2, "ライトガンY2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER2)+IPT_EXTENSION,                "ライトガンY2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER3, "ライトガンY3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER3)+IPT_EXTENSION,                "ライトガンY3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER4, "ライトガンY4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER4)+IPT_EXTENSION,                "ライトガンY4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_UNKNOWN,             "UNKNOWN",         SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_END,                 0,                 SEQ_DEF_0 }	/* returned when there is no match */
#else
	{ IPT_UI_CONFIGURE,         "Config Menu",			SEQ_DEF_1(KEYCODE_TAB) },
#ifdef JMAME
	{ IPT_UI_ON_SCREEN_DISPLAY, "On Screen Display",		SEQ_DEF_1(KEYCODE_OPENBRACE) },
#else
	{ IPT_UI_ON_SCREEN_DISPLAY, "On Screen Display",		SEQ_DEF_1(KEYCODE_TILDE) },
#endif
	{ IPT_UI_PAUSE,             "Pause",				SEQ_DEF_1(KEYCODE_P) },
	{ IPT_UI_RESET_MACHINE,     "Reset Game",			SEQ_DEF_1(KEYCODE_F3) },
	{ IPT_UI_SHOW_GFX,          "Show Gfx",				SEQ_DEF_1(KEYCODE_F4) },
	{ IPT_UI_FRAMESKIP_DEC,     "Frameskip Dec",			SEQ_DEF_1(KEYCODE_F8) },
	{ IPT_UI_FRAMESKIP_INC,     "Frameskip Inc",			SEQ_DEF_1(KEYCODE_F9) },
	{ IPT_UI_THROTTLE,          "Throttle",				SEQ_DEF_1(KEYCODE_F10) },
	{ IPT_UI_SHOW_FPS,          "Show FPS",				SEQ_DEF_5(KEYCODE_F11, CODE_NOT, KEYCODE_LCONTROL, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_SHOW_PROFILER,     "Show Profiler",			SEQ_DEF_2(KEYCODE_F11, KEYCODE_LSHIFT) },
#ifdef MESS
	{ IPT_UI_TOGGLE_UI,         "UI Toggle",			SEQ_DEF_1(KEYCODE_SCRLOCK) },
#endif
	{ IPT_UI_SNAPSHOT,          "Save Snapshot",			SEQ_DEF_1(KEYCODE_F12) },
	{ IPT_UI_TOGGLE_CHEAT,      "Toggle Cheat",			SEQ_DEF_1(KEYCODE_F6) },
#ifdef JMAME // AUTO_FIRE
	{ IPT_UI_TOGGLE_AUTOFIRE,   "Toggle Autofire",			SEQ_DEF_1(KEYCODE_COLON) },
#endif
#ifdef COMMAND_LIST
	{ IPT_UI_COMMAND,           "Show Command List",		SEQ_DEF_1(KEYCODE_END) },
#endif
#ifdef JMAME // CHEAT_LIST
	{ IPT_UI_CHEAT,             "Show Cheat List",			SEQ_DEF_1(KEYCODE_PGDN) },
#endif
	{ IPT_UI_UP,                "UI Up",				SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ IPT_UI_DOWN,              "UI Down",				SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_UI_LEFT,              "UI Left",				SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ IPT_UI_RIGHT,             "UI Right",				SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_UI_SELECT,            "UI Select",			SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_1_BUTTON1) },
#ifdef JMAME // EMULATION_CLOSE
	{ IPT_UI_CANCEL,            "UI Cancel",			SEQ_DEF_3(KEYCODE_ESC, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_CLOSE,             "Emulation Close",			SEQ_DEF_2(KEYCODE_ESC, KEYCODE_LSHIFT) },
#else
	{ IPT_UI_CANCEL,            "UI Cancel",			SEQ_DEF_1(KEYCODE_ESC) },
#endif
#ifndef JMAME
	{ IPT_UI_PAN_UP,            "Pan Up",				SEQ_DEF_3(KEYCODE_PGUP, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_DOWN,          "Pan Down",				SEQ_DEF_3(KEYCODE_PGDN, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_LEFT,          "Pan Left",				SEQ_DEF_2(KEYCODE_PGUP, KEYCODE_LSHIFT) },
	{ IPT_UI_PAN_RIGHT,         "Pan Right",			SEQ_DEF_2(KEYCODE_PGDN, KEYCODE_LSHIFT) },
#endif
#ifdef MAME_DEBUG
	{ IPT_UI_TOGGLE_DEBUG,      "Toggle Debugger",			SEQ_DEF_1(KEYCODE_F5) },
#endif
	{ IPT_UI_SAVE_STATE,        "Save State",			SEQ_DEF_2(KEYCODE_F7, KEYCODE_LSHIFT) },
	{ IPT_UI_LOAD_STATE,        "Load State",			SEQ_DEF_3(KEYCODE_F7, CODE_NOT, KEYCODE_LSHIFT) },
	{ IPT_UI_ADD_CHEAT,		"Add Cheat",			SEQ_DEF_1(KEYCODE_A) },
	{ IPT_UI_DELETE_CHEAT,		"Delete Cheat",			SEQ_DEF_1(KEYCODE_D) },
	{ IPT_UI_SAVE_CHEAT,		"Save Cheat",			SEQ_DEF_1(KEYCODE_S) },
	{ IPT_UI_WATCH_VALUE,		"Watch Value",			SEQ_DEF_1(KEYCODE_W) },
	{ IPT_UI_EDIT_CHEAT,		"Edit Cheat",			SEQ_DEF_1(KEYCODE_E) },
	{ IPT_UI_TOGGLE_CROSSHAIR,	"Toggle Crosshair",		SEQ_DEF_1(KEYCODE_F1) },
	{ IPT_START1, "1 Player Start",  SEQ_DEF_3(KEYCODE_1, CODE_OR, JOYCODE_1_START) },
	{ IPT_START2, "2 Players Start", SEQ_DEF_3(KEYCODE_2, CODE_OR, JOYCODE_2_START) },
	{ IPT_START3, "3 Players Start", SEQ_DEF_3(KEYCODE_3, CODE_OR, JOYCODE_3_START) },
	{ IPT_START4, "4 Players Start", SEQ_DEF_3(KEYCODE_4, CODE_OR, JOYCODE_4_START) },
	{ IPT_COIN1,  "Coin 1",          SEQ_DEF_3(KEYCODE_5, CODE_OR, JOYCODE_1_SELECT) },
	{ IPT_COIN2,  "Coin 2",          SEQ_DEF_3(KEYCODE_6, CODE_OR, JOYCODE_2_SELECT) },
	{ IPT_COIN3,  "Coin 3",          SEQ_DEF_3(KEYCODE_7, CODE_OR, JOYCODE_3_SELECT) },
	{ IPT_COIN4,  "Coin 4",          SEQ_DEF_3(KEYCODE_8, CODE_OR, JOYCODE_4_SELECT) },
	{ IPT_SERVICE1, "Service 1",     SEQ_DEF_1(KEYCODE_9) },
	{ IPT_SERVICE2, "Service 2",     SEQ_DEF_1(KEYCODE_0) },
	{ IPT_SERVICE3, "Service 3",     SEQ_DEF_1(KEYCODE_MINUS) },
	{ IPT_SERVICE4, "Service 4",     SEQ_DEF_1(KEYCODE_EQUALS) },
#ifndef MESS
	{ IPT_TILT,   "Tilt",            SEQ_DEF_1(KEYCODE_T) },
#else
	{ IPT_TILT,   "Tilt",            SEQ_DEF_0 },
#endif

	{ IPT_JOYSTICK_UP         | IPF_PLAYER1, "P1 Up",          SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER1, "P1 Down",        SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER1, "P1 Left",        SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER1, "P1 Right",       SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER1, "P1 Button 1",    SEQ_DEF_5(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1, CODE_OR, JOYCODE_MOUSE_1_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER1, "P1 Button 2",    SEQ_DEF_5(KEYCODE_LALT, CODE_OR, JOYCODE_1_BUTTON2, CODE_OR, JOYCODE_MOUSE_1_BUTTON3) },
	{ IPT_BUTTON3             | IPF_PLAYER1, "P1 Button 3",    SEQ_DEF_5(KEYCODE_SPACE, CODE_OR, JOYCODE_1_BUTTON3, CODE_OR, JOYCODE_MOUSE_1_BUTTON2) },
	{ IPT_BUTTON4             | IPF_PLAYER1, "P1 Button 4",    SEQ_DEF_3(KEYCODE_LSHIFT, CODE_OR, JOYCODE_1_BUTTON4) },
	{ IPT_BUTTON5             | IPF_PLAYER1, "P1 Button 5",    SEQ_DEF_3(KEYCODE_Z, CODE_OR, JOYCODE_1_BUTTON5) },
	{ IPT_BUTTON6             | IPF_PLAYER1, "P1 Button 6",    SEQ_DEF_3(KEYCODE_X, CODE_OR, JOYCODE_1_BUTTON6) },
	{ IPT_BUTTON7             | IPF_PLAYER1, "P1 Button 7",    SEQ_DEF_1(KEYCODE_C) },
	{ IPT_BUTTON8             | IPF_PLAYER1, "P1 Button 8",    SEQ_DEF_1(KEYCODE_V) },
	{ IPT_BUTTON9             | IPF_PLAYER1, "P1 Button 9",    SEQ_DEF_1(KEYCODE_B) },
	{ IPT_BUTTON10            | IPF_PLAYER1, "P1 Button 10",   SEQ_DEF_1(KEYCODE_N) },
	{ IPT_JOYSTICKRIGHT_UP    | IPF_PLAYER1, "P1 Right/Up",    SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_1_BUTTON2) },
	{ IPT_JOYSTICKRIGHT_DOWN  | IPF_PLAYER1, "P1 Right/Down",  SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_1_BUTTON3) },
	{ IPT_JOYSTICKRIGHT_LEFT  | IPF_PLAYER1, "P1 Right/Left",  SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_1_BUTTON1) },
	{ IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER1, "P1 Right/Right", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_1_BUTTON4) },
	{ IPT_JOYSTICKLEFT_UP     | IPF_PLAYER1, "P1 Left/Up",     SEQ_DEF_3(KEYCODE_E, CODE_OR, JOYCODE_1_UP) },
	{ IPT_JOYSTICKLEFT_DOWN   | IPF_PLAYER1, "P1 Left/Down",   SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_JOYSTICKLEFT_LEFT   | IPF_PLAYER1, "P1 Left/Left",   SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_1_LEFT) },
	{ IPT_JOYSTICKLEFT_RIGHT  | IPF_PLAYER1, "P1 Left/Right",  SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_1_RIGHT) },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER2, "P2 Up",          SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER2, "P2 Down",        SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER2, "P2 Left",        SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER2, "P2 Right",       SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER2, "P2 Button 1",    SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER2, "P2 Button 2",    SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_2_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER2, "P2 Button 3",    SEQ_DEF_3(KEYCODE_Q, CODE_OR, JOYCODE_2_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER2, "P2 Button 4",    SEQ_DEF_3(KEYCODE_W, CODE_OR, JOYCODE_2_BUTTON4) },
	{ IPT_BUTTON5             | IPF_PLAYER2, "P2 Button 5",    SEQ_DEF_1(JOYCODE_2_BUTTON5) },
	{ IPT_BUTTON6             | IPF_PLAYER2, "P2 Button 6",    SEQ_DEF_1(JOYCODE_2_BUTTON6) },
	{ IPT_BUTTON7             | IPF_PLAYER2, "P2 Button 7",    SEQ_DEF_0 },
	{ IPT_BUTTON8             | IPF_PLAYER2, "P2 Button 8",    SEQ_DEF_0 },
	{ IPT_BUTTON9             | IPF_PLAYER2, "P2 Button 9",    SEQ_DEF_0 },
	{ IPT_BUTTON10            | IPF_PLAYER2, "P2 Button 10",   SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_UP    | IPF_PLAYER2, "P2 Right/Up",    SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_DOWN  | IPF_PLAYER2, "P2 Right/Down",  SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_LEFT  | IPF_PLAYER2, "P2 Right/Left",  SEQ_DEF_0 },
	{ IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER2, "P2 Right/Right", SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_UP     | IPF_PLAYER2, "P2 Left/Up",     SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_DOWN   | IPF_PLAYER2, "P2 Left/Down",   SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_LEFT   | IPF_PLAYER2, "P2 Left/Left",   SEQ_DEF_0 },
	{ IPT_JOYSTICKLEFT_RIGHT  | IPF_PLAYER2, "P2 Left/Right",  SEQ_DEF_0 },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER3, "P3 Up",          SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP)    },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER3, "P3 Down",        SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN)  },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER3, "P3 Left",        SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT)  },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER3, "P3 Right",       SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER3, "P3 Button 1",    SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER3, "P3 Button 2",    SEQ_DEF_3(KEYCODE_RSHIFT, CODE_OR, JOYCODE_3_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER3, "P3 Button 3",    SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_3_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER3, "P3 Button 4",    SEQ_DEF_1(JOYCODE_3_BUTTON4) },

	{ IPT_JOYSTICK_UP         | IPF_PLAYER4, "P4 Up",          SEQ_DEF_1(JOYCODE_4_UP) },
	{ IPT_JOYSTICK_DOWN       | IPF_PLAYER4, "P4 Down",        SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ IPT_JOYSTICK_LEFT       | IPF_PLAYER4, "P4 Left",        SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ IPT_JOYSTICK_RIGHT      | IPF_PLAYER4, "P4 Right",       SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_BUTTON1             | IPF_PLAYER4, "P4 Button 1",    SEQ_DEF_1(JOYCODE_4_BUTTON1) },
	{ IPT_BUTTON2             | IPF_PLAYER4, "P4 Button 2",    SEQ_DEF_1(JOYCODE_4_BUTTON2) },
	{ IPT_BUTTON3             | IPF_PLAYER4, "P4 Button 3",    SEQ_DEF_1(JOYCODE_4_BUTTON3) },
	{ IPT_BUTTON4             | IPF_PLAYER4, "P4 Button 4",    SEQ_DEF_1(JOYCODE_4_BUTTON4) },

	{ IPT_PEDAL	            | IPF_PLAYER1, "P1 Pedal 1",     SEQ_DEF_3(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER1, "P1 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER2, "P2 Pedal 1",     SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER2, "P2 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER3, "P3 Pedal 1",     SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER3, "P3 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL                 | IPF_PLAYER4, "P4 Pedal 1",     SEQ_DEF_1(JOYCODE_4_BUTTON1) },
	{ (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER4, "P4 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },

	{ IPT_PEDAL2	             | IPF_PLAYER1, "P1 Pedal 2",    SEQ_DEF_1(JOYCODE_1_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER1, "P1 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER2, "P2 Pedal 2",    SEQ_DEF_1(JOYCODE_2_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER2, "P2 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER3, "P3 Pedal 2",    SEQ_DEF_1(JOYCODE_3_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER3, "P3 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
	{ IPT_PEDAL2                 | IPF_PLAYER4, "P4 Pedal 2",    SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ (IPT_PEDAL2+IPT_EXTENSION) | IPF_PLAYER4, "P4 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },

	{ IPT_PADDLE | IPF_PLAYER1,  "Paddle 1",      SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER1)+IPT_EXTENSION,             "Paddle 1",      SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT)  },
	{ IPT_PADDLE | IPF_PLAYER2,  "Paddle 2",      SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER2)+IPT_EXTENSION,             "Paddle 2",      SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_PADDLE | IPF_PLAYER3,  "Paddle 3",      SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER3)+IPT_EXTENSION,             "Paddle 3",      SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_PADDLE | IPF_PLAYER4,  "Paddle 4",      SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_PADDLE | IPF_PLAYER4)+IPT_EXTENSION,             "Paddle 4",      SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_PADDLE_V | IPF_PLAYER1,  "Paddle V 1",        SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER1)+IPT_EXTENSION,             "Paddle V 1",      SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER2,  "Paddle V 2",        SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER2)+IPT_EXTENSION,             "Paddle V 2",      SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER3,  "Paddle V 3",        SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER3)+IPT_EXTENSION,             "Paddle V 3",      SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_PADDLE_V | IPF_PLAYER4,  "Paddle V 4",        SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_PADDLE_V | IPF_PLAYER4)+IPT_EXTENSION,             "Paddle V 4",      SEQ_DEF_1(JOYCODE_4_DOWN) },
	{ IPT_DIAL | IPF_PLAYER1,    "Dial 1",        SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER1)+IPT_EXTENSION,               "Dial 1",      SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER2,    "Dial 2",        SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER2)+IPT_EXTENSION,               "Dial 2",      SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER3,    "Dial 3",        SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER3)+IPT_EXTENSION,               "Dial 3",      SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_DIAL | IPF_PLAYER4,    "Dial 4",        SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_DIAL | IPF_PLAYER4)+IPT_EXTENSION,               "Dial 4",      SEQ_DEF_1(JOYCODE_4_RIGHT) },
	{ IPT_DIAL_V | IPF_PLAYER1,  "Dial V 1",        SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER1)+IPT_EXTENSION,             "Dial V 1",      SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER2,  "Dial V 2",        SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER2)+IPT_EXTENSION,             "Dial V 2",      SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER3,  "Dial V 3",        SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER3)+IPT_EXTENSION,             "Dial V 3",      SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_DIAL_V | IPF_PLAYER4,  "Dial V 4",        SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_DIAL_V | IPF_PLAYER4)+IPT_EXTENSION,             "Dial V 4",      SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_TRACKBALL_X | IPF_PLAYER1, "Track X 1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER1)+IPT_EXTENSION,                 "Track X 1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER2, "Track X 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER2)+IPT_EXTENSION,                 "Track X 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER3, "Track X 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER3)+IPT_EXTENSION,                 "Track X 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_TRACKBALL_X | IPF_PLAYER4, "Track X 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_TRACKBALL_X | IPF_PLAYER4)+IPT_EXTENSION,                 "Track X 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_TRACKBALL_Y | IPF_PLAYER1, "Track Y 1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER1)+IPT_EXTENSION,                 "Track Y 1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER2, "Track Y 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER2)+IPT_EXTENSION,                 "Track Y 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER3, "Track Y 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER3)+IPT_EXTENSION,                 "Track Y 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_TRACKBALL_Y | IPF_PLAYER4, "Track Y 4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_TRACKBALL_Y | IPF_PLAYER4)+IPT_EXTENSION,                 "Track Y 4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_AD_STICK_X | IPF_PLAYER1, "AD Stick X 1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER1)+IPT_EXTENSION,                "AD Stick X 1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER2, "AD Stick X 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER2)+IPT_EXTENSION,                "AD Stick X 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER3, "AD Stick X 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER3)+IPT_EXTENSION,                "AD Stick X 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_AD_STICK_X | IPF_PLAYER4, "AD Stick X 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_AD_STICK_X | IPF_PLAYER4)+IPT_EXTENSION,                "AD Stick X 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_AD_STICK_Y | IPF_PLAYER1, "AD Stick Y 1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER1)+IPT_EXTENSION,                "AD Stick Y 1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER2, "AD Stick Y 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER2)+IPT_EXTENSION,                "AD Stick Y 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER3, "AD Stick Y 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER3)+IPT_EXTENSION,                "AD Stick Y 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_AD_STICK_Y | IPF_PLAYER4, "AD Stick Y 4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_AD_STICK_Y | IPF_PLAYER4)+IPT_EXTENSION,                "AD Stick Y 4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_AD_STICK_Z | IPF_PLAYER1, "AD Stick Z 1", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER1)+IPT_EXTENSION,                "AD Stick Z 1", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER2, "AD Stick Z 2", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER2)+IPT_EXTENSION,                "AD Stick Z 2", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER3, "AD Stick Z 3", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER3)+IPT_EXTENSION,                "AD Stick Z 3", SEQ_DEF_0 },
	{ IPT_AD_STICK_Z | IPF_PLAYER4, "AD Stick Z 4", SEQ_DEF_0 },
	{ (IPT_AD_STICK_Z | IPF_PLAYER4)+IPT_EXTENSION,                "AD Stick Z 4", SEQ_DEF_0 },

	{ IPT_LIGHTGUN_X | IPF_PLAYER1, "Lightgun X 1", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER1)+IPT_EXTENSION,                "Lightgun X 1", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER2, "Lightgun X 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER2)+IPT_EXTENSION,                "Lightgun X 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER3, "Lightgun X 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER3)+IPT_EXTENSION,                "Lightgun X 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
	{ IPT_LIGHTGUN_X | IPF_PLAYER4, "Lightgun X 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
	{ (IPT_LIGHTGUN_X | IPF_PLAYER4)+IPT_EXTENSION,                "Lightgun X 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },

	{ IPT_LIGHTGUN_Y | IPF_PLAYER1, "Lightgun Y 1", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER1)+IPT_EXTENSION,                "Lightgun Y 1", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER2, "Lightgun Y 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER2)+IPT_EXTENSION,                "Lightgun Y 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER3, "Lightgun Y 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER3)+IPT_EXTENSION,                "Lightgun Y 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
	{ IPT_LIGHTGUN_Y | IPF_PLAYER4, "Lightgun Y 4", SEQ_DEF_1(JOYCODE_4_UP) },
	{ (IPT_LIGHTGUN_Y | IPF_PLAYER4)+IPT_EXTENSION,                "Lightgun Y 4", SEQ_DEF_1(JOYCODE_4_DOWN) },

	{ IPT_UNKNOWN,             "UNKNOWN",         SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_OSD_RESERVED,        "",                SEQ_DEF_0 },
	{ IPT_END,                 0,                 SEQ_DEF_0 }	/* returned when there is no match */
#endif
};

struct ipd inputport_defaults_backup[sizeof(inputport_defaults)/sizeof(struct ipd)];


struct ik *osd_input_keywords = NULL;

struct ik input_keywords[] =
{
	{ "KEYCODE_A",		   		IKT_STD,		KEYCODE_A },
	{ "KEYCODE_B",		   		IKT_STD,		KEYCODE_B },
	{ "KEYCODE_C",		   		IKT_STD,		KEYCODE_C },
	{ "KEYCODE_D",		   		IKT_STD,		KEYCODE_D },
	{ "KEYCODE_E",		   		IKT_STD,		KEYCODE_E },
	{ "KEYCODE_F",		   		IKT_STD,		KEYCODE_F },
	{ "KEYCODE_G",		   		IKT_STD,		KEYCODE_G },
	{ "KEYCODE_H",		   		IKT_STD,		KEYCODE_H },
	{ "KEYCODE_I",		   		IKT_STD,		KEYCODE_I },
	{ "KEYCODE_J",		   		IKT_STD,		KEYCODE_J },
	{ "KEYCODE_K",		   		IKT_STD,		KEYCODE_K },
	{ "KEYCODE_L",		   		IKT_STD,		KEYCODE_L },
	{ "KEYCODE_M",		   		IKT_STD,		KEYCODE_M },
	{ "KEYCODE_N",		   		IKT_STD,		KEYCODE_N },
	{ "KEYCODE_O",		   		IKT_STD,		KEYCODE_O },
	{ "KEYCODE_P",		   		IKT_STD,		KEYCODE_P },
	{ "KEYCODE_Q",		   		IKT_STD,		KEYCODE_Q },
	{ "KEYCODE_R",		   		IKT_STD,		KEYCODE_R },
	{ "KEYCODE_S",		   		IKT_STD,		KEYCODE_S },
	{ "KEYCODE_T",		   		IKT_STD,		KEYCODE_T },
	{ "KEYCODE_U",		   		IKT_STD,		KEYCODE_U },
	{ "KEYCODE_V",		   		IKT_STD,		KEYCODE_V },
	{ "KEYCODE_W",		   		IKT_STD,		KEYCODE_W },
	{ "KEYCODE_X",		   		IKT_STD,		KEYCODE_X },
	{ "KEYCODE_Y",		   		IKT_STD,		KEYCODE_Y },
	{ "KEYCODE_Z",		   		IKT_STD,		KEYCODE_Z },
	{ "KEYCODE_0",		   		IKT_STD,		KEYCODE_0 },
	{ "KEYCODE_1",		   		IKT_STD,		KEYCODE_1 },
	{ "KEYCODE_2",		   		IKT_STD,		KEYCODE_2 },
	{ "KEYCODE_3",		   		IKT_STD,		KEYCODE_3 },
	{ "KEYCODE_4",		   		IKT_STD,		KEYCODE_4 },
	{ "KEYCODE_5",		   		IKT_STD,		KEYCODE_5 },
	{ "KEYCODE_6",		   		IKT_STD,		KEYCODE_6 },
	{ "KEYCODE_7",		   		IKT_STD,		KEYCODE_7 },
	{ "KEYCODE_8",		   		IKT_STD,		KEYCODE_8 },
	{ "KEYCODE_9",		   		IKT_STD,		KEYCODE_9 },
	{ "KEYCODE_0_PAD",	   		IKT_STD,		KEYCODE_0_PAD },
	{ "KEYCODE_1_PAD",	   		IKT_STD,		KEYCODE_1_PAD },
	{ "KEYCODE_2_PAD",	   		IKT_STD,		KEYCODE_2_PAD },
	{ "KEYCODE_3_PAD",	   		IKT_STD,		KEYCODE_3_PAD },
	{ "KEYCODE_4_PAD",	   		IKT_STD,		KEYCODE_4_PAD },
	{ "KEYCODE_5_PAD",	   		IKT_STD,		KEYCODE_5_PAD },
	{ "KEYCODE_6_PAD",	   		IKT_STD,		KEYCODE_6_PAD },
	{ "KEYCODE_7_PAD",	   		IKT_STD,		KEYCODE_7_PAD },
	{ "KEYCODE_8_PAD",	      	IKT_STD,		KEYCODE_8_PAD },
	{ "KEYCODE_9_PAD",	      	IKT_STD,		KEYCODE_9_PAD },
	{ "KEYCODE_F1",		   		IKT_STD,		KEYCODE_F1 },
	{ "KEYCODE_F2",			  	IKT_STD,		KEYCODE_F2 },
	{ "KEYCODE_F3",			  	IKT_STD,		KEYCODE_F3 },
	{ "KEYCODE_F4",			  	IKT_STD,		KEYCODE_F4 },
	{ "KEYCODE_F5",			  	IKT_STD,		KEYCODE_F5 },
	{ "KEYCODE_F6",			  	IKT_STD,		KEYCODE_F6 },
	{ "KEYCODE_F7",			  	IKT_STD,		KEYCODE_F7 },
	{ "KEYCODE_F8",			  	IKT_STD,		KEYCODE_F8 },
	{ "KEYCODE_F9",			  	IKT_STD,		KEYCODE_F9 },
	{ "KEYCODE_F10",		  	IKT_STD,		KEYCODE_F10 },
	{ "KEYCODE_F11",		  	IKT_STD,		KEYCODE_F11 },
	{ "KEYCODE_F12",		  	IKT_STD,		KEYCODE_F12 },
	{ "KEYCODE_ESC",		  	IKT_STD,		KEYCODE_ESC },
	{ "KEYCODE_TILDE",		  	IKT_STD,		KEYCODE_TILDE },
	{ "KEYCODE_MINUS",		  	IKT_STD,		KEYCODE_MINUS },
	{ "KEYCODE_EQUALS",		  	IKT_STD,		KEYCODE_EQUALS },
	{ "KEYCODE_BACKSPACE",	  	IKT_STD,		KEYCODE_BACKSPACE },
	{ "KEYCODE_TAB",		  	IKT_STD,		KEYCODE_TAB },
	{ "KEYCODE_OPENBRACE",	  	IKT_STD,		KEYCODE_OPENBRACE },
	{ "KEYCODE_CLOSEBRACE",	  	IKT_STD,		KEYCODE_CLOSEBRACE },
	{ "KEYCODE_ENTER",		  	IKT_STD,		KEYCODE_ENTER },
	{ "KEYCODE_COLON",		  	IKT_STD,		KEYCODE_COLON },
	{ "KEYCODE_QUOTE",		  	IKT_STD,		KEYCODE_QUOTE },
	{ "KEYCODE_BACKSLASH",	  	IKT_STD,		KEYCODE_BACKSLASH },
	{ "KEYCODE_BACKSLASH2",	  	IKT_STD,		KEYCODE_BACKSLASH2 },
	{ "KEYCODE_COMMA",		  	IKT_STD,		KEYCODE_COMMA },
	{ "KEYCODE_STOP",		  	IKT_STD,		KEYCODE_STOP },
	{ "KEYCODE_SLASH",		  	IKT_STD,		KEYCODE_SLASH },
	{ "KEYCODE_SPACE",		  	IKT_STD,		KEYCODE_SPACE },
	{ "KEYCODE_INSERT",		  	IKT_STD,		KEYCODE_INSERT },
	{ "KEYCODE_DEL",		  	IKT_STD,		KEYCODE_DEL },
	{ "KEYCODE_HOME",		  	IKT_STD,		KEYCODE_HOME },
	{ "KEYCODE_END",		  	IKT_STD,		KEYCODE_END },
	{ "KEYCODE_PGUP",		  	IKT_STD,		KEYCODE_PGUP },
	{ "KEYCODE_PGDN",		  	IKT_STD,		KEYCODE_PGDN },
	{ "KEYCODE_LEFT",		  	IKT_STD,		KEYCODE_LEFT },
	{ "KEYCODE_RIGHT",		  	IKT_STD,		KEYCODE_RIGHT },
	{ "KEYCODE_UP",			  	IKT_STD,		KEYCODE_UP },
	{ "KEYCODE_DOWN",		  	IKT_STD,		KEYCODE_DOWN },
	{ "KEYCODE_SLASH_PAD",	  	IKT_STD,		KEYCODE_SLASH_PAD },
	{ "KEYCODE_ASTERISK",	  	IKT_STD,		KEYCODE_ASTERISK },
	{ "KEYCODE_MINUS_PAD",	  	IKT_STD,		KEYCODE_MINUS_PAD },
	{ "KEYCODE_PLUS_PAD",	  	IKT_STD,		KEYCODE_PLUS_PAD },
	{ "KEYCODE_DEL_PAD",	  	IKT_STD,		KEYCODE_DEL_PAD },
	{ "KEYCODE_ENTER_PAD",	  	IKT_STD,		KEYCODE_ENTER_PAD },
	{ "KEYCODE_PRTSCR",		  	IKT_STD,		KEYCODE_PRTSCR },
	{ "KEYCODE_PAUSE",		  	IKT_STD,		KEYCODE_PAUSE },
	{ "KEYCODE_LSHIFT",		  	IKT_STD,		KEYCODE_LSHIFT },
	{ "KEYCODE_RSHIFT",		  	IKT_STD,		KEYCODE_RSHIFT },
	{ "KEYCODE_LCONTROL",	  	IKT_STD,		KEYCODE_LCONTROL },
	{ "KEYCODE_RCONTROL",	  	IKT_STD,		KEYCODE_RCONTROL },
	{ "KEYCODE_LALT",		  	IKT_STD,		KEYCODE_LALT },
	{ "KEYCODE_RALT",		  	IKT_STD,		KEYCODE_RALT },
	{ "KEYCODE_SCRLOCK",	  	IKT_STD,		KEYCODE_SCRLOCK },
	{ "KEYCODE_NUMLOCK",	  	IKT_STD,		KEYCODE_NUMLOCK },
	{ "KEYCODE_CAPSLOCK",	  	IKT_STD,		KEYCODE_CAPSLOCK },
	{ "KEYCODE_LWIN",		  	IKT_STD,		KEYCODE_LWIN },
	{ "KEYCODE_RWIN",		  	IKT_STD,		KEYCODE_RWIN },
	{ "KEYCODE_MENU",		  	IKT_STD,		KEYCODE_MENU },

	{ "JOYCODE_1_LEFT",		  	IKT_STD,		JOYCODE_1_LEFT },
	{ "JOYCODE_1_RIGHT",	  	IKT_STD,		JOYCODE_1_RIGHT },
	{ "JOYCODE_1_UP",		  	IKT_STD,		JOYCODE_1_UP },
	{ "JOYCODE_1_DOWN",		  	IKT_STD,		JOYCODE_1_DOWN },
	{ "JOYCODE_1_BUTTON1",	  	IKT_STD,		JOYCODE_1_BUTTON1 },
	{ "JOYCODE_1_BUTTON2",	  	IKT_STD,		JOYCODE_1_BUTTON2 },
	{ "JOYCODE_1_BUTTON3",	  	IKT_STD,		JOYCODE_1_BUTTON3 },
	{ "JOYCODE_1_BUTTON4",	  	IKT_STD,		JOYCODE_1_BUTTON4 },
	{ "JOYCODE_1_BUTTON5",	  	IKT_STD,		JOYCODE_1_BUTTON5 },
	{ "JOYCODE_1_BUTTON6",	  	IKT_STD,		JOYCODE_1_BUTTON6 },
#ifdef JMAME // JOYSTICK_CODE_FIX
	{ "JOYCODE_1_BUTTON7",	  	IKT_STD,		JOYCODE_1_BUTTON7 },
	{ "JOYCODE_1_BUTTON8",	  	IKT_STD,		JOYCODE_1_BUTTON8 },
	{ "JOYCODE_1_BUTTON9",	  	IKT_STD,		JOYCODE_1_BUTTON9 },
	{ "JOYCODE_1_BUTTON10",	  	IKT_STD,		JOYCODE_1_BUTTON10 },
	{ "JOYCODE_1_BUTTON11",	  	IKT_STD,		JOYCODE_1_BUTTON11 },
	{ "JOYCODE_1_BUTTON12",	  	IKT_STD,		JOYCODE_1_BUTTON12 },
	{ "JOYCODE_1_BUTTON13",	  	IKT_STD,		JOYCODE_1_BUTTON13 },
	{ "JOYCODE_1_BUTTON14",	  	IKT_STD,		JOYCODE_1_BUTTON14 },
	{ "JOYCODE_1_BUTTON15",	  	IKT_STD,		JOYCODE_1_BUTTON15 },
	{ "JOYCODE_1_BUTTON16",	  	IKT_STD,		JOYCODE_1_BUTTON16 },
#endif
	{ "JOYCODE_1_START",	  	IKT_STD,		JOYCODE_1_START },
	{ "JOYCODE_1_SELECT",	  	IKT_STD,		JOYCODE_1_SELECT },
	{ "JOYCODE_2_LEFT",		  	IKT_STD,		JOYCODE_2_LEFT },
	{ "JOYCODE_2_RIGHT",	  	IKT_STD,		JOYCODE_2_RIGHT },
	{ "JOYCODE_2_UP",		  	IKT_STD,		JOYCODE_2_UP },
	{ "JOYCODE_2_DOWN",		  	IKT_STD,		JOYCODE_2_DOWN },
	{ "JOYCODE_2_BUTTON1",	  	IKT_STD,		JOYCODE_2_BUTTON1 },
	{ "JOYCODE_2_BUTTON2",	  	IKT_STD,		JOYCODE_2_BUTTON2 },
	{ "JOYCODE_2_BUTTON3",	  	IKT_STD,		JOYCODE_2_BUTTON3 },
	{ "JOYCODE_2_BUTTON4",	  	IKT_STD,		JOYCODE_2_BUTTON4 },
	{ "JOYCODE_2_BUTTON5",	  	IKT_STD,		JOYCODE_2_BUTTON5 },
	{ "JOYCODE_2_BUTTON6",	  	IKT_STD,		JOYCODE_2_BUTTON6 },
#ifdef JMAME // JOYSTICK_CODE_FIX
	{ "JOYCODE_2_BUTTON7",	  	IKT_STD,		JOYCODE_2_BUTTON7 },
	{ "JOYCODE_2_BUTTON8",	  	IKT_STD,		JOYCODE_2_BUTTON8 },
	{ "JOYCODE_2_BUTTON9",	  	IKT_STD,		JOYCODE_2_BUTTON9 },
	{ "JOYCODE_2_BUTTON10",	  	IKT_STD,		JOYCODE_2_BUTTON10 },
	{ "JOYCODE_2_BUTTON11",	  	IKT_STD,		JOYCODE_2_BUTTON11 },
	{ "JOYCODE_2_BUTTON12",	  	IKT_STD,		JOYCODE_2_BUTTON12 },
	{ "JOYCODE_2_BUTTON13",	  	IKT_STD,		JOYCODE_2_BUTTON13 },
	{ "JOYCODE_2_BUTTON14",	  	IKT_STD,		JOYCODE_2_BUTTON14 },
	{ "JOYCODE_2_BUTTON15",	  	IKT_STD,		JOYCODE_2_BUTTON15 },
	{ "JOYCODE_2_BUTTON16",	  	IKT_STD,		JOYCODE_2_BUTTON16 },
#endif
	{ "JOYCODE_2_START",	  	IKT_STD,		JOYCODE_2_START },
	{ "JOYCODE_2_SELECT",	  	IKT_STD,		JOYCODE_2_SELECT },
	{ "JOYCODE_3_LEFT",		  	IKT_STD,		JOYCODE_3_LEFT },
	{ "JOYCODE_3_RIGHT",	  	IKT_STD,		JOYCODE_3_RIGHT },
	{ "JOYCODE_3_UP",		  	IKT_STD,		JOYCODE_3_UP },
	{ "JOYCODE_3_DOWN",		  	IKT_STD,		JOYCODE_3_DOWN },
	{ "JOYCODE_3_BUTTON1",	  	IKT_STD,		JOYCODE_3_BUTTON1 },
	{ "JOYCODE_3_BUTTON2",	  	IKT_STD,		JOYCODE_3_BUTTON2 },
	{ "JOYCODE_3_BUTTON3",	  	IKT_STD,		JOYCODE_3_BUTTON3 },
	{ "JOYCODE_3_BUTTON4",	  	IKT_STD,		JOYCODE_3_BUTTON4 },
	{ "JOYCODE_3_BUTTON5",	  	IKT_STD,		JOYCODE_3_BUTTON5 },
	{ "JOYCODE_3_BUTTON6",	  	IKT_STD,		JOYCODE_3_BUTTON6 },
#ifdef JMAME // JOYSTICK_CODE_FIX
	{ "JOYCODE_3_BUTTON7",	  	IKT_STD,		JOYCODE_3_BUTTON7 },
	{ "JOYCODE_3_BUTTON8",	  	IKT_STD,		JOYCODE_3_BUTTON8 },
	{ "JOYCODE_3_BUTTON9",	  	IKT_STD,		JOYCODE_3_BUTTON9 },
	{ "JOYCODE_3_BUTTON10",	  	IKT_STD,		JOYCODE_3_BUTTON10 },
	{ "JOYCODE_3_BUTTON11",	  	IKT_STD,		JOYCODE_3_BUTTON11 },
	{ "JOYCODE_3_BUTTON12",	  	IKT_STD,		JOYCODE_3_BUTTON12 },
	{ "JOYCODE_3_BUTTON13",	  	IKT_STD,		JOYCODE_3_BUTTON13 },
	{ "JOYCODE_3_BUTTON14",	  	IKT_STD,		JOYCODE_3_BUTTON14 },
	{ "JOYCODE_3_BUTTON15",	  	IKT_STD,		JOYCODE_3_BUTTON15 },
	{ "JOYCODE_3_BUTTON16",	  	IKT_STD,		JOYCODE_3_BUTTON16 },
#endif
	{ "JOYCODE_3_START",	  	IKT_STD,		JOYCODE_3_START },
	{ "JOYCODE_3_SELECT",	  	IKT_STD,		JOYCODE_3_SELECT },
	{ "JOYCODE_4_LEFT",		  	IKT_STD,		JOYCODE_4_LEFT },
	{ "JOYCODE_4_RIGHT",	  	IKT_STD,		JOYCODE_4_RIGHT },
	{ "JOYCODE_4_UP",		  	IKT_STD,		JOYCODE_4_UP },
	{ "JOYCODE_4_DOWN",		  	IKT_STD,		JOYCODE_4_DOWN },
	{ "JOYCODE_4_BUTTON1",	  	IKT_STD,		JOYCODE_4_BUTTON1 },
	{ "JOYCODE_4_BUTTON2",	  	IKT_STD,		JOYCODE_4_BUTTON2 },
	{ "JOYCODE_4_BUTTON3",	  	IKT_STD,		JOYCODE_4_BUTTON3 },
	{ "JOYCODE_4_BUTTON4",	  	IKT_STD,		JOYCODE_4_BUTTON4 },
	{ "JOYCODE_4_BUTTON5",	  	IKT_STD,		JOYCODE_4_BUTTON5 },
	{ "JOYCODE_4_BUTTON6",	  	IKT_STD,		JOYCODE_4_BUTTON6 },
#ifdef JMAME // JOYSTICK_CODE_FIX
	{ "JOYCODE_4_BUTTON7",	  	IKT_STD,		JOYCODE_4_BUTTON7 },
	{ "JOYCODE_4_BUTTON8",	  	IKT_STD,		JOYCODE_4_BUTTON8 },
	{ "JOYCODE_4_BUTTON9",	  	IKT_STD,		JOYCODE_4_BUTTON9 },
	{ "JOYCODE_4_BUTTON10",	  	IKT_STD,		JOYCODE_4_BUTTON10 },
	{ "JOYCODE_4_BUTTON11",	  	IKT_STD,		JOYCODE_4_BUTTON11 },
	{ "JOYCODE_4_BUTTON12",	  	IKT_STD,		JOYCODE_4_BUTTON12 },
	{ "JOYCODE_4_BUTTON13",	  	IKT_STD,		JOYCODE_4_BUTTON13 },
	{ "JOYCODE_4_BUTTON14",	  	IKT_STD,		JOYCODE_4_BUTTON14 },
	{ "JOYCODE_4_BUTTON15",	  	IKT_STD,		JOYCODE_4_BUTTON15 },
	{ "JOYCODE_4_BUTTON16",	  	IKT_STD,		JOYCODE_4_BUTTON16 },
#endif
	{ "JOYCODE_4_START",	  	IKT_STD,		JOYCODE_4_START },
	{ "JOYCODE_4_SELECT",	  	IKT_STD,		JOYCODE_4_SELECT },

	{ "MOUSECODE_1_BUTTON1", 	IKT_STD,		JOYCODE_MOUSE_1_BUTTON1 },
	{ "MOUSECODE_1_BUTTON2", 	IKT_STD,		JOYCODE_MOUSE_1_BUTTON2 },
	{ "MOUSECODE_1_BUTTON3", 	IKT_STD,		JOYCODE_MOUSE_1_BUTTON3 },

	{ "KEYCODE_NONE",			IKT_STD,		CODE_NONE },
	{ "CODE_NONE",			  	IKT_STD,		CODE_NONE },
	{ "CODE_OTHER",				IKT_STD,		CODE_OTHER },
	{ "CODE_DEFAULT",			IKT_STD,		CODE_DEFAULT },
	{ "CODE_PREVIOUS",			IKT_STD,		CODE_PREVIOUS },
	{ "CODE_NOT",				IKT_STD,		CODE_NOT },
	{ "CODE_OR",			   	IKT_STD,		CODE_OR },
	{ "!",						IKT_STD,		CODE_NOT },
	{ "|",					   	IKT_STD,		CODE_OR },

	{ "UI_CONFIGURE", 			IKT_IPT,	 	IPT_UI_CONFIGURE },
	{ "UI_ON_SCREEN_DISPLAY",	IKT_IPT,		IPT_UI_ON_SCREEN_DISPLAY },
	{ "UI_PAUSE",				IKT_IPT,		IPT_UI_PAUSE },
	{ "UI_RESET_MACHINE",		IKT_IPT,		IPT_UI_RESET_MACHINE },
	{ "UI_SHOW_GFX",			IKT_IPT,		IPT_UI_SHOW_GFX },
	{ "UI_FRAMESKIP_DEC",		IKT_IPT,		IPT_UI_FRAMESKIP_DEC },
	{ "UI_FRAMESKIP_INC",		IKT_IPT,		IPT_UI_FRAMESKIP_INC },
	{ "UI_THROTTLE",			IKT_IPT,		IPT_UI_THROTTLE },
	{ "UI_SHOW_FPS",			IKT_IPT,		IPT_UI_SHOW_FPS },
	{ "UI_SHOW_PROFILER",		IKT_IPT,		IPT_UI_SHOW_PROFILER },
#ifdef MESS
	{ "UI_TOGGLE_UI",			IKT_IPT,		IPT_UI_TOGGLE_UI },
#endif
	{ "UI_SNAPSHOT",			IKT_IPT,		IPT_UI_SNAPSHOT },
	{ "UI_TOGGLE_CHEAT",		IKT_IPT,		IPT_UI_TOGGLE_CHEAT },
#ifdef JMAME // AUTO_FIRE
	{ "UI_TOGGLE_AUTOFIRE",		IKT_IPT,		IPT_UI_TOGGLE_AUTOFIRE },
#endif
#ifdef COMMAND_LIST
	{ "UI_COMMAND",				IKT_IPT,		IPT_UI_COMMAND },
#endif
#ifdef JMAME // CHEAT_LIST
	{ "UI_CHEAT",				IKT_IPT,		IPT_UI_CHEAT },
#endif
	{ "UI_UP",					IKT_IPT,		IPT_UI_UP },
	{ "UI_DOWN",				IKT_IPT,		IPT_UI_DOWN },
	{ "UI_LEFT",				IKT_IPT,		IPT_UI_LEFT },
	{ "UI_RIGHT",				IKT_IPT,		IPT_UI_RIGHT },
	{ "UI_SELECT",				IKT_IPT,		IPT_UI_SELECT },
	{ "UI_CANCEL",				IKT_IPT,		IPT_UI_CANCEL },
#ifdef JMAME // EMULATION_CLOSE
	{ "UI_CLOSE",				IKT_IPT,		IPT_UI_CLOSE },
#endif
#ifndef JMAME
	{ "UI_PAN_UP",				IKT_IPT,		IPT_UI_PAN_UP },
	{ "UI_PAN_DOWN",			IKT_IPT,		IPT_UI_PAN_DOWN },
	{ "UI_PAN_LEFT",			IKT_IPT,		IPT_UI_PAN_LEFT },
	{ "UI_PAN_RIGHT",			IKT_IPT,		IPT_UI_PAN_RIGHT },
#endif
#ifdef MAME_DEBUG
	{ "UI_TOGGLE_DEBUG",		IKT_IPT,		IPT_UI_TOGGLE_DEBUG },
#endif
	{ "UI_SAVE_STATE",			IKT_IPT,		IPT_UI_SAVE_STATE },
	{ "UI_LOAD_STATE",			IKT_IPT,		IPT_UI_LOAD_STATE },
	{ "UI_ADD_CHEAT",			IKT_IPT,		IPT_UI_ADD_CHEAT },
	{ "UI_DELETE_CHEAT",		IKT_IPT,		IPT_UI_DELETE_CHEAT },
	{ "UI_SAVE_CHEAT",			IKT_IPT,		IPT_UI_SAVE_CHEAT },
	{ "UI_WATCH_VALUE",			IKT_IPT,		IPT_UI_WATCH_VALUE },
	{ "UI_EDIT_CHEAT",			IKT_IPT,		IPT_UI_EDIT_CHEAT },
	{ "UI_TOGGLE_CROSSHAIR",	IKT_IPT,		IPT_UI_TOGGLE_CROSSHAIR },
	{ "START1",					IKT_IPT,		IPT_START1 },
	{ "START2",					IKT_IPT,		IPT_START2 },
	{ "START3",					IKT_IPT,		IPT_START3 },
	{ "START4",					IKT_IPT,		IPT_START4 },
	{ "COIN1",					IKT_IPT,		IPT_COIN1 },
	{ "COIN2",					IKT_IPT,		IPT_COIN2 },
	{ "COIN3",					IKT_IPT,		IPT_COIN3 },
	{ "COIN4",					IKT_IPT,		IPT_COIN4 },
	{ "SERVICE1",				IKT_IPT,		IPT_SERVICE1 },
	{ "SERVICE2",				IKT_IPT,		IPT_SERVICE2 },
	{ "SERVICE3",				IKT_IPT,		IPT_SERVICE3 },
	{ "SERVICE4",				IKT_IPT,		IPT_SERVICE4 },
	{ "TILT",					IKT_IPT,		IPT_TILT },

	{ "P1_JOYSTICK_UP",			IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICK_UP },
	{ "P1_JOYSTICK_DOWN",		IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICK_DOWN },
	{ "P1_JOYSTICK_LEFT",		IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICK_LEFT },
	{ "P1_JOYSTICK_RIGHT",		IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICK_RIGHT },
	{ "P1_BUTTON1",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON1 },
	{ "P1_BUTTON2",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON2 },
	{ "P1_BUTTON3",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON3 },
	{ "P1_BUTTON4",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON4 },
	{ "P1_BUTTON5",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON5 },
	{ "P1_BUTTON6",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON6 },
	{ "P1_BUTTON7",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON7 },
	{ "P1_BUTTON8",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON8 },
	{ "P1_BUTTON9",				IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON9 },
	{ "P1_BUTTON10",			IKT_IPT,		IPF_PLAYER1 | IPT_BUTTON10 },
	{ "P1_JOYSTICKRIGHT_UP",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKRIGHT_UP },
	{ "P1_JOYSTICKRIGHT_DOWN",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKRIGHT_DOWN },
	{ "P1_JOYSTICKRIGHT_LEFT",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKRIGHT_LEFT },
	{ "P1_JOYSTICKRIGHT_RIGHT",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKRIGHT_RIGHT },
	{ "P1_JOYSTICKLEFT_UP",		IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKLEFT_UP },
	{ "P1_JOYSTICKLEFT_DOWN",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKLEFT_DOWN },
	{ "P1_JOYSTICKLEFT_LEFT",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKLEFT_LEFT },
	{ "P1_JOYSTICKLEFT_RIGHT",	IKT_IPT,		IPF_PLAYER1 | IPT_JOYSTICKLEFT_RIGHT },

	{ "P2_JOYSTICK_UP",			IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICK_UP },
	{ "P2_JOYSTICK_DOWN",		IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICK_DOWN },
	{ "P2_JOYSTICK_LEFT",		IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICK_LEFT },
	{ "P2_JOYSTICK_RIGHT",		IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICK_RIGHT },
	{ "P2_BUTTON1",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON1 },
	{ "P2_BUTTON2",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON2 },
	{ "P2_BUTTON3",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON3 },
	{ "P2_BUTTON4",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON4 },
	{ "P2_BUTTON5",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON5 },
	{ "P2_BUTTON6",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON6 },
	{ "P2_BUTTON7",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON7 },
	{ "P2_BUTTON8",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON8 },
	{ "P2_BUTTON9",				IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON9 },
	{ "P2_BUTTON10",			IKT_IPT,		IPF_PLAYER2 | IPT_BUTTON10 },
	{ "P2_JOYSTICKRIGHT_UP",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKRIGHT_UP },
	{ "P2_JOYSTICKRIGHT_DOWN",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKRIGHT_DOWN },
	{ "P2_JOYSTICKRIGHT_LEFT",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKRIGHT_LEFT },
	{ "P2_JOYSTICKRIGHT_RIGHT",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKRIGHT_RIGHT },
	{ "P2_JOYSTICKLEFT_UP",		IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKLEFT_UP },
	{ "P2_JOYSTICKLEFT_DOWN",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKLEFT_DOWN },
	{ "P2_JOYSTICKLEFT_LEFT",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKLEFT_LEFT },
	{ "P2_JOYSTICKLEFT_RIGHT",	IKT_IPT,		IPF_PLAYER2 | IPT_JOYSTICKLEFT_RIGHT },

	{ "P3_JOYSTICK_UP",			IKT_IPT,		IPF_PLAYER3 | IPT_JOYSTICK_UP },
	{ "P3_JOYSTICK_DOWN",		IKT_IPT,		IPF_PLAYER3 | IPT_JOYSTICK_DOWN },
	{ "P3_JOYSTICK_LEFT",		IKT_IPT,		IPF_PLAYER3 | IPT_JOYSTICK_LEFT },
	{ "P3_JOYSTICK_RIGHT",		IKT_IPT,		IPF_PLAYER3 | IPT_JOYSTICK_RIGHT },
	{ "P3_BUTTON1",				IKT_IPT,		IPF_PLAYER3 | IPT_BUTTON1 },
	{ "P3_BUTTON2",				IKT_IPT,		IPF_PLAYER3 | IPT_BUTTON2 },
	{ "P3_BUTTON3",				IKT_IPT,		IPF_PLAYER3 | IPT_BUTTON3 },
	{ "P3_BUTTON4",				IKT_IPT,		IPF_PLAYER3 | IPT_BUTTON4 },

	{ "P4_JOYSTICK_UP",			IKT_IPT,		IPF_PLAYER4 | IPT_JOYSTICK_UP },
	{ "P4_JOYSTICK_DOWN",		IKT_IPT,		IPF_PLAYER4 | IPT_JOYSTICK_DOWN },
	{ "P4_JOYSTICK_LEFT",		IKT_IPT,		IPF_PLAYER4 | IPT_JOYSTICK_LEFT },
	{ "P4_JOYSTICK_RIGHT",		IKT_IPT,		IPF_PLAYER4 | IPT_JOYSTICK_RIGHT },
	{ "P4_BUTTON1",				IKT_IPT,		IPF_PLAYER4 | IPT_BUTTON1 },
	{ "P4_BUTTON2",				IKT_IPT,		IPF_PLAYER4 | IPT_BUTTON2 },
	{ "P4_BUTTON3",				IKT_IPT,		IPF_PLAYER4 | IPT_BUTTON3 },
	{ "P4_BUTTON4",				IKT_IPT,		IPF_PLAYER4 | IPT_BUTTON4 },

	{ "P1_PEDAL",				IKT_IPT,		IPF_PLAYER1 | IPT_PEDAL },
	{ "P1_PEDAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER1 | IPT_PEDAL },
	{ "P2_PEDAL",				IKT_IPT,		IPF_PLAYER2 | IPT_PEDAL },
	{ "P2_PEDAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER2 | IPT_PEDAL },
	{ "P3_PEDAL",				IKT_IPT,		IPF_PLAYER3 | IPT_PEDAL },
	{ "P3_PEDAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER3 | IPT_PEDAL },
	{ "P4_PEDAL",				IKT_IPT,		IPF_PLAYER4 | IPT_PEDAL },
	{ "P4_PEDAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER4 | IPT_PEDAL },

	{ "P1_PEDAL2",				IKT_IPT,		IPF_PLAYER1 | IPT_PEDAL2 },
	{ "P1_PEDAL2_EXT",			IKT_IPT_EXT,	IPF_PLAYER1 | IPT_PEDAL2 },
	{ "P2_PEDAL2",				IKT_IPT,		IPF_PLAYER2 | IPT_PEDAL2 },
	{ "P2_PEDAL2_EXT",			IKT_IPT_EXT,	IPF_PLAYER2 | IPT_PEDAL2 },
	{ "P3_PEDAL2",				IKT_IPT,		IPF_PLAYER3 | IPT_PEDAL2 },
	{ "P3_PEDAL2_EXT",			IKT_IPT_EXT,	IPF_PLAYER3 | IPT_PEDAL2 },
	{ "P4_PEDAL2",				IKT_IPT,		IPF_PLAYER4 | IPT_PEDAL2 },
	{ "P4_PEDAL2_EXT",			IKT_IPT_EXT,	IPF_PLAYER4 | IPT_PEDAL2 },

	{ "P1_PADDLE",				IKT_IPT,		IPF_PLAYER1 | IPT_PADDLE },
	{ "P1_PADDLE_EXT",			IKT_IPT_EXT,	IPF_PLAYER1 | IPT_PADDLE },
	{ "P2_PADDLE",				IKT_IPT,		IPF_PLAYER2 | IPT_PADDLE },
	{ "P2_PADDLE_EXT",			IKT_IPT_EXT,	IPF_PLAYER2 | IPT_PADDLE },
	{ "P3_PADDLE",				IKT_IPT,		IPF_PLAYER3 | IPT_PADDLE },
	{ "P3_PADDLE_EXT",			IKT_IPT_EXT,	IPF_PLAYER3 | IPT_PADDLE },
	{ "P4_PADDLE",				IKT_IPT,		IPF_PLAYER4 | IPT_PADDLE },
	{ "P4_PADDLE_EXT",			IKT_IPT_EXT,	IPF_PLAYER4 | IPT_PADDLE },
	{ "P1_PADDLE_V",			IKT_IPT,		IPF_PLAYER1 | IPT_PADDLE_V },
	{ "P1_PADDLE_V_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_PADDLE_V },
	{ "P2_PADDLE_V",			IKT_IPT,		IPF_PLAYER2 | IPT_PADDLE_V },
	{ "P2_PADDLE_V_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_PADDLE_V },
	{ "P3_PADDLE_V",			IKT_IPT,		IPF_PLAYER3 | IPT_PADDLE_V },
	{ "P3_PADDLE_V_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_PADDLE_V },
	{ "P4_PADDLE_V",			IKT_IPT,		IPF_PLAYER4 | IPT_PADDLE_V },
	{ "P4_PADDLE_V_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_PADDLE_V },

	{ "P1_DIAL",				IKT_IPT,		IPF_PLAYER1 | IPT_DIAL },
	{ "P1_DIAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER1 | IPT_DIAL },
	{ "P2_DIAL",				IKT_IPT,		IPF_PLAYER2 | IPT_DIAL },
	{ "P2_DIAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER2 | IPT_DIAL },
	{ "P3_DIAL",				IKT_IPT,		IPF_PLAYER3 | IPT_DIAL },
	{ "P3_DIAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER3 | IPT_DIAL },
	{ "P4_DIAL",				IKT_IPT,		IPF_PLAYER4 | IPT_DIAL },
	{ "P4_DIAL_EXT",			IKT_IPT_EXT,	IPF_PLAYER4 | IPT_DIAL },
	{ "P1_DIAL_V",				IKT_IPT,		IPF_PLAYER1 | IPT_DIAL_V },
	{ "P1_DIAL_V_EXT",			IKT_IPT_EXT,	IPF_PLAYER1 | IPT_DIAL_V },
	{ "P2_DIAL_V",				IKT_IPT,		IPF_PLAYER2 | IPT_DIAL_V },
	{ "P2_DIAL_V_EXT",			IKT_IPT_EXT,	IPF_PLAYER2 | IPT_DIAL_V },
	{ "P3_DIAL_V",				IKT_IPT,		IPF_PLAYER3 | IPT_DIAL_V },
	{ "P3_DIAL_V_EXT",			IKT_IPT_EXT,	IPF_PLAYER3 | IPT_DIAL_V },
	{ "P4_DIAL_V",				IKT_IPT,		IPF_PLAYER4 | IPT_DIAL_V },
	{ "P4_DIAL_V_EXT",			IKT_IPT_EXT,	IPF_PLAYER4 | IPT_DIAL_V },

	{ "P1_TRACKBALL_X",			IKT_IPT,		IPF_PLAYER1 | IPT_TRACKBALL_X },
	{ "P1_TRACKBALL_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_TRACKBALL_X },
	{ "P2_TRACKBALL_X",			IKT_IPT,		IPF_PLAYER2 | IPT_TRACKBALL_X },
	{ "P2_TRACKBALL_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_TRACKBALL_X },
	{ "P3_TRACKBALL_X",			IKT_IPT,		IPF_PLAYER3 | IPT_TRACKBALL_X },
	{ "P3_TRACKBALL_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_TRACKBALL_X },
	{ "P4_TRACKBALL_X",			IKT_IPT,		IPF_PLAYER4 | IPT_TRACKBALL_X },
	{ "P4_TRACKBALL_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_TRACKBALL_X },

	{ "P1_TRACKBALL_Y",			IKT_IPT,		IPF_PLAYER1 | IPT_TRACKBALL_Y },
	{ "P1_TRACKBALL_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_TRACKBALL_Y },
	{ "P2_TRACKBALL_Y",			IKT_IPT,		IPF_PLAYER2 | IPT_TRACKBALL_Y },
	{ "P2_TRACKBALL_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_TRACKBALL_Y },
	{ "P3_TRACKBALL_Y",			IKT_IPT,		IPF_PLAYER3 | IPT_TRACKBALL_Y },
	{ "P3_TRACKBALL_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_TRACKBALL_Y },
	{ "P4_TRACKBALL_Y",			IKT_IPT,		IPF_PLAYER4 | IPT_TRACKBALL_Y },
	{ "P4_TRACKBALL_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_TRACKBALL_Y },

	{ "P1_AD_STICK_X",			IKT_IPT,		IPF_PLAYER1 | IPT_AD_STICK_X },
	{ "P1_AD_STICK_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_AD_STICK_X },
	{ "P2_AD_STICK_X",			IKT_IPT,		IPF_PLAYER2 | IPT_AD_STICK_X },
	{ "P2_AD_STICK_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_AD_STICK_X },
	{ "P3_AD_STICK_X",			IKT_IPT,		IPF_PLAYER3 | IPT_AD_STICK_X },
	{ "P3_AD_STICK_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_AD_STICK_X },
	{ "P4_AD_STICK_X",			IKT_IPT,		IPF_PLAYER4 | IPT_AD_STICK_X },
	{ "P4_AD_STICK_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_AD_STICK_X },

	{ "P1_AD_STICK_Y",			IKT_IPT,		IPF_PLAYER1 | IPT_AD_STICK_Y },
	{ "P1_AD_STICK_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_AD_STICK_Y },
	{ "P2_AD_STICK_Y",			IKT_IPT,		IPF_PLAYER2 | IPT_AD_STICK_Y },
	{ "P2_AD_STICK_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_AD_STICK_Y },
	{ "P3_AD_STICK_Y",			IKT_IPT,		IPF_PLAYER3 | IPT_AD_STICK_Y },
	{ "P3_AD_STICK_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_AD_STICK_Y },
	{ "P4_AD_STICK_Y",			IKT_IPT,		IPF_PLAYER4 | IPT_AD_STICK_Y },
	{ "P4_AD_STICK_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_AD_STICK_Y },

	{ "P1_LIGHTGUN_X",			IKT_IPT,		IPF_PLAYER1 | IPT_LIGHTGUN_X },
	{ "P1_LIGHTGUN_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_LIGHTGUN_X },
	{ "P2_LIGHTGUN_X",			IKT_IPT,		IPF_PLAYER2 | IPT_LIGHTGUN_X },
	{ "P2_LIGHTGUN_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_LIGHTGUN_X },
	{ "P3_LIGHTGUN_X",			IKT_IPT,		IPF_PLAYER3 | IPT_LIGHTGUN_X },
	{ "P3_LIGHTGUN_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_LIGHTGUN_X },
	{ "P4_LIGHTGUN_X",			IKT_IPT,		IPF_PLAYER4 | IPT_LIGHTGUN_X },
	{ "P4_LIGHTGUN_X_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_LIGHTGUN_X },

	{ "P1_LIGHTGUN_Y",			IKT_IPT,		IPF_PLAYER1 | IPT_LIGHTGUN_Y },
	{ "P1_LIGHTGUN_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_LIGHTGUN_Y },
	{ "P2_LIGHTGUN_Y",			IKT_IPT,		IPF_PLAYER2 | IPT_LIGHTGUN_Y },
	{ "P2_LIGHTGUN_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_LIGHTGUN_Y },
	{ "P3_LIGHTGUN_Y",			IKT_IPT,		IPF_PLAYER3 | IPT_LIGHTGUN_Y },
	{ "P3_LIGHTGUN_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_LIGHTGUN_Y },
	{ "P4_LIGHTGUN_Y",			IKT_IPT,		IPF_PLAYER4 | IPT_LIGHTGUN_Y },
	{ "P4_LIGHTGUN_Y_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_LIGHTGUN_Y },

	{ "P1_AD_STICK_Z",			IKT_IPT,		IPF_PLAYER1 | IPT_AD_STICK_Z },
	{ "P1_AD_STICK_Z_EXT",		IKT_IPT_EXT,	IPF_PLAYER1 | IPT_AD_STICK_Z },
	{ "P2_AD_STICK_Z",			IKT_IPT,		IPF_PLAYER2 | IPT_AD_STICK_Z },
	{ "P2_AD_STICK_Z_EXT",		IKT_IPT_EXT,	IPF_PLAYER2 | IPT_AD_STICK_Z },
	{ "P3_AD_STICK_Z",			IKT_IPT,		IPF_PLAYER3 | IPT_AD_STICK_Z },
	{ "P3_AD_STICK_Z_EXT",		IKT_IPT_EXT,	IPF_PLAYER3 | IPT_AD_STICK_Z },
	{ "P4_AD_STICK_Z",			IKT_IPT,		IPF_PLAYER4 | IPT_AD_STICK_Z },
	{ "P4_AD_STICK_Z_EXT",		IKT_IPT_EXT,	IPF_PLAYER4 | IPT_AD_STICK_Z },

	{ "OSD_1",					IKT_IPT,		IPT_OSD_1 },
	{ "OSD_2",					IKT_IPT,		IPT_OSD_2 },
	{ "OSD_3",					IKT_IPT,		IPT_OSD_3 },
	{ "OSD_4",					IKT_IPT,		IPT_OSD_4 },

	{ "UNKNOWN",				IKT_IPT,		IPT_UNKNOWN },
	{ "END",					IKT_IPT,		IPT_END },

	{ "",						0,	0 }
};

int num_ik = sizeof(input_keywords)/sizeof(struct ik);

/***************************************************************************/
/* Generic IO */

static int readint(void *f,UINT32 *num)
{
	unsigned i;

	*num = 0;
	for (i = 0;i < sizeof(UINT32);i++)
	{
		unsigned char c;


		*num <<= 8;
		if (osd_fread(f,&c,1) != 1)
			return -1;
		*num |= c;
	}

	return 0;
}

static void writeint(void *f,UINT32 num)
{
	unsigned i;

	for (i = 0;i < sizeof(UINT32);i++)
	{
		unsigned char c;


		c = (num >> 8 * (sizeof(UINT32)-1)) & 0xff;
		osd_fwrite(f,&c,1);
		num <<= 8;
	}
}

static int readword(void *f,UINT16 *num)
{
	unsigned i;
	int res;

	res = 0;
	for (i = 0;i < sizeof(UINT16);i++)
	{
		unsigned char c;


		res <<= 8;
		if (osd_fread(f,&c,1) != 1)
			return -1;
		res |= c;
	}

	*num = res;
	return 0;
}

static void writeword(void *f,UINT16 num)
{
	unsigned i;

	for (i = 0;i < sizeof(UINT16);i++)
	{
		unsigned char c;


		c = (num >> 8 * (sizeof(UINT16)-1)) & 0xff;
		osd_fwrite(f,&c,1);
		num <<= 8;
	}
}

#ifndef NOLEGACY
#include "legacy.h"
#endif

static int seq_read_ver_8(void* f, InputSeq* seq)
{
	int j,len;
	UINT32 i;
	UINT16 w;

	if (readword(f,&w) != 0)
		return -1;

	len = w;
	seq_set_0(seq);
	for(j=0;j<len;++j)
	{
		if (readint(f,&i) != 0)
 			return -1;
		(*seq)[j] = savecode_to_code(i);
 	}

 	return 0;
  }

static int seq_read(void* f, InputSeq* seq, int ver)
  {
#ifdef NOLEGACY
	if (ver==8)
		return seq_read_ver_8(f,seq);
#else
	switch (ver) {
		case 5 : return seq_read_ver_5(f,seq);
		case 6 : return seq_read_ver_6(f,seq);
		case 7 : return seq_read_ver_7(f,seq);
		case 8 : return seq_read_ver_8(f,seq);
	}
#endif
	return -1;
  }

static void seq_write(void* f, InputSeq* seq)
  {
	int j,len;
        for(len=0;len<SEQ_MAX;++len)
		if ((*seq)[len] == CODE_NONE)
			break;
	writeword(f,len);
	for(j=0;j<len;++j)
		writeint(f, code_to_savecode( (*seq)[j] ));
  }

/***************************************************************************/
/* Load */

static void load_default_keys(void)
{
	void *f;


#ifdef JMAME // AUTO_FIRE
	memset(autopressed, 0, MAX_INPUT_BITS);
	autofire_enable = 0;

	if (options.autofiredelay <= 0)
		options.autofiredelay = 1;
#endif

	osd_customize_inputport_defaults(inputport_defaults);
	memcpy(inputport_defaults_backup,inputport_defaults,sizeof(inputport_defaults));

	if ((f = osd_fopen("default",0,OSD_FILETYPE_CONFIG,0)) != 0)
	{
		char buf[8];
		int version;

		/* read header */
		if (osd_fread(f,buf,8) != 8)
			goto getout;

		if (memcmp(buf,MAMEDEFSTRING_V5,8) == 0)
			version = 5;
		else if (memcmp(buf,MAMEDEFSTRING_V6,8) == 0)
			version = 6;
		else if (memcmp(buf,MAMEDEFSTRING_V7,8) == 0)
			version = 7;
		else if (memcmp(buf,MAMEDEFSTRING_V8,8) == 0)
			version = 8;
		else
			goto getout;	/* header invalid */

		for (;;)
		{
			UINT32 type;
			InputSeq def_seq;
			InputSeq seq;
			int i;

			if (readint(f,&type) != 0)
				goto getout;

			if (seq_read(f,&def_seq,version)!=0)
				goto getout;
			if (seq_read(f,&seq,version)!=0)
				goto getout;

			i = 0;
			while (inputport_defaults[i].type != IPT_END)
			{
				if (inputport_defaults[i].type == type)
				{
					/* load stored settings only if the default hasn't changed */
					if (seq_cmp(&inputport_defaults[i].seq,&def_seq)==0)
						seq_copy(&inputport_defaults[i].seq,&seq);
				}

				i++;
			}
		}

getout:
		osd_fclose(f);
	}
}

static void save_default_keys(void)
{
	void *f;


	if ((f = osd_fopen("default",0,OSD_FILETYPE_CONFIG,1)) != 0)
	{
		int i;


		/* write header */
		osd_fwrite(f,MAMEDEFSTRING_V8,8);

		i = 0;
		while (inputport_defaults[i].type != IPT_END)
		{
			if (inputport_defaults[i].type != IPT_OSD_RESERVED)
			{
				writeint(f,inputport_defaults[i].type);

				seq_write(f,&inputport_defaults_backup[i].seq);
				seq_write(f,&inputport_defaults[i].seq);
			}

			i++;
		}

		osd_fclose(f);
	}
	memcpy(inputport_defaults,inputport_defaults_backup,sizeof(inputport_defaults_backup));
}

static int input_port_read_ver_8(void *f,struct InputPort *in)
{
	UINT32 i;
	UINT16 w;
	if (readint(f,&i) != 0)
		return -1;
	in->type = i;

	if (readword(f,&w) != 0)
		return -1;
	in->mask = w;

	if (readword(f,&w) != 0)
		return -1;
	in->default_value = w;

	if (seq_read_ver_8(f,&in->seq) != 0)
		return -1;

	return 0;
}

static int input_port_read(void *f,struct InputPort *in, int ver)
{
#ifdef NOLEGACY
	if (ver==8)
		return input_port_read_ver_8(f,in);
#else
	switch (ver) {
		case 5 : return	input_port_read_ver_5(f,in);
		case 6 : return	input_port_read_ver_6(f,in);
		case 7 : return	input_port_read_ver_7(f,in);
		case 8 : return	input_port_read_ver_8(f,in);
	}
#endif
	return -1;
}

static void input_port_write(void *f,struct InputPort *in)
{
	writeint(f,in->type);
	writeword(f,in->mask);
	writeword(f,in->default_value);
	seq_write(f,&in->seq);
}


int load_input_port_settings(void)
{
	void *f;
#ifdef MAME_NET
    struct InputPort *in;
    int port, player;
#endif /* MAME_NET */


	load_default_keys();

#ifdef JMAME // VOLUME_AUTO_ADJUST
	volume_multiplier = 10 << 8;
#endif

	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,0)) != 0)
	{
#ifndef MAME_NET
		struct InputPort *in;
#endif
		unsigned int total,savedtotal;
		char buf[8];
		int i;
		int version;

		in = Machine->input_ports_default;

		/* calculate the size of the array */
		total = 0;
		while (in->type != IPT_END)
		{
			total++;
			in++;
		}

		/* read header */
		if (osd_fread(f,buf,8) != 8)
			goto getout;

		if (memcmp(buf,MAMECFGSTRING_V5,8) == 0)
			version = 5;
		else if (memcmp(buf,MAMECFGSTRING_V6,8) == 0)
			version = 6;
		else if (memcmp(buf,MAMECFGSTRING_V7,8) == 0)
			version = 7;
		else if (memcmp(buf,MAMECFGSTRING_V8,8) == 0)
			version = 8;
		else
			goto getout;	/* header invalid */

		/* read array size */
		if (readint(f,&savedtotal) != 0)
			goto getout;
		if (total != savedtotal)
			goto getout;	/* different size */

		/* read the original settings and compare them with the ones defined in the driver */
		in = Machine->input_ports_default;
		while (in->type != IPT_END)
		{
			struct InputPort saved;

			if (input_port_read(f,&saved,version) != 0)
				goto getout;

			if (in->mask != saved.mask ||
				in->default_value != saved.default_value ||
				in->type != saved.type ||
				seq_cmp(&in->seq,&saved.seq) !=0 )
			goto getout;	/* the default values are different */

			in++;
		}

		/* read the current settings */
		in = Machine->input_ports;
		while (in->type != IPT_END)
		{
			if (input_port_read(f,in,version) != 0)
				goto getout;
			in++;
		}

		/* Clear the coin & ticket counters/flags - LBO 042898 */
		for (i = 0; i < COIN_COUNTERS; i ++)
			coins[i] = lastcoin[i] = coinlockedout[i] = 0;
		dispensed_tickets = 0;

		/* read in the coin/ticket counters */
		for (i = 0; i < COIN_COUNTERS; i ++)
		{
			if (readint(f,&coins[i]) != 0)
				goto getout;
		}
		if (readint(f,&dispensed_tickets) != 0)
			goto getout;

#ifdef JMAME // AUTO_FIRE
		if (readint(f,&options.autofiredelay) != 0)
			goto getout;
#endif // JMAME

		mixer_read_config(f);
#ifdef JMAME // VOLUME_AUTO_ADJUST
		{
			INT32 n;

			if (osd_fread(f, &n, sizeof(INT32)) != 0)
				volume_multiplier = n;
		}
#endif

getout:
		osd_fclose(f);
	}

	/* All analog ports need initialization */
	{
		int i;
		for (i = 0; i < MAX_INPUT_PORTS; i++)
			input_analog_init[i] = 1;
	}
#ifdef MAME_NET
	/* Find out what port is used by what player and swap regular inputs */
	in = Machine->input_ports;

//	if (in->type == IPT_END) return; 	/* nothing to do */

	/* make sure the InputPort definition is correct */
//	if (in->type != IPT_PORT)
//	{
//		logerror("Error in InputPort definition: expecting PORT_START\n");
//		return;
//	}
//	else in++;
	in++;

	/* scan all the input ports */
	port = 0;
	while (in->type != IPT_END && port < MAX_INPUT_PORTS)
	{
		/* now check the input bits. */
		while (in->type != IPT_END && in->type != IPT_PORT)
		{
			if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING &&	/* skip dipswitch definitions */
				(in->type & ~IPF_MASK) != IPT_EXTENSION &&			/* skip analog extension fields */
				(in->type & IPF_UNUSED) == 0 &&						/* skip unused bits */
				!(!options.cheat && (in->type & IPF_CHEAT)) &&				/* skip cheats if cheats disabled */
				(in->type & ~IPF_MASK) != IPT_VBLANK &&				/* skip vblank stuff */
				((in->type & ~IPF_MASK) >= IPT_COIN1 &&				/* skip if coin input and it's locked out */
				(in->type & ~IPF_MASK) <= IPT_COIN4 &&
                 coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1]))
			{
				player = 0;
				if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
				else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
				else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;

				if (((in->type & ~IPF_MASK) > IPT_ANALOG_START)
					&& ((in->type & ~IPF_MASK) < IPT_ANALOG_END))
				{
					analog_player_port[port] = player;
				}
				if (((in->type & ~IPF_MASK) == IPT_BUTTON1) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON2) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON3) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON4) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_DOWN) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_DOWN) ||
 					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_DOWN) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_PADDLE) ||
					((in->type & ~IPF_MASK) == IPT_DIAL) ||
					((in->type & ~IPF_MASK) == IPT_TRACKBALL_X) ||
					((in->type & ~IPF_MASK) == IPT_TRACKBALL_Y) ||
					((in->type & ~IPF_MASK) == IPT_LIGHTGUN_X) ||
					((in->type & ~IPF_MASK) == IPT_LIGHTGUN_Y) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_X) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_Y) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_Z))
				{
					switch (default_player)
					{
						case 0:
							/* do nothing */
							break;
						case 1:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER2;
							}
							else if (player == 1)
							{
								in->type &= ~IPF_PLAYER2;
								in->type |= IPF_PLAYER1;
							}
							break;
						case 2:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER3;
							}
							else if (player == 2)
							{
								in->type &= ~IPF_PLAYER3;
								in->type |= IPF_PLAYER1;
							}
							break;
						case 3:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER4;
							}
							else if (player == 3)
							{
								in->type &= ~IPF_PLAYER4;
								in->type |= IPF_PLAYER1;
							}
							break;
					}
				}
			}
			in++;
		}
		port++;
		if (in->type == IPT_PORT) in++;
	}

	/* TODO: at this point the games should initialize peers to same as server */

#endif /* MAME_NET */

#ifdef JMAME // PLAYBACK_FIX
	if(playback) pback = 1; else pback = 0;
#endif

	init_analog_seq();

	update_input_ports();

	/* if we didn't find a saved config, return 0 so the main core knows that it */
	/* is the first time the game is run and it should diplay the disclaimer. */
	if (f) return 1;
	else return 0;
}

/***************************************************************************/
/* Save */

void save_input_port_settings(void)
{
	void *f;
#ifdef MAME_NET
	struct InputPort *in;
	int port, player;

	/* Swap input port definitions back to defaults */
	in = Machine->input_ports;

	if (in->type == IPT_END) return; 	/* nothing to do */

	/* make sure the InputPort definition is correct */
	if (in->type != IPT_PORT)
	{
		logerror("Error in InputPort definition: expecting PORT_START\n");
		return;
	}
	else in++;

	/* scan all the input ports */
	port = 0;
	while (in->type != IPT_END && port < MAX_INPUT_PORTS)
	{
		/* now check the input bits. */
		while (in->type != IPT_END && in->type != IPT_PORT)
		{
			if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING &&	/* skip dipswitch definitions */
				(in->type & ~IPF_MASK) != IPT_EXTENSION &&			/* skip analog extension fields */
				(in->type & IPF_UNUSED) == 0 &&						/* skip unused bits */
				!(!options.cheat && (in->type & IPF_CHEAT)) &&				/* skip cheats if cheats disabled */
				(in->type & ~IPF_MASK) != IPT_VBLANK &&				/* skip vblank stuff */
				((in->type & ~IPF_MASK) >= IPT_COIN1 &&				/* skip if coin input and it's locked out */
				(in->type & ~IPF_MASK) <= IPT_COIN4 &&
                 coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1]))
			{
				player = 0;
				if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
				else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
				else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;

				if (((in->type & ~IPF_MASK) == IPT_BUTTON1) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON2) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON3) ||
					((in->type & ~IPF_MASK) == IPT_BUTTON4) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_DOWN) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICK_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_DOWN) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_UP) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_DOWN) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_LEFT) ||
					((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_RIGHT) ||
					((in->type & ~IPF_MASK) == IPT_PADDLE) ||
					((in->type & ~IPF_MASK) == IPT_DIAL) ||
					((in->type & ~IPF_MASK) == IPT_TRACKBALL_X) ||
					((in->type & ~IPF_MASK) == IPT_TRACKBALL_Y) ||
					((in->type & ~IPF_MASK) == IPT_LIGHTGUN_X) ||
					((in->type & ~IPF_MASK) == IPT_LIGHTGUN_Y) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_X) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_Y) ||
					((in->type & ~IPF_MASK) == IPT_AD_STICK_Z))
				{
					switch (default_player)
					{
						case 0:
							/* do nothing */
							analog_player_port[port] = player;
							break;
						case 1:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER2;
								analog_player_port[port] = 1;
							}
							else if (player == 1)
							{
								in->type &= ~IPF_PLAYER2;
								in->type |= IPF_PLAYER1;
								analog_player_port[port] = 0;
							}
							break;
						case 2:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER3;
								analog_player_port[port] = 2;
							}
							else if (player == 2)
							{
								in->type &= ~IPF_PLAYER3;
								in->type |= IPF_PLAYER1;
								analog_player_port[port] = 0;
							}
							break;
						case 3:
							if (player == 0)
							{
								in->type &= ~IPF_PLAYER1;
								in->type |= IPF_PLAYER4;
								analog_player_port[port] = 3;
							}
							else if (player == 3)
							{
								in->type &= ~IPF_PLAYER4;
								in->type |= IPF_PLAYER1;
								analog_player_port[port] = 0;
							}
							break;
					}
				}
			}
			in++;
		}
		port++;
		if (in->type == IPT_PORT) in++;
	}
#endif /* MAME_NET */

	save_default_keys();

	if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,1)) != 0)
	{
#ifndef MAME_NET
		struct InputPort *in;
#endif /* MAME_NET */
		int total;
		int i;


		in = Machine->input_ports_default;

		/* calculate the size of the array */
		total = 0;
		while (in->type != IPT_END)
		{
			total++;
			in++;
		}

		/* write header */
		osd_fwrite(f,MAMECFGSTRING_V8,8);
		/* write array size */
		writeint(f,total);
		/* write the original settings as defined in the driver */
		in = Machine->input_ports_default;
		while (in->type != IPT_END)
		{
			input_port_write(f,in);
			in++;
		}
		/* write the current settings */
		in = Machine->input_ports;
		while (in->type != IPT_END)
		{
			input_port_write(f,in);
			in++;
		}

		/* write out the coin/ticket counters for this machine - LBO 042898 */
		for (i = 0; i < COIN_COUNTERS; i ++)
			writeint(f,coins[i]);
		writeint(f,dispensed_tickets);
#ifdef JMAME // AUTO_FIRE
		writeint(f,options.autofiredelay);
#endif

		mixer_write_config(f);

#ifdef JMAME // VOLUME_AUTO_ADJUST
		osd_fwrite(f, &volume_multiplier, sizeof(INT32));
#endif

		osd_fclose(f);
	}
}

#ifdef JAPANESE
struct fix_name_t
{
	const char *org_name;
	const char *jpn_name;
};

static struct fix_name_t fix_port_names[] =
{
	/* Input (mahjong) */

	{ "Chi",			"チー" },
	{ "Pon",			"ポン" },
	{ "Kan",			"カン" },
	{ "Reach",			"リーチ" },
	{ "Ron",			"ロン" },

	{ "P1 Chi",			"P1 チー" },
	{ "P1 Pon",			"P1 ポン" },
	{ "P1 Kan",			"P1 カン" },
	{ "P1 Reach",			"P1 リーチ" },
	{ "P1 Ron",			"P1 ロン" },

	{ "P2 Chi",			"P2 チー" },
	{ "P2 Pon",			"P2 ポン" },
	{ "P2 Kan",			"P2 カン" },
	{ "P2 Reach",			"P2 リーチ" },
	{ "P2 Ron",			"P2 ロン" },

	/* Dip (\src\drivers\neogeo.c) */

	{ "Test Switch",		"テストスイッチ" },
	{ "Coin Chutes?",		"コイン投入数？" },
	{ "Autofire (in some games)",	"連射 (いくつかのゲームで有効)" },
	{ "COMM Setting",		"通信設定" },
	{ "Freeze",			"フリーズ" },
	{ "Territory",			"地域" },
	{ "Machine Mode",		"マシンモード" },

	/* Dip (\src\drivers\toaplan2.c) */

	{ "Credits to Start",		"スタートに必要なクレジット数" },
	{ "Allow Continue",		"コンティニューあり" },
	{ "Stage Edit",			"ステージエディット" },
	{ "Invulnerability",		"無敵" },

	{ 0, 0 }
};

static const char *input_port_name_fix(const char *name)
{
	int i = 0;

	if (name == NULL)
		return name;

	while (fix_port_names[i].org_name)
	{
		if (!stricmp(name, fix_port_names[i].org_name))
			return fix_port_names[i].jpn_name;
		i++;
	}
	return name;
}
#endif



/* Note that the following 3 routines have slightly different meanings with analog ports */
const char *input_port_name(const struct InputPort *in)
{
	int i;
	unsigned type;

#ifdef JAPANESE
	if (in->name != IP_NAME_DEFAULT) return input_port_name_fix(in->name);
#else
	if (in->name != IP_NAME_DEFAULT) return in->name;
#endif

	i = 0;

	if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
		type = (in-1)->type & (~IPF_MASK | IPF_PLAYERMASK);
	else
		type = in->type & (~IPF_MASK | IPF_PLAYERMASK);

	while (inputport_defaults[i].type != IPT_END &&
			inputport_defaults[i].type != type)
		i++;

	if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
		return inputport_defaults[i+1].name;
	else
		return inputport_defaults[i].name;
}

InputSeq* input_port_type_seq(int type)
{
	unsigned i;

	i = 0;

	while (inputport_defaults[i].type != IPT_END &&
			inputport_defaults[i].type != type)
		i++;

	return &inputport_defaults[i].seq;
}

InputSeq* input_port_seq(const struct InputPort *in)
{
	int i,type;

	static InputSeq ip_none = SEQ_DEF_1(CODE_NONE);

	while (seq_get_1((InputSeq*)&in->seq) == CODE_PREVIOUS) in--;

	if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
	{
		type = (in-1)->type & (~IPF_MASK | IPF_PLAYERMASK);
		/* if port is disabled, or cheat with cheats disabled, return no key */
		if (((in-1)->type & IPF_UNUSED) || (!options.cheat && ((in-1)->type & IPF_CHEAT)))
			return &ip_none;
	}
	else
	{
		type = in->type & (~IPF_MASK | IPF_PLAYERMASK);
		/* if port is disabled, or cheat with cheats disabled, return no key */
		if ((in->type & IPF_UNUSED) || (!options.cheat && (in->type & IPF_CHEAT)))
			return &ip_none;
	}

	if (seq_get_1((InputSeq*)&in->seq) != CODE_DEFAULT)
		return (InputSeq*)&in->seq;

	i = 0;

	while (inputport_defaults[i].type != IPT_END &&
			inputport_defaults[i].type != type)
		i++;

	if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
		return &inputport_defaults[i+1].seq;
	else
		return &inputport_defaults[i].seq;
}

void update_analog_port(int port)
{
	struct InputPort *in;
	int current, delta, type, sensitivity, min, max, default_value;
	int axis, is_stick, is_gun, check_bounds;
	InputSeq* incseq;
	InputSeq* decseq;
	int keydelta;
	int player;

	/* get input definition */
	in = input_analog[port];

	/* if we're not cheating and this is a cheat-only port, bail */
	if (!options.cheat && (in->type & IPF_CHEAT)) return;
	type=(in->type & ~IPF_MASK);

	decseq = input_port_seq(in);
	incseq = input_port_seq(in+1);

	keydelta = IP_GET_DELTA(in);

	switch (type)
	{
		case IPT_PADDLE:
			axis = X_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_PADDLE_V:
			axis = Y_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_DIAL:
			axis = X_AXIS; is_stick = 0; is_gun=0; check_bounds = 0; break;
		case IPT_DIAL_V:
			axis = Y_AXIS; is_stick = 0; is_gun=0; check_bounds = 0; break;
		case IPT_TRACKBALL_X:
			axis = X_AXIS; is_stick = 0; is_gun=0; check_bounds = 0; break;
		case IPT_TRACKBALL_Y:
			axis = Y_AXIS; is_stick = 0; is_gun=0; check_bounds = 0; break;
		case IPT_AD_STICK_X:
			axis = X_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_AD_STICK_Y:
			axis = Y_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_AD_STICK_Z:
			axis = Z_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_LIGHTGUN_X:
			axis = X_AXIS; is_stick = 1; is_gun=1; check_bounds = 1; break;
		case IPT_LIGHTGUN_Y:
			axis = Y_AXIS; is_stick = 1; is_gun=1; check_bounds = 1; break;
		case IPT_PEDAL:
			axis = PEDAL_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		case IPT_PEDAL2:
			axis = Z_AXIS; is_stick = 1; is_gun=0; check_bounds = 1; break;
		default:
			/* Use some defaults to prevent crash */
			axis = X_AXIS; is_stick = 0; is_gun=0; check_bounds = 0;
			logerror("Oops, polling non analog device in update_analog_port()????\n");
	}


	sensitivity = IP_GET_SENSITIVITY(in);
	min = IP_GET_MIN(in);
	max = IP_GET_MAX(in);
	default_value = in->default_value * 100 / sensitivity;
	/* extremes can be either signed or unsigned */
	if (min > max)
	{
		if (in->mask > 0xff) min = min - 0x10000;
		else min = min - 0x100;
	}

	input_analog_previous_value[port] = input_analog_current_value[port];

	/* if IPF_CENTER go back to the default position */
	/* sticks are handled later... */
	if ((in->type & IPF_CENTER) && (!is_stick))
		input_analog_current_value[port] = in->default_value * 100 / sensitivity;

	current = input_analog_current_value[port];

	delta = 0;

	switch (in->type & IPF_PLAYERMASK)
	{
		case IPF_PLAYER2:          player = 1; break;
		case IPF_PLAYER3:          player = 2; break;
		case IPF_PLAYER4:          player = 3; break;
		case IPF_PLAYER1: default: player = 0; break;
	}

	delta = mouse_delta_axis[player][axis];

	if (seq_pressed(decseq)) delta -= keydelta;

	if (type != IPT_PEDAL && type != IPT_PEDAL2)
	{
		if (seq_pressed(incseq)) delta += keydelta;
	}
	else
	{
		/* is this cheesy or what? */
		if (!delta && seq_get_1(incseq) == KEYCODE_Y) delta += keydelta;
		delta = -delta;
	}

	if (in->type & IPF_REVERSE) delta = -delta;

	if (is_gun)
	{
		/* The OSD lightgun call should return the delta from the middle of the screen
		when the gun is fired (not the absolute pixel value), and 0 when the gun is
		inactive.  We take advantage of this to provide support for other controllers
		in place of a physical lightgun.  When the OSD lightgun returns 0, then control
		passes through to the analog joystick, and mouse, in that order.  When the OSD
		lightgun returns a value it overrides both mouse & analog joystick.

		The value returned by the OSD layer should be -128 to 128, same as analog
		joysticks.

		There is an ugly hack to stop scaling of lightgun returned values.  It really
		needs rewritten...
		*/
		if (axis == X_AXIS) {
			if (lightgun_delta_axis[player][X_AXIS] || lightgun_delta_axis[player][Y_AXIS]) {
				analog_previous_axis[player][X_AXIS]=0;
				analog_current_axis[player][X_AXIS]=lightgun_delta_axis[player][X_AXIS];
				input_analog_scale[port]=0;
				sensitivity=100;
			}
		}
		else
		{
			if (lightgun_delta_axis[player][X_AXIS] || lightgun_delta_axis[player][Y_AXIS]) {
				analog_previous_axis[player][Y_AXIS]=0;
				analog_current_axis[player][Y_AXIS]=lightgun_delta_axis[player][Y_AXIS];
				input_analog_scale[port]=0;
				sensitivity=100;
			}
		}
	}

	if (is_stick)
	{
		int new, prev;

		/* center stick */
		if ((delta == 0) && (in->type & IPF_CENTER))
		{
			if (current > default_value)
			delta = -100 / sensitivity;
			if (current < default_value)
			delta = 100 / sensitivity;
		}

		/* An analog joystick which is not at zero position (or has just */
		/* moved there) takes precedence over all other computations */
		/* analog_x/y holds values from -128 to 128 (yes, 128, not 127) */

		new  = analog_current_axis[player][axis];
		prev = analog_previous_axis[player][axis];

		if ((new != 0) || (new-prev != 0))
		{
			delta=0;

			/* for pedals, need to change to possitive number */
			/* and, if needed, reverse pedal input */
			if (type == IPT_PEDAL || type == IPT_PEDAL2)
			{
				new  = -new;
				prev = -prev;
				if (in->type & IPF_REVERSE)		// a reversed pedal is diff than normal reverse
				{								// 128 = no gas, 0 = all gas
					new  = 128-new;				// the default "new=-new" doesn't handle this
					prev = 128-prev;
				}
			}
			else if (in->type & IPF_REVERSE)
			{
				new  = -new;
				prev = -prev;
			}

			/* apply sensitivity using a logarithmic scale */
			if (in->mask > 0xff)
			{
				if (new > 0)
				{
					current = (pow(new / 32768.0, 100.0 / sensitivity) * (max-in->default_value)
							+ in->default_value) * 100 / sensitivity;
				}
				else
				{
					current = (pow(-new / 32768.0, 100.0 / sensitivity) * (min-in->default_value)
							+ in->default_value) * 100 / sensitivity;
				}
			}
			else
			{
				if (new > 0)
				{
					current = (pow(new / 128.0, 100.0 / sensitivity) * (max-in->default_value)
							+ in->default_value) * 100 / sensitivity;
				}
				else
				{
					current = (pow(-new / 128.0, 100.0 / sensitivity) * (min-in->default_value)
							+ in->default_value) * 100 / sensitivity;
				}
			}
		}
	}

	current += delta;

	if (check_bounds)
	{
		int temp;

		if (current >= 0)
			temp = (current * sensitivity + 50) / 100;
		else
			temp = (-current * sensitivity + 50) / -100;

		if (temp < min)
		{
			if (min >= 0)
				current = (min * 100 + sensitivity/2) / sensitivity;
			else
				current = (-min * 100 + sensitivity/2) / -sensitivity;
		}
		if (temp > max)
		{
			if (max >= 0)
				current = (max * 100 + sensitivity/2) / sensitivity;
			else
				current = (-max * 100 + sensitivity/2) / -sensitivity;
		}
	}

	input_analog_current_value[port] = current;
}

static void scale_analog_port(int port)
{
	struct InputPort *in;
	int delta,current,sensitivity;

profiler_mark(PROFILER_INPUT);
	in = input_analog[port];
	sensitivity = IP_GET_SENSITIVITY(in);

	/* apply scaling fairly in both positive and negative directions */
	delta = input_analog_current_value[port] - input_analog_previous_value[port];
	if (delta >= 0)
		delta = cpu_scalebyfcount(delta);
	else
		delta = -cpu_scalebyfcount(-delta);

	current = input_analog_previous_value[port] + delta;

	/* An ugly hack to remove scaling on lightgun ports */
	if (input_analog_scale[port]) {
		/* apply scaling fairly in both positive and negative directions */
		if (current >= 0)
			current = (current * sensitivity + 50) / 100;
		else
			current = (-current * sensitivity + 50) / -100;
	}

	input_port_value[port] &= ~in->mask;
	input_port_value[port] |= current & in->mask;

	if (playback)
		readword(playback,&input_port_value[port]);
	if (record)
		writeword(record,input_port_value[port]);
#ifdef MAME_NET
	if ( net_active() && (default_player != NET_SPECTATOR) )
		net_analog_sync((unsigned char *) input_port_value, port, analog_player_port, default_player);
#endif /* MAME_NET */
profiler_mark(PROFILER_END);
}

#define MAX_JOYSTICKS 3
#define MAX_PLAYERS 4
static int mJoyCurrent[MAX_JOYSTICKS*MAX_PLAYERS];
static int mJoyPrevious[MAX_JOYSTICKS*MAX_PLAYERS];
static int mJoy4Way[MAX_JOYSTICKS*MAX_PLAYERS];
/*
The above "Joy" states contain packed bits:
	0001	up
	0010	down
	0100	left
	1000	right
*/

static void
ScanJoysticks( struct InputPort *in )
{
	int i;
	int port = 0;

	/* Save old Joystick state. */
	memcpy( mJoyPrevious, mJoyCurrent, sizeof(mJoyPrevious) );

	/* Initialize bits of mJoyCurrent to zero. */
	memset( mJoyCurrent, 0, sizeof(mJoyCurrent) );

	/* Now iterate over the input port structure to populate mJoyCurrent. */
	while( in->type != IPT_END && port < MAX_INPUT_PORTS )
	{
		while (in->type != IPT_END && in->type != IPT_PORT)
		{
			if ((in->type & ~IPF_MASK) >= IPT_JOYSTICK_UP &&
				(in->type & ~IPF_MASK) <= IPT_JOYSTICKLEFT_RIGHT)
			{
				InputSeq* seq;
				seq = input_port_seq(in);
				if( seq_pressed(seq) )
				{
					int joynum,joydir,player;
					player = 0;
					if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2)
						player = 1;
					else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3)
						player = 2;
					else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4)
						player = 3;

					joynum = player * MAX_JOYSTICKS +
							 ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) / 4;
					joydir = ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) % 4;

					mJoyCurrent[joynum] |= 1<<joydir;
				}
			}
			in++;
		}
		port++;
		if (in->type == IPT_PORT) in++;
	}

	/* Process the joystick states, to filter out illegal combinations of switches. */
	for( i=0; i<MAX_JOYSTICKS*MAX_PLAYERS; i++ )
	{
		if( (mJoyCurrent[i]&0x3)==0x3 ) /* both up and down are pressed */
		{
			mJoyCurrent[i]&=0xc; /* clear up and down */
		}
		if( (mJoyCurrent[i]&0xc)==0xc ) /* both left and right are pressed */
		{
			mJoyCurrent[i]&=0x3; /* clear left and right */
		}

		/* Only update mJoy4Way if the joystick has moved. */
		if( mJoyCurrent[i]!=mJoyPrevious[i] )
		{
			mJoy4Way[i] = mJoyCurrent[i];

			if( (mJoy4Way[i] & 0x3) && (mJoy4Way[i] & 0xc) )
			{
				/* If joystick is pointing at a diagonal, acknowledge that the player moved
				 * the joystick by favoring a direction change.  This minimizes frustration
				 * when using a keyboard for input, and maximizes responsiveness.
				 *
				 * For example, if you are holding "left" then switch to "up" (where both left
				 * and up are briefly pressed at the same time), we'll transition immediately
				 * to "up."
				 *
				 * Under the old "sticky" key implentation, "up" wouldn't be triggered until
				 * left was released.
				 *
				 * Zero any switches that didn't change from the previous to current state.
				 */
				mJoy4Way[i] ^= (mJoy4Way[i] & mJoyPrevious[i]);
			}

			if( (mJoy4Way[i] & 0x3) && (mJoy4Way[i] & 0xc) )
			{
				/* If we are still pointing at a diagonal, we are in an indeterminant state.
				 *
				 * This could happen if the player moved the joystick from the idle position directly
				 * to a diagonal, or from one diagonal directly to an extreme diagonal.
				 *
				 * The chances of this happening with a keyboard are slim, but we still need to
				 * constrain this case.
				 *
				 * For now, just resolve randomly.
				 */
				if( rand()&1 )
				{
					mJoy4Way[i] &= 0x3; /* eliminate horizontal component */
				}
				else
				{
					mJoy4Way[i] &= 0xc; /* eliminate vertical component */
				}
			}
		}
	}
} /* ScanJoysticks */

void update_input_ports(void)
{
	int port,ib;
	struct InputPort *in;

#define MAX_INPUT_BITS 1024
	static int impulsecount[MAX_INPUT_BITS];
	static int waspressed[MAX_INPUT_BITS];
	static int pbwaspressed[MAX_INPUT_BITS];

#ifdef MAME_NET
	int player;
#endif /* MAME_NET */


profiler_mark(PROFILER_INPUT);

	/* clear all the values before proceeding */
	for (port = 0;port < MAX_INPUT_PORTS;port++)
	{
		input_port_value[port] = 0;
		input_vblank[port] = 0;
		input_analog[port] = 0;
	}

	in = Machine->input_ports;
	if (in->type == IPT_END) return; 	/* nothing to do */

	/* make sure the InputPort definition is correct */
	if (in->type != IPT_PORT)
	{
		logerror("Error in InputPort definition: expecting PORT_START\n");
		return;
	}
	else
	{
		in++;
	}

	ScanJoysticks( in ); /* populates mJoyCurrent[] */

	/* scan all the input ports */
	port = 0;
	ib = 0;
	while (in->type != IPT_END && port < MAX_INPUT_PORTS)
	{
		struct InputPort *start;
		/* first of all, scan the whole input port definition and build the */
		/* default value. I must do it before checking for input because otherwise */
		/* multiple keys associated with the same input bit wouldn't work (the bit */
		/* would be reset to its default value by the second entry, regardless if */
		/* the key associated with the first entry was pressed) */
		start = in;
		while (in->type != IPT_END && in->type != IPT_PORT)
		{
			if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING &&	/* skip dipswitch definitions */
				(in->type & ~IPF_MASK) != IPT_EXTENSION)			/* skip analog extension fields */
			{
				input_port_value[port] =
						(input_port_value[port] & ~in->mask) | (in->default_value & in->mask);
#ifdef MAME_NET
				if ( net_active() )
					input_port_defaults[port] = input_port_value[port];
#endif /* MAME_NET */
			}

			in++;
		}

		/* now get back to the beginning of the input port and check the input bits. */
		for (in = start;
			 in->type != IPT_END && in->type != IPT_PORT;
			 in++, ib++)
		{
#ifdef MAME_NET
			player = 0;
			if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
			else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
			else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
#endif /* MAME_NET */
			if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING &&	/* skip dipswitch definitions */
					(in->type & ~IPF_MASK) != IPT_EXTENSION)		/* skip analog extension fields */
			{
				if ((in->type & ~IPF_MASK) == IPT_VBLANK)
				{
					input_vblank[port] ^= in->mask;
					input_port_value[port] ^= in->mask;
if (Machine->drv->vblank_duration == 0)
	logerror("Warning: you are using IPT_VBLANK with vblank_duration = 0. You need to increase vblank_duration for IPT_VBLANK to work.\n");
				}
				/* If it's an analog control, handle it appropriately */
				else if (((in->type & ~IPF_MASK) > IPT_ANALOG_START)
					  && ((in->type & ~IPF_MASK) < IPT_ANALOG_END  )) /* LBO 120897 */
				{
					input_analog[port]=in;
					/* reset the analog port on first access */
					if (input_analog_init[port])
					{
						input_analog_init[port] = 0;
						input_analog_scale[port] = 1;
						input_analog_current_value[port] = input_analog_previous_value[port]
							= in->default_value * 100 / IP_GET_SENSITIVITY(in);
					}
				}
				else
				{
					InputSeq* seq;
					seq = input_port_seq(in);
#ifdef JMAME // AUTO_FIRE
					if (auto_pressed(seq, in->type, ib))
#else
					if (seq_pressed(seq))
#endif
					{
						/* skip if coin input and it's locked out */
						if ((in->type & ~IPF_MASK) >= IPT_COIN1 &&
							(in->type & ~IPF_MASK) <= IPT_COIN4 &&
                            coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1])
						{
							continue;
						}

						/* if IPF_RESET set, reset the first CPU */
						if ((in->type & IPF_RESETCPU) && waspressed[ib] == 0 && !playback)
						{
							cpu_set_reset_line(0,PULSE_LINE);
						}

						if (in->type & IPF_IMPULSE)
						{
if (IP_GET_IMPULSE(in) == 0)
	logerror("error in input port definition: IPF_IMPULSE with length = 0\n");
							if (waspressed[ib] == 0)
								impulsecount[ib] = IP_GET_IMPULSE(in);
								/* the input bit will be toggled later */
						}
						else if (in->type & IPF_TOGGLE)
						{
							if (waspressed[ib] == 0)
							{
								in->default_value ^= in->mask;
								input_port_value[port] ^= in->mask;
							}
						}
						else if ((in->type & ~IPF_MASK) >= IPT_JOYSTICK_UP &&
								(in->type & ~IPF_MASK) <= IPT_JOYSTICKLEFT_RIGHT)
						{
#ifndef MAME_NET
							int joynum,joydir,mask,player;


							player = 0;
							if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
							else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
							else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
#else
							int joynum,joydir,mask;
#endif /* !MAME_NET */
							joynum = player * MAX_JOYSTICKS +
									((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) / 4;

							joydir = ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) % 4;

							mask = in->mask;

							if( in->type & IPF_4WAY )
							{
								/* apply 4-way joystick constraint */
								if( ((mJoy4Way[joynum]>>joydir)&1) == 0 )
								{
									mask = 0;
								}
							}
							else
							{
								/* filter up+down and left+right */
								if( ((mJoyCurrent[joynum]>>joydir)&1) == 0 )
								{
									mask = 0;
								}
							}

							input_port_value[port] ^= mask;
						} /* joystick */
						else
						{
							input_port_value[port] ^= in->mask;
						}
						waspressed[ib] = 1;
					}
					else
						waspressed[ib] = 0;

					if ((in->type & IPF_IMPULSE) && impulsecount[ib] > 0)
					{
						impulsecount[ib]--;
						waspressed[ib] = 1;
						input_port_value[port] ^= in->mask;
					}
				}
			}
		}

		port++;
		if (in->type == IPT_PORT) in++;
	}

#ifdef JMAME // PLAYBACK_FIX
	if (playback && pback)
#else
	if (playback)
#endif
	{
		int i;

		ib=0;
		in = Machine->input_ports;
		in++;
		for (i = 0; i < MAX_INPUT_PORTS; i ++)
		{
#ifdef JMAME // PLAYBACK_FIX
			if (readword(playback,&input_port_value[i]))
			{
				pback = 0;
#ifdef JAPANESE
				usrintf_showmessage("入力の再現が終了しました");
#else
				usrintf_showmessage("End of playback");
#endif
				break;
			}
#else
			readword(playback,&input_port_value[i]);
#endif

			/* check if the input port includes an IPF_RESETCPU bit
			   and reset the CPU on first "press", no need to check
			   the impulse count as this was done during recording */
			for (; in->type != IPT_END && in->type != IPT_PORT; in++, ib++)
			{
				if (in->type & IPF_RESETCPU)
				{
					if((input_port_value[i] ^ in->default_value) & in->mask)
					{
						if (pbwaspressed[ib] == 0)
							cpu_set_reset_line(0,PULSE_LINE);
						pbwaspressed[ib] = 1;
					}
					else
						pbwaspressed[ib] = 0;
				}
			}
			if (in->type == IPT_PORT) in++;
#ifdef JMAME // PLAYBACK_FIX
		}

		in = Machine->input_ports;
		in++;
		port = 0;
		while (in->type != IPT_END && port < MAX_INPUT_PORTS)
		{
			while (in->type != IPT_END && in->type != IPT_PORT)
			{
				if ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_NAME)
				{
					in->default_value =
						(in->default_value & ~in->mask) | (input_port_value[port] & in->mask);
				}
				in++;
			}
			port++;
			if (in->type == IPT_PORT) in++;
#endif
		}
	}

	if (record)
	{
		int i;

		for (i = 0; i < MAX_INPUT_PORTS; i ++)
			writeword(record,input_port_value[i]);
	}
#ifdef MAME_NET
	if ( net_active() && (default_player != NET_SPECTATOR) )
		net_input_sync((unsigned char *) input_port_value, (unsigned char *) input_port_defaults, MAX_INPUT_PORTS);
#endif /* MAME_NET */

profiler_mark(PROFILER_END);
}



/* used the the CPU interface to notify that VBlank has ended, so we can update */
/* IPT_VBLANK input ports. */
void inputport_vblank_end(void)
{
	int port;
	int i;


profiler_mark(PROFILER_INPUT);
	for (port = 0;port < MAX_INPUT_PORTS;port++)
	{
		if (input_vblank[port])
		{
			input_port_value[port] ^= input_vblank[port];
			input_vblank[port] = 0;
		}
	}

	/* update the analog devices */
	for (i = 0;i < OSD_MAX_JOY_ANALOG;i++)
	{
		/* update the analog joystick position */
		int a;
		for (a=0; a<MAX_ANALOG_AXES ; a++)
		{
			analog_previous_axis[i][a] = analog_current_axis[i][a];
		}
		osd_analogjoy_read (i, analog_current_axis[i], analogjoy_input[i]);

		/* update mouse/trackball position */
		osd_trak_read (i, &(mouse_delta_axis[i])[X_AXIS], &(mouse_delta_axis[i])[Y_AXIS]);

		/* update lightgun position, if any */
 		osd_lightgun_read (i, &(lightgun_delta_axis[i])[X_AXIS], &(lightgun_delta_axis[i])[Y_AXIS]);
	}

	for (i = 0;i < MAX_INPUT_PORTS;i++)
	{
		struct InputPort *in;

		in=input_analog[i];
		if (in)
		{
			update_analog_port(i);
		}
	}
profiler_mark(PROFILER_END);
}



int readinputport(int port)
{
	struct InputPort *in;

	/* Update analog ports on demand */
	in=input_analog[port];
	if (in)
	{
		scale_analog_port(port);
	}

	return input_port_value[port];
}

READ_HANDLER( input_port_0_r ) { return readinputport(0); }
READ_HANDLER( input_port_1_r ) { return readinputport(1); }
READ_HANDLER( input_port_2_r ) { return readinputport(2); }
READ_HANDLER( input_port_3_r ) { return readinputport(3); }
READ_HANDLER( input_port_4_r ) { return readinputport(4); }
READ_HANDLER( input_port_5_r ) { return readinputport(5); }
READ_HANDLER( input_port_6_r ) { return readinputport(6); }
READ_HANDLER( input_port_7_r ) { return readinputport(7); }
READ_HANDLER( input_port_8_r ) { return readinputport(8); }
READ_HANDLER( input_port_9_r ) { return readinputport(9); }
READ_HANDLER( input_port_10_r ) { return readinputport(10); }
READ_HANDLER( input_port_11_r ) { return readinputport(11); }
READ_HANDLER( input_port_12_r ) { return readinputport(12); }
READ_HANDLER( input_port_13_r ) { return readinputport(13); }
READ_HANDLER( input_port_14_r ) { return readinputport(14); }
READ_HANDLER( input_port_15_r ) { return readinputport(15); }
READ_HANDLER( input_port_16_r ) { return readinputport(16); }
READ_HANDLER( input_port_17_r ) { return readinputport(17); }
READ_HANDLER( input_port_18_r ) { return readinputport(18); }
READ_HANDLER( input_port_19_r ) { return readinputport(19); }

READ16_HANDLER( input_port_0_word_r ) { return readinputport(0); }
READ16_HANDLER( input_port_1_word_r ) { return readinputport(1); }
READ16_HANDLER( input_port_2_word_r ) { return readinputport(2); }
READ16_HANDLER( input_port_3_word_r ) { return readinputport(3); }
READ16_HANDLER( input_port_4_word_r ) { return readinputport(4); }
READ16_HANDLER( input_port_5_word_r ) { return readinputport(5); }
READ16_HANDLER( input_port_6_word_r ) { return readinputport(6); }
READ16_HANDLER( input_port_7_word_r ) { return readinputport(7); }
READ16_HANDLER( input_port_8_word_r ) { return readinputport(8); }
READ16_HANDLER( input_port_9_word_r ) { return readinputport(9); }
READ16_HANDLER( input_port_10_word_r ) { return readinputport(10); }
READ16_HANDLER( input_port_11_word_r ) { return readinputport(11); }
READ16_HANDLER( input_port_12_word_r ) { return readinputport(12); }
READ16_HANDLER( input_port_13_word_r ) { return readinputport(13); }
READ16_HANDLER( input_port_14_word_r ) { return readinputport(14); }
READ16_HANDLER( input_port_15_word_r ) { return readinputport(15); }
READ16_HANDLER( input_port_16_word_r ) { return readinputport(16); }
READ16_HANDLER( input_port_17_word_r ) { return readinputport(17); }
READ16_HANDLER( input_port_18_word_r ) { return readinputport(18); }
READ16_HANDLER( input_port_19_word_r ) { return readinputport(19); }

#ifdef MAME_NET
void set_default_player_controls(int player)
{
	if (player == NET_SPECTATOR)
		default_player = NET_SPECTATOR;
	else
		default_player = player - 1;
}
#endif /* MAME_NET */

/***************************************************************************/
/* InputPort conversion */

static unsigned input_port_count(const struct InputPortTiny *src)
{
	unsigned total;

	total = 0;
	while (src->type != IPT_END)
	{
		int type = src->type & ~IPF_MASK;
		if (type > IPT_ANALOG_START && type < IPT_ANALOG_END)
			total += 2;
		else if (type != IPT_EXTENSION)
			++total;
		++src;
	}

	++total; /* for IPT_END */

	return total;
}

struct InputPort* input_port_allocate(const struct InputPortTiny *src)
{
	struct InputPort* dst;
	struct InputPort* base;
	unsigned total;

	total = input_port_count(src);

	base = (struct InputPort*)malloc(total * sizeof(struct InputPort));
	dst = base;

	while (src->type != IPT_END)
	{
		int type = src->type & ~IPF_MASK;
		const struct InputPortTiny *ext;
		const struct InputPortTiny *src_end;
		InputCode seq_default;

		if (type > IPT_ANALOG_START && type < IPT_ANALOG_END)
			src_end = src + 2;
		else
			src_end = src + 1;

		switch (type)
		{
			case IPT_END :
			case IPT_PORT :
			case IPT_DIPSWITCH_NAME :
			case IPT_DIPSWITCH_SETTING :
				seq_default = CODE_NONE;
			break;
			default:
				seq_default = CODE_DEFAULT;
		}

		ext = src_end;
		while (src != src_end)
		{
			dst->type = src->type;
			dst->mask = src->mask;
			dst->default_value = src->default_value;
			dst->name = src->name;

  			if (ext->type == IPT_EXTENSION)
  			{
				InputCode or1 =	IP_GET_CODE_OR1(ext);
				InputCode or2 =	IP_GET_CODE_OR2(ext);

				if (or1 < __code_max)
				{
					if (or2 < __code_max)
						seq_set_3(&dst->seq, or1, CODE_OR, or2);
					else
						seq_set_1(&dst->seq, or1);
				} else {
					if (or1 == CODE_NONE)
						seq_set_1(&dst->seq, or2);
					else
						seq_set_1(&dst->seq, or1);
				}

  				++ext;
  			} else {
				seq_set_1(&dst->seq,seq_default);
  			}

			++src;
			++dst;
		}

		src = ext;
	}

	dst->type = IPT_END;

	return base;
}

void input_port_free(struct InputPort* dst)
{
	free(dst);
}


void seq_set_string(InputSeq* a, const char *buf)
{
	char *lbuf;
	char *arg = NULL;
	int j;
	struct ik *pik;
	int found;

	// create a locale buffer to be parsed by strtok
	lbuf = malloc (strlen(buf)+1);

	// copy the input string
	strcpy (lbuf, buf);

	for(j=0;j<SEQ_MAX;++j)
		(*a)[j] = CODE_NONE;

	arg = strtok(lbuf, " \t\r\n");
	j = 0;
	while( arg != NULL )
	{
		found = 0;

		pik = input_keywords;

		while (!found && pik->name && pik->name[0] != 0)
		{
			if (strcmp(pik->name,arg) == 0)
			{
				// this entry is only valid if it is a KEYCODE
				if (pik->type == IKT_STD)
				{
					(*a)[j] = pik->val;
					j++;
					found = 1;
				}
			}
			pik++;
		}

		pik = osd_input_keywords;

		if (pik)
		{
			while (!found && pik->name && pik->name[0] != 0)
			{
				if (strcmp(pik->name,arg) == 0)
				{
					switch (pik->type)
					{
						case IKT_STD:
							(*a)[j] = pik->val;
							j++;
							found = 1;
						break;

						case IKT_OSD_KEY:
							(*a)[j] = keyoscode_to_code(pik->val);
							j++;
							found = 1;
						break;

						case IKT_OSD_JOY:
							(*a)[j] = joyoscode_to_code(pik->val);
							j++;
							found = 1;
						break;
					}
				}
				pik++;
			}
		}

		arg = strtok(NULL, " \t\r\n");
	}
	free (lbuf);
}

void init_analog_seq()
{
	struct InputPort *in;
	int player, axis;

/* init analogjoy_input array */
	for (player=0; player<OSD_MAX_JOY_ANALOG; player++)
	{
		for (axis=0; axis<MAX_ANALOG_AXES; axis++)
		{
			analogjoy_input[player][axis] = CODE_NONE;
		}
	}

	in = Machine->input_ports;
	if (in->type == IPT_END) return; 	/* nothing to do */

	/* make sure the InputPort definition is correct */
	if (in->type != IPT_PORT)
	{
		logerror("Error in InputPort definition: expecting PORT_START\n");
		return;
	}
	else
	{
		in++;
	}

	while (in->type != IPT_END)
	{
		if (in->type != IPT_PORT && ((in->type & ~IPF_MASK) > IPT_ANALOG_START)
			&& ((in->type & ~IPF_MASK) < IPT_ANALOG_END))
		{
			int j, invert;
			InputSeq *seq;
			InputCode analog_seq;

			seq = input_port_seq(in);
			invert = 0;
			analog_seq = CODE_NONE;

			for(j=0; j<SEQ_MAX && analog_seq == CODE_NONE; ++j)
			{
				switch ((*seq)[j])
				{
					case CODE_NONE :
						continue;
					case CODE_NOT :
						invert = !invert;
						break;
					case CODE_OR :
						invert = 0;
						break;
					default:
						if (!invert && is_joystick_axis_code((*seq)[j]) )
						{
							analog_seq = return_os_joycode((*seq)[j]);
						}
						invert = 0;
						break;
				}
			}
			if (analog_seq != CODE_NONE)
			{
				switch (in->type & IPF_PLAYERMASK)
				{
					case IPF_PLAYER2:          player = 1; break;
					case IPF_PLAYER3:          player = 2; break;
					case IPF_PLAYER4:          player = 3; break;
					case IPF_PLAYER1: default: player = 0; break;
				}

				switch (in->type & ~IPF_MASK)
				{
					case IPT_DIAL:
					case IPT_PADDLE:
					case IPT_TRACKBALL_X:
					case IPT_AD_STICK_X:
						axis = X_AXIS;
						break;
					case IPT_DIAL_V:
					case IPT_PADDLE_V:
					case IPT_TRACKBALL_Y:
					case IPT_AD_STICK_Y:
						axis = Y_AXIS;
						break;
					case IPT_AD_STICK_Z:
					case IPT_PEDAL2:
						axis = Z_AXIS;
						break;
					case IPT_PEDAL:
						axis = PEDAL_AXIS;
						break;
					default:
						axis = 0;
						break;
				}

				analogjoy_input[player][axis] = analog_seq;
			}
		}

		in++;
	}

	return;
}

#ifdef JMAME // AUTO_FIRE
UINT32 toggle_autofire(void)
{
	autofire_enable = autofire_enable ? 0 : 1;

	return autofire_enable;
}

static int auto_pressed(InputSeq *seq, UINT32 type, int bit)
{
	int pressed = seq_pressed(seq);

	if (pressed)
	{
		if ((type & IPF_AUTOFIRE_ON) || ((type & IPF_AUTOFIRE_TOGGLE) && autofire_enable))
		{
			if (autopressed[bit] >= options.autofiredelay)
			{
				pressed = 0;
				autopressed[bit] = 0;
			}
			else
				autopressed[bit]++;
		}
	}

	return pressed;
}
#endif
