summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ioport.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ioport.h')
-rw-r--r--src/emu/ioport.h1930
1 files changed, 1072 insertions, 858 deletions
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index 8856e15ae4a..21050a6fb57 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -4,8 +4,36 @@
Input/output port handling.
- Copyright Nicola Salmoria and the MAME Team.
- Visit http://mamedev.org for licensing and usage restrictions.
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
@@ -21,61 +49,48 @@
#include <time.h>
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define MAX_PLAYERS 8
-
-#define IP_ACTIVE_HIGH 0x00000000
-#define IP_ACTIVE_LOW 0xffffffff
+// input ports support up to 32 bits each
+typedef UINT32 ioport_value;
+// active high/low values for input ports
+const ioport_value IP_ACTIVE_HIGH = 0x00000000;
+const ioport_value IP_ACTIVE_LOW = 0xffffffff;
-/* flags for input_field_configs */
-#define FIELD_FLAG_UNUSED 0x01 /* set if this field is unused but relevant to other games on the same hw */
-#define FIELD_FLAG_COCKTAIL 0x02 /* set if this field is relevant only for cocktail cabinets */
-#define FIELD_FLAG_TOGGLE 0x04 /* set if this field should behave as a toggle */
-#define FIELD_FLAG_ROTATED 0x08 /* set if this field represents a rotated control */
-#define ANALOG_FLAG_REVERSE 0x10 /* analog only: reverse the sense of the axis */
-#define ANALOG_FLAG_RESET 0x20 /* analog only: always preload in->default for relative axes, returning only deltas */
-#define ANALOG_FLAG_WRAPS 0x40 /* analog only: positional count wraps around */
-#define ANALOG_FLAG_INVERT 0x80 /* analog only: bitwise invert bits */
+// maximum number of players supported
+const int MAX_PLAYERS = 8;
+// INP file parameters
+const UINT32 INP_HEADER_SIZE = 64;
+const UINT32 INP_HEADER_MAJVERSION = 3;
+const UINT32 INP_HEADER_MINVERSION = 0;
-/* INP file information */
-#define INP_HEADER_SIZE 64
-#define INP_HEADER_MAJVERSION 3
-#define INP_HEADER_MINVERSION 0
+// unicode constants
+const unicode_char UCHAR_PRIVATE = 0x100000;
+const unicode_char UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
+const unicode_char UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1;
+const unicode_char UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1;
+const unicode_char UCHAR_SHIFT_END = UCHAR_SHIFT_2;
+const unicode_char UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
-/* sequence types for input_port_seq() call */
-enum _input_seq_type
+// sequence types for input_port_seq() call
+enum input_seq_type
{
+ SEQ_TYPE_INVALID = -1,
SEQ_TYPE_STANDARD = 0,
SEQ_TYPE_INCREMENT,
SEQ_TYPE_DECREMENT,
SEQ_TYPE_TOTAL
};
-typedef enum _input_seq_type input_seq_type;
DECLARE_ENUM_OPERATORS(input_seq_type)
-/* conditions for DIP switches */
-enum
-{
- PORTCOND_ALWAYS = 0,
- PORTCOND_EQUALS,
- PORTCOND_NOTEQUALS,
- PORTCOND_GREATERTHAN,
- PORTCOND_NOTGREATERTHAN,
- PORTCOND_LESSTHAN,
- PORTCOND_NOTLESSTHAN
-};
-
-
-/* crosshair types */
-enum
+// crosshair types
+enum crosshair_axis_t
{
CROSSHAIR_AXIS_NONE = 0,
CROSSHAIR_AXIS_X,
@@ -83,7 +98,7 @@ enum
};
-/* groups for input ports */
+// groups for input ports
enum ioport_group
{
IPG_UI = 0,
@@ -101,20 +116,19 @@ enum ioport_group
};
-/* various input port types */
-enum
+// various input port types
+enum ioport_type
{
- /* pseudo-port types */
+ // pseudo-port types
IPT_INVALID = 0,
IPT_UNUSED,
IPT_END,
IPT_UNKNOWN,
IPT_PORT,
IPT_DIPSWITCH,
- IPT_VBLANK,
IPT_CONFIG,
- /* start buttons */
+ // start buttons
IPT_START1,
IPT_START2,
IPT_START3,
@@ -124,7 +138,7 @@ enum
IPT_START7,
IPT_START8,
- /* coin slots */
+ // coin slots
IPT_COIN1,
IPT_COIN2,
IPT_COIN3,
@@ -139,48 +153,51 @@ enum
IPT_COIN12,
IPT_BILL1,
- /* service coin */
+ // service coin
IPT_SERVICE1,
IPT_SERVICE2,
IPT_SERVICE3,
IPT_SERVICE4,
- /* tilt inputs */
+ // tilt inputs
IPT_TILT1,
IPT_TILT2,
IPT_TILT3,
IPT_TILT4,
- /* misc other digital inputs */
+ // misc other digital inputs
IPT_SERVICE,
IPT_TILT,
IPT_INTERLOCK,
IPT_VOLUME_UP,
IPT_VOLUME_DOWN,
- IPT_START, /* MESS only */
- IPT_SELECT, /* MESS only */
- IPT_KEYPAD, /* MESS only */
- IPT_KEYBOARD, /* MESS only */
-
-#define __ipt_digital_joystick_start IPT_JOYSTICK_UP
- /* use IPT_JOYSTICK for panels where the player has one single joystick */
- IPT_JOYSTICK_UP,
- IPT_JOYSTICK_DOWN,
- IPT_JOYSTICK_LEFT,
- IPT_JOYSTICK_RIGHT,
-
- /* use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels */
- IPT_JOYSTICKRIGHT_UP,
- IPT_JOYSTICKRIGHT_DOWN,
- IPT_JOYSTICKRIGHT_LEFT,
- IPT_JOYSTICKRIGHT_RIGHT,
- IPT_JOYSTICKLEFT_UP,
- IPT_JOYSTICKLEFT_DOWN,
- IPT_JOYSTICKLEFT_LEFT,
- IPT_JOYSTICKLEFT_RIGHT,
-#define __ipt_digital_joystick_end IPT_JOYSTICKLEFT_RIGHT
-
- /* action buttons */
+ IPT_START, // MESS only
+ IPT_SELECT, // MESS only
+ IPT_KEYPAD, // MESS only
+ IPT_KEYBOARD, // MESS only
+
+ // digital joystick inputs
+ IPT_DIGITAL_JOYSTICK_FIRST,
+
+ // use IPT_JOYSTICK for panels where the player has one single joystick
+ IPT_JOYSTICK_UP = IPT_DIGITAL_JOYSTICK_FIRST,
+ IPT_JOYSTICK_DOWN,
+ IPT_JOYSTICK_LEFT,
+ IPT_JOYSTICK_RIGHT,
+
+ // use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels
+ IPT_JOYSTICKRIGHT_UP,
+ IPT_JOYSTICKRIGHT_DOWN,
+ IPT_JOYSTICKRIGHT_LEFT,
+ IPT_JOYSTICKRIGHT_RIGHT,
+ IPT_JOYSTICKLEFT_UP,
+ IPT_JOYSTICKLEFT_DOWN,
+ IPT_JOYSTICKLEFT_LEFT,
+ IPT_JOYSTICKLEFT_RIGHT,
+
+ IPT_DIGITAL_JOYSTICK_LAST,
+
+ // action buttons
IPT_BUTTON1,
IPT_BUTTON2,
IPT_BUTTON3,
@@ -198,210 +215,234 @@ enum
IPT_BUTTON15,
IPT_BUTTON16,
- /* mahjong inputs */
-#define __ipt_mahjong_start IPT_MAHJONG_A
- IPT_MAHJONG_A,
- IPT_MAHJONG_B,
- IPT_MAHJONG_C,
- IPT_MAHJONG_D,
- IPT_MAHJONG_E,
- IPT_MAHJONG_F,
- IPT_MAHJONG_G,
- IPT_MAHJONG_H,
- IPT_MAHJONG_I,
- IPT_MAHJONG_J,
- IPT_MAHJONG_K,
- IPT_MAHJONG_L,
- IPT_MAHJONG_M,
- IPT_MAHJONG_N,
- IPT_MAHJONG_O,
- IPT_MAHJONG_P,
- IPT_MAHJONG_Q,
- IPT_MAHJONG_KAN,
- IPT_MAHJONG_PON,
- IPT_MAHJONG_CHI,
- IPT_MAHJONG_REACH, //IPT_MAHJONG_RIICHI, // REACH is Japanglish
- IPT_MAHJONG_RON,
- IPT_MAHJONG_BET,
- IPT_MAHJONG_LAST_CHANCE,
- IPT_MAHJONG_SCORE,
- IPT_MAHJONG_DOUBLE_UP,
- IPT_MAHJONG_FLIP_FLOP,
- IPT_MAHJONG_BIG,
- IPT_MAHJONG_SMALL,
-#define __ipt_mahjong_end IPT_MAHJONG_SMALL
-
- /* hanafuda inputs */
-#define __ipt_hanafuda_start IPT_HANAFUDA_A
- IPT_HANAFUDA_A,
- IPT_HANAFUDA_B,
- IPT_HANAFUDA_C,
- IPT_HANAFUDA_D,
- IPT_HANAFUDA_E,
- IPT_HANAFUDA_F,
- IPT_HANAFUDA_G,
- IPT_HANAFUDA_H,
- IPT_HANAFUDA_YES,
- IPT_HANAFUDA_NO,
-#define __ipt_hanafuda_end IPT_HANAFUDA_NO
-
-#define __ipt_gambling_start IPT_GAMBLE_KEYIN
-
- /* gambling inputs */
- IPT_GAMBLE_KEYIN, // attendant
- IPT_GAMBLE_KEYOUT, // attendant
- IPT_GAMBLE_SERVICE, // attendant
- IPT_GAMBLE_BOOK, // attendant
- IPT_GAMBLE_DOOR, // attendant
-// IPT_GAMBLE_DOOR2, // many gambling games have several doors.
-// IPT_GAMBLE_DOOR3,
-// IPT_GAMBLE_DOOR4,
-// IPT_GAMBLE_DOOR5,
-
- IPT_GAMBLE_HIGH, // player
- IPT_GAMBLE_LOW, // player
- IPT_GAMBLE_HALF, // player
- IPT_GAMBLE_DEAL, // player
- IPT_GAMBLE_D_UP, // player
- IPT_GAMBLE_TAKE, // player
- IPT_GAMBLE_STAND, // player
- IPT_GAMBLE_BET, // player
- IPT_GAMBLE_PAYOUT, // player
-// IPT_GAMBLE_BUTTON1, // player
-// IPT_GAMBLE_BUTTON2, // many many gambling games have multi-games and/or multi-function-buttons
-// IPT_GAMBLE_BUTTON3, // I suggest to eliminate specific names
-// IPT_GAMBLE_BUTTON4,
-// IPT_GAMBLE_BUTTON5,
-// IPT_GAMBLE_BUTTON6,
-// IPT_GAMBLE_BUTTON7,
-// IPT_GAMBLE_BUTTON8,
-// IPT_GAMBLE_BUTTON9,
-// IPT_GAMBLE_BUTTON10,
-// IPT_GAMBLE_BUTTON11,
-// IPT_GAMBLE_BUTTON12,
-// IPT_GAMBLE_BUTTON13,
-// IPT_GAMBLE_BUTTON14,
-// IPT_GAMBLE_BUTTON15,
-// IPT_GAMBLE_BUTTON16,
-
- /* poker-specific inputs */
- IPT_POKER_HOLD1,
- IPT_POKER_HOLD2,
- IPT_POKER_HOLD3,
- IPT_POKER_HOLD4,
- IPT_POKER_HOLD5,
- IPT_POKER_CANCEL,
- IPT_POKER_BET,
-
- /* slot-specific inputs */
- IPT_SLOT_STOP1,
- IPT_SLOT_STOP2,
- IPT_SLOT_STOP3,
- IPT_SLOT_STOP4,
- IPT_SLOT_STOP_ALL,
-
-#define __ipt_gambling_end IPT_SLOT_STOP_ALL
-
- /* analog inputs */
-#define __ipt_analog_start IPT_AD_STICK_X
-#define __ipt_analog_absolute_start IPT_AD_STICK_X
- IPT_AD_STICK_X, // absolute // autocenter
- IPT_AD_STICK_Y, // absolute // autocenter
- IPT_AD_STICK_Z, // absolute // autocenter
- IPT_PADDLE, // absolute // autocenter
- IPT_PADDLE_V, // absolute // autocenter
- IPT_PEDAL, // absolute // autocenter
- IPT_PEDAL2, // absolute // autocenter
- IPT_PEDAL3, // absolute // autocenter
- IPT_LIGHTGUN_X, // absolute
- IPT_LIGHTGUN_Y, // absolute
- IPT_POSITIONAL, // absolute // autocenter if not wraps
- IPT_POSITIONAL_V, // absolute // autocenter if not wraps
-#define __ipt_analog_absolute_end IPT_POSITIONAL_V
-
- IPT_DIAL, // relative
- IPT_DIAL_V, // relative
- IPT_TRACKBALL_X, // relative
- IPT_TRACKBALL_Y, // relative
- IPT_MOUSE_X, // relative
- IPT_MOUSE_Y, // relative
-#define __ipt_analog_end IPT_MOUSE_Y
-
- /* analog adjuster support */
+ // mahjong inputs
+ IPT_MAHJONG_FIRST,
+
+ IPT_MAHJONG_A,
+ IPT_MAHJONG_B,
+ IPT_MAHJONG_C,
+ IPT_MAHJONG_D,
+ IPT_MAHJONG_E,
+ IPT_MAHJONG_F,
+ IPT_MAHJONG_G,
+ IPT_MAHJONG_H,
+ IPT_MAHJONG_I,
+ IPT_MAHJONG_J,
+ IPT_MAHJONG_K,
+ IPT_MAHJONG_L,
+ IPT_MAHJONG_M,
+ IPT_MAHJONG_N,
+ IPT_MAHJONG_O,
+ IPT_MAHJONG_P,
+ IPT_MAHJONG_Q,
+ IPT_MAHJONG_KAN,
+ IPT_MAHJONG_PON,
+ IPT_MAHJONG_CHI,
+ IPT_MAHJONG_REACH, //IPT_MAHJONG_RIICHI, // REACH is Japanglish
+ IPT_MAHJONG_RON,
+ IPT_MAHJONG_BET,
+ IPT_MAHJONG_LAST_CHANCE,
+ IPT_MAHJONG_SCORE,
+ IPT_MAHJONG_DOUBLE_UP,
+ IPT_MAHJONG_FLIP_FLOP,
+ IPT_MAHJONG_BIG,
+ IPT_MAHJONG_SMALL,
+
+ IPT_MAHJONG_LAST,
+
+ // hanafuda inputs
+ IPT_HANAFUDA_FIRST,
+
+ IPT_HANAFUDA_A,
+ IPT_HANAFUDA_B,
+ IPT_HANAFUDA_C,
+ IPT_HANAFUDA_D,
+ IPT_HANAFUDA_E,
+ IPT_HANAFUDA_F,
+ IPT_HANAFUDA_G,
+ IPT_HANAFUDA_H,
+ IPT_HANAFUDA_YES,
+ IPT_HANAFUDA_NO,
+
+ IPT_HANAFUDA_LAST,
+
+ // gambling inputs
+ IPT_GAMBLING_FIRST,
+
+ IPT_GAMBLE_KEYIN, // attendant
+ IPT_GAMBLE_KEYOUT, // attendant
+ IPT_GAMBLE_SERVICE, // attendant
+ IPT_GAMBLE_BOOK, // attendant
+ IPT_GAMBLE_DOOR, // attendant
+ // IPT_GAMBLE_DOOR2, // many gambling games have several doors.
+ // IPT_GAMBLE_DOOR3,
+ // IPT_GAMBLE_DOOR4,
+ // IPT_GAMBLE_DOOR5,
+
+ IPT_GAMBLE_HIGH, // player
+ IPT_GAMBLE_LOW, // player
+ IPT_GAMBLE_HALF, // player
+ IPT_GAMBLE_DEAL, // player
+ IPT_GAMBLE_D_UP, // player
+ IPT_GAMBLE_TAKE, // player
+ IPT_GAMBLE_STAND, // player
+ IPT_GAMBLE_BET, // player
+ IPT_GAMBLE_PAYOUT, // player
+ // IPT_GAMBLE_BUTTON1, // player
+ // IPT_GAMBLE_BUTTON2, // many many gambling games have multi-games and/or multi-function-buttons
+ // IPT_GAMBLE_BUTTON3, // I suggest to eliminate specific names
+ // IPT_GAMBLE_BUTTON4,
+ // IPT_GAMBLE_BUTTON5,
+ // IPT_GAMBLE_BUTTON6,
+ // IPT_GAMBLE_BUTTON7,
+ // IPT_GAMBLE_BUTTON8,
+ // IPT_GAMBLE_BUTTON9,
+ // IPT_GAMBLE_BUTTON10,
+ // IPT_GAMBLE_BUTTON11,
+ // IPT_GAMBLE_BUTTON12,
+ // IPT_GAMBLE_BUTTON13,
+ // IPT_GAMBLE_BUTTON14,
+ // IPT_GAMBLE_BUTTON15,
+ // IPT_GAMBLE_BUTTON16,
+
+ // poker-specific inputs
+ IPT_POKER_HOLD1,
+ IPT_POKER_HOLD2,
+ IPT_POKER_HOLD3,
+ IPT_POKER_HOLD4,
+ IPT_POKER_HOLD5,
+ IPT_POKER_CANCEL,
+ IPT_POKER_BET,
+
+ // slot-specific inputs
+ IPT_SLOT_STOP1,
+ IPT_SLOT_STOP2,
+ IPT_SLOT_STOP3,
+ IPT_SLOT_STOP4,
+ IPT_SLOT_STOP_ALL,
+
+ IPT_GAMBLING_LAST,
+
+ // analog inputs
+ IPT_ANALOG_FIRST,
+
+ IPT_ANALOG_ABSOLUTE_FIRST,
+
+ IPT_AD_STICK_X, // absolute // autocenter
+ IPT_AD_STICK_Y, // absolute // autocenter
+ IPT_AD_STICK_Z, // absolute // autocenter
+ IPT_PADDLE, // absolute // autocenter
+ IPT_PADDLE_V, // absolute // autocenter
+ IPT_PEDAL, // absolute // autocenter
+ IPT_PEDAL2, // absolute // autocenter
+ IPT_PEDAL3, // absolute // autocenter
+ IPT_LIGHTGUN_X, // absolute
+ IPT_LIGHTGUN_Y, // absolute
+ IPT_POSITIONAL, // absolute // autocenter if not wraps
+ IPT_POSITIONAL_V, // absolute // autocenter if not wraps
+
+ IPT_ANALOG_ABSOLUTE_LAST,
+
+ IPT_DIAL, // relative
+ IPT_DIAL_V, // relative
+ IPT_TRACKBALL_X, // relative
+ IPT_TRACKBALL_Y, // relative
+ IPT_MOUSE_X, // relative
+ IPT_MOUSE_Y, // relative
+
+ IPT_ANALOG_LAST,
+
+ // analog adjuster support
IPT_ADJUSTER,
- /* the following are special codes for user interface handling - not to be used by drivers! */
-#define __ipt_ui_start IPT_UI_CONFIGURE
- IPT_UI_CONFIGURE,
- IPT_UI_ON_SCREEN_DISPLAY,
- IPT_UI_DEBUG_BREAK,
- IPT_UI_PAUSE,
- IPT_UI_RESET_MACHINE,
- IPT_UI_SOFT_RESET,
- IPT_UI_SHOW_GFX,
- IPT_UI_FRAMESKIP_DEC,
- IPT_UI_FRAMESKIP_INC,
- IPT_UI_THROTTLE,
- IPT_UI_FAST_FORWARD,
- IPT_UI_SHOW_FPS,
- IPT_UI_SNAPSHOT,
- IPT_UI_RECORD_MOVIE,
- IPT_UI_TOGGLE_CHEAT,
- IPT_UI_UP,
- IPT_UI_DOWN,
- IPT_UI_LEFT,
- IPT_UI_RIGHT,
- IPT_UI_HOME,
- IPT_UI_END,
- IPT_UI_PAGE_UP,
- IPT_UI_PAGE_DOWN,
- IPT_UI_SELECT,
- IPT_UI_CANCEL,
- IPT_UI_DISPLAY_COMMENT,
- IPT_UI_CLEAR,
- IPT_UI_ZOOM_IN,
- IPT_UI_ZOOM_OUT,
- IPT_UI_PREV_GROUP,
- IPT_UI_NEXT_GROUP,
- IPT_UI_ROTATE,
- IPT_UI_SHOW_PROFILER,
- IPT_UI_TOGGLE_UI,
- IPT_UI_TOGGLE_DEBUG,
- IPT_UI_PASTE,
- IPT_UI_SAVE_STATE,
- IPT_UI_LOAD_STATE,
-
- /* additional OSD-specified UI port types (up to 16) */
- IPT_OSD_1,
- IPT_OSD_2,
- IPT_OSD_3,
- IPT_OSD_4,
- IPT_OSD_5,
- IPT_OSD_6,
- IPT_OSD_7,
- IPT_OSD_8,
- IPT_OSD_9,
- IPT_OSD_10,
- IPT_OSD_11,
- IPT_OSD_12,
- IPT_OSD_13,
- IPT_OSD_14,
- IPT_OSD_15,
- IPT_OSD_16,
-#define __ipt_ui_end IPT_OSD_16
-
- /* other meaning not mapped to standard defaults */
+ // the following are special codes for user interface handling - not to be used by drivers!
+ IPT_UI_FIRST,
+
+ IPT_UI_CONFIGURE,
+ IPT_UI_ON_SCREEN_DISPLAY,
+ IPT_UI_DEBUG_BREAK,
+ IPT_UI_PAUSE,
+ IPT_UI_RESET_MACHINE,
+ IPT_UI_SOFT_RESET,
+ IPT_UI_SHOW_GFX,
+ IPT_UI_FRAMESKIP_DEC,
+ IPT_UI_FRAMESKIP_INC,
+ IPT_UI_THROTTLE,
+ IPT_UI_FAST_FORWARD,
+ IPT_UI_SHOW_FPS,
+ IPT_UI_SNAPSHOT,
+ IPT_UI_RECORD_MOVIE,
+ IPT_UI_TOGGLE_CHEAT,
+ IPT_UI_UP,
+ IPT_UI_DOWN,
+ IPT_UI_LEFT,
+ IPT_UI_RIGHT,
+ IPT_UI_HOME,
+ IPT_UI_END,
+ IPT_UI_PAGE_UP,
+ IPT_UI_PAGE_DOWN,
+ IPT_UI_SELECT,
+ IPT_UI_CANCEL,
+ IPT_UI_DISPLAY_COMMENT,
+ IPT_UI_CLEAR,
+ IPT_UI_ZOOM_IN,
+ IPT_UI_ZOOM_OUT,
+ IPT_UI_PREV_GROUP,
+ IPT_UI_NEXT_GROUP,
+ IPT_UI_ROTATE,
+ IPT_UI_SHOW_PROFILER,
+ IPT_UI_TOGGLE_UI,
+ IPT_UI_TOGGLE_DEBUG,
+ IPT_UI_PASTE,
+ IPT_UI_SAVE_STATE,
+ IPT_UI_LOAD_STATE,
+
+ // additional OSD-specified UI port types (up to 16)
+ IPT_OSD_1,
+ IPT_OSD_2,
+ IPT_OSD_3,
+ IPT_OSD_4,
+ IPT_OSD_5,
+ IPT_OSD_6,
+ IPT_OSD_7,
+ IPT_OSD_8,
+ IPT_OSD_9,
+ IPT_OSD_10,
+ IPT_OSD_11,
+ IPT_OSD_12,
+ IPT_OSD_13,
+ IPT_OSD_14,
+ IPT_OSD_15,
+ IPT_OSD_16,
+
+ IPT_UI_LAST,
+
+ // other meaning not mapped to standard defaults
IPT_OTHER,
- /* special meaning handled by custom code */
+ // special meaning handled by custom code
IPT_SPECIAL,
+ IPT_CUSTOM,
IPT_OUTPUT,
- __ipt_max
+ IPT_COUNT
+};
+DECLARE_ENUM_OPERATORS(ioport_type)
+
+
+// input type classes
+enum ioport_type_class
+{
+ INPUT_CLASS_INTERNAL,
+ INPUT_CLASS_KEYBOARD,
+ INPUT_CLASS_CONTROLLER,
+ INPUT_CLASS_CONFIG,
+ INPUT_CLASS_DIPSWITCH,
+ INPUT_CLASS_MISC
};
-/* default strings used in port definitions */
+// default strings used in port definitions
enum
{
INPUT_STRING_Off = 1,
@@ -627,300 +668,565 @@ enum
};
-/* input classes */
-enum
-{
- INPUT_CLASS_INTERNAL,
- INPUT_CLASS_KEYBOARD,
- INPUT_CLASS_CONTROLLER,
- INPUT_CLASS_CONFIG,
- INPUT_CLASS_DIPSWITCH,
- INPUT_CLASS_MISC
-};
-
-#define UCHAR_PRIVATE (0x100000)
-#define UCHAR_SHIFT_1 (UCHAR_PRIVATE + 0)
-#define UCHAR_SHIFT_2 (UCHAR_PRIVATE + 1)
-#define UCHAR_MAMEKEY_BEGIN (UCHAR_PRIVATE + 2)
-#define UCHAR_MAMEKEY(code) (UCHAR_MAMEKEY_BEGIN + ITEM_ID_##code)
-
-#define UCHAR_SHIFT_BEGIN (UCHAR_SHIFT_1)
-#define UCHAR_SHIFT_END (UCHAR_SHIFT_2)
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/* input ports support up to 32 bits each */
-typedef UINT32 input_port_value;
+// opaque types pointing to live state
+struct input_port_state;
+struct input_field_state;
+// forward declarations
+class ioport_list;
+class ioport_port;
+struct ioport_port_live;
+class ioport_field;
+struct ioport_field_live;
+class ioport_manager;
+class emu_timer;
+typedef struct _xml_data_node xml_data_node;
+class analog_field;
-/* opaque types pointing to live state */
-typedef struct _input_port_state input_port_state;
-typedef struct _input_field_state input_field_state;
-
+// constructor function pointer
+typedef void (*ioport_constructor)(device_t &owner, ioport_list &portlist, astring &errorbuf);
-/* forward declarations */
-class input_port_config;
-class input_field_config;
-class emu_timer;
+// I/O port callback function delegates
+typedef device_delegate<ioport_value (ioport_field &, void *)> ioport_field_read_delegate;
+typedef device_delegate<void (ioport_field &, void *, ioport_value, ioport_value)> ioport_field_write_delegate;
+typedef device_delegate<float (ioport_field &, float)> ioport_field_crossmap_delegate;
-/* template specializations */
-typedef tagged_list<input_port_config> ioport_list;
+// keyboard helper function delegates
+typedef delegate<int (const unicode_char *, size_t)> ioport_queue_chars_delegate;
+typedef delegate<bool (unicode_char)> ioport_accept_char_delegate;
+typedef delegate<bool ()> ioport_charqueue_empty_delegate;
-/* read input port callback function */
-typedef delegate<UINT32 (const input_field_config &, void *)> input_field_read_delegate;
+// ======================> inp_header
-/* input port write callback function */
-typedef delegate<void (const input_field_config &, void *, input_port_value, input_port_value)> input_field_write_delegate;
+// header at the front of INP files
+struct inp_header
+{
+ char header[8]; // +00: 8 byte header - must be "MAMEINP\0"
+ UINT64 basetime; // +08: base time of recording
+ UINT8 majversion; // +10: major INP version
+ UINT8 minversion; // +11: minor INP version
+ UINT8 reserved[2]; // +12: must be zero
+ char gamename[12]; // +14: game name string, NULL-terminated
+ char version[32]; // +20: system version string, NULL-terminated
+};
-/* crosshair mapping function */
-typedef delegate<float (const input_field_config &, float)> input_field_crossmap_delegate;
+// ======================> input_device_default
-/* encapsulates a condition on a port field or setting */
-typedef struct _input_condition input_condition;
-struct _input_condition
+// device defined default input settings
+struct input_device_default
{
- const char * tag; /* tag of port whose condition is to be tested */
- input_port_value mask; /* mask to apply to the port */
- input_port_value value; /* value to compare against */
- UINT8 condition; /* condition to use */
+ const char * tag; // tag of port to update
+ ioport_value mask; // mask to apply to the port
+ ioport_value defvalue; // new default value
};
-/* a single setting for a configuration or DIP switch */
-class input_setting_config
+// ======================> input_type_entry
+
+// describes a fundamental input type, including default input sequences
+class input_type_entry
{
- DISABLE_COPYING(input_setting_config);
- friend class simple_list<input_setting_config>;
+ friend class simple_list<input_type_entry>;
+ friend class ioport_manager;
public:
- input_setting_config(input_field_config &field, input_port_value value, const char *name);
- input_setting_config *next() const { return m_next; }
-
- input_port_value value; /* value of the bits in this setting */
- input_condition condition; /* condition under which this setting is valid */
- const char * name; /* user-friendly name to display */
+ // construction/destruction
+ input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard);
+ input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard, input_seq decrement, input_seq increment);
+ // getters
+ input_type_entry *next() const { return m_next; }
+ ioport_type type() const { return m_type; }
+ ioport_group group() const { return m_group; }
+ UINT8 player() const { return m_player; }
+ const char *token() const { return m_token; }
+ const char *name() const { return m_name; }
+ input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) { return m_defseq[seqtype]; }
+ const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const { return m_seq[seqtype]; }
+
+ // setters
+ void configure_osd(const char *token, const char *name);
+
private:
- input_field_config & m_field; /* pointer back to the field that owns us */
- input_setting_config * m_next; /* pointer to next setting in sequence */
+ // internal state
+ input_type_entry * m_next; // next description in the list
+ ioport_type m_type; // IPT_* for this entry
+ ioport_group m_group; // which group the port belongs to
+ UINT8 m_player; // player number (0 is player 1)
+ const char * m_token; // token used to store settings
+ const char * m_name; // user-friendly name
+ input_seq m_defseq[SEQ_TYPE_TOTAL];// default input sequence
+ input_seq m_seq[SEQ_TYPE_TOTAL];// currently configured sequences
};
-/* a mapping from a bit to a physical DIP switch description */
-class input_field_diplocation
+// ======================> digital_joystick
+
+// tracking information about a digital joystick input
+class digital_joystick
{
- DISABLE_COPYING(input_field_diplocation);
- friend class simple_list<input_field_diplocation>;
+ DISABLE_COPYING(digital_joystick);
+ friend class simple_list<digital_joystick>;
public:
- input_field_diplocation(const char *string, UINT8 swnum, bool invert);
- input_field_diplocation *next() const { return m_next; }
-
- astring swname; /* name of the physical DIP switch */
- UINT8 swnum; /* physical switch number */
- bool invert; /* is this an active-high DIP? */
+ // directions
+ enum direction_t
+ {
+ JOYDIR_UP,
+ JOYDIR_DOWN,
+ JOYDIR_LEFT,
+ JOYDIR_RIGHT,
+ JOYDIR_COUNT
+ };
+
+ // bit constants
+ static const UINT8 UP_BIT = 1 << JOYDIR_UP;
+ static const UINT8 DOWN_BIT = 1 << JOYDIR_DOWN;
+ static const UINT8 LEFT_BIT = 1 << JOYDIR_LEFT;
+ static const UINT8 RIGHT_BIT = 1 << JOYDIR_RIGHT;
+ // construction/destruction
+ digital_joystick(int player, int number);
+
+ // getters
+ digital_joystick *next() const { return m_next; }
+ int player() const { return m_player; }
+ int number() const { return m_number; }
+ UINT8 current() const { return m_current; }
+ UINT8 current4way() const { return m_current4way; }
+
+ // configuration
+ direction_t set_axis(ioport_field &field);
+
+ // updates
+ void frame_update();
+
private:
- input_field_diplocation * m_next; /* pointer to the next bit */
+ // internal state
+ digital_joystick * m_next; // next joystick in the list
+ int m_player; // player number represented
+ int m_number; // joystick number represented
+ ioport_field * m_field[JOYDIR_COUNT]; // input field for each direction
+ UINT8 m_current; // current value
+ UINT8 m_current4way; // current 4-way value
+ UINT8 m_previous; // previous value
};
+DECLARE_ENUM_OPERATORS(digital_joystick::direction_t)
-/* a single bitfield within an input port */
-class input_field_config
+// ======================> natural_keyboard
+
+// buffer to handle copy/paste/insert of keys
+class natural_keyboard
{
- DISABLE_COPYING(input_field_config);
- friend class simple_list<input_field_config>;
+ DISABLE_COPYING(natural_keyboard);
public:
- input_field_config(input_port_config &port, int type, input_port_value defvalue, input_port_value maskbits, const char *name = NULL);
+ // construction/destruction
+ natural_keyboard(running_machine &machine);
+
+ // getters and queries
+ running_machine &machine() const { return m_machine; }
+ bool empty() const { return (m_bufbegin == m_bufend); }
+ bool full() const { return ((m_bufend + 1) % m_buffer.count()) == m_bufbegin; }
+ bool can_post() const { return (!m_queue_chars.isnull() || m_keycode_map.count() == 0); }
+ bool is_posting() const { return (!empty() || (!m_charqueue_empty.isnull() && !m_charqueue_empty())); }
- input_field_config *next() const { return m_next; }
- input_port_config &port() const { return m_port; }
- running_machine &machine() const;
- simple_list<input_setting_config> &settinglist() { return m_settinglist; }
- const simple_list<input_setting_config> &settinglist() const { return m_settinglist; }
- simple_list<input_field_diplocation> &diploclist() { return m_diploclist; }
- int modcount() const { return m_modcount; }
+ // configuration
+ void configure(ioport_queue_chars_delegate queue_chars, ioport_accept_char_delegate accept_char, ioport_charqueue_empty_delegate charqueue_empty);
- /* generally-applicable data */
- input_port_value mask; /* mask of bits belonging to the field */
- input_port_value defvalue; /* default value of these bits */
- input_condition condition; /* condition under which this field is relevant */
- UINT32 type; /* IPT_* type for this port */
- UINT8 player; /* player number (0-based) */
- UINT32 flags; /* combination of FIELD_FLAG_* and ANALOG_FLAG_* above */
- UINT8 impulse; /* number of frames before reverting to defvalue */
- const char * name; /* user-friendly name to display */
- input_seq seq[SEQ_TYPE_TOTAL];/* sequences of all types */
- input_field_read_delegate read; /* read callback routine */
- void * read_param; /* parameter for read callback routine */
- const char * read_device; /* parameter for read callback routine */
- input_field_write_delegate write; /* write callback routine */
- void * write_param; /* parameter for write callback routine */
- const char * write_device; /* parameter for write callback routine */
-
- /* data relevant to analog control types */
- INT32 min; /* minimum value for absolute axes */
- INT32 max; /* maximum value for absolute axes */
- INT32 sensitivity; /* sensitivity (100=normal) */
- INT32 delta; /* delta to apply each frame a digital inc/dec key is pressed */
- INT32 centerdelta; /* delta to apply each frame no digital inputs are pressed */
- UINT8 crossaxis; /* crosshair axis */
- double crossscale; /* crosshair scale */
- double crossoffset; /* crosshair offset */
- double crossaltaxis; /* crosshair alternate axis value */
- input_field_crossmap_delegate crossmapper; /* crosshair mapping function */
- const char * crossmapper_device; /* parameter for write callback routine */
- UINT16 full_turn_count;/* number of optical counts for 1 full turn of the original control */
- const input_port_value * remap_table; /* pointer to an array that remaps the port value */
-
- /* data relevant to other specific types */
- UINT8 way; /* digital joystick 2/4/8-way descriptions */
- unicode_char chars[3]; /* (MESS-specific) unicode key data */
-
- /* this field is only valid if the device is live */
- input_field_state * state; /* live state of field (NULL if not live) */
+ // posting
+ void post(unicode_char ch);
+ void post(const unicode_char *text, size_t length = 0, attotime rate = attotime::zero);
+ void post_utf8(const char *text, size_t length = 0, attotime rate = attotime::zero);
+ void post_coded(const char *text, size_t length = 0, attotime rate = attotime::zero);
+
+ void frame_update(ioport_port &port, ioport_value &digital);
+ const char *key_name(astring &string, unicode_char ch);
private:
- input_field_config * m_next; /* pointer to next field in sequence */
- input_port_config & m_port; /* pointer back to the port that owns us */
- int m_modcount;
- simple_list<input_setting_config> m_settinglist; /* list of input_setting_configs */
- simple_list<input_field_diplocation> m_diploclist; /* list of locations for various bits */
+ // internal keyboard code information
+ struct keycode_map_entry
+ {
+ unicode_char ch;
+ ioport_field * field[UCHAR_SHIFT_END + 1 - UCHAR_SHIFT_BEGIN];
+ };
+
+ // internal helpers
+ void build_codes(ioport_manager &manager);
+ bool can_post_directly(unicode_char ch);
+ bool can_post_alternate(unicode_char ch);
+ attotime choose_delay(unicode_char ch);
+ void internal_post(unicode_char ch);
+ void timer(void *ptr, int param);
+ const char *unicode_to_string(astring &buffer, unicode_char ch);
+ const keycode_map_entry *find_code(unicode_char ch) const;
+
+ // debugger helpers
+ static void execute_input(running_machine &machine, int ref, int params, const char *param[]);
+ static void execute_dumpkbd(running_machine &machine, int ref, int params, const char *param[]);
+
+ // internal state
+ running_machine & m_machine; // reference to our machine
+ UINT32 m_bufbegin; // index of starting character
+ UINT32 m_bufend; // index of ending character
+ dynamic_array<unicode_char> m_buffer; // actual buffer
+ bool m_status_keydown; // current keydown status
+ bool m_last_cr; // was the last char a CR?
+ emu_timer * m_timer; // timer for posting characters
+ attotime m_current_rate; // current rate for posting
+ ioport_queue_chars_delegate m_queue_chars; // queue characters callback
+ ioport_accept_char_delegate m_accept_char; // accept character callback
+ ioport_charqueue_empty_delegate m_charqueue_empty; // character queue empty callback
+ dynamic_array<keycode_map_entry> m_keycode_map; // keycode map
};
-/* user-controllable settings for a field */
-typedef struct _input_field_user_settings input_field_user_settings;
-struct _input_field_user_settings
-{
- input_port_value value; /* for DIP switches */
- input_seq seq[SEQ_TYPE_TOTAL];/* sequences of all types */
- INT32 sensitivity; /* for analog controls */
- INT32 delta; /* for analog controls */
- INT32 centerdelta; /* for analog controls */
- UINT8 reverse; /* for analog controls */
-};
+// ======================> ioport_condition
-/* device defined default input settings */
-typedef struct _input_device_default input_device_default;
-struct _input_device_default
+// encapsulates a condition on a port field or setting
+class ioport_condition
{
- const char * tag; /* tag of port to update */
- input_port_value mask; /* mask to apply to the port */
- input_port_value defvalue; /* new default value */
+public:
+ // condition types
+ enum condition_t
+ {
+ ALWAYS = 0,
+ EQUALS,
+ NOTEQUALS,
+ GREATERTHAN,
+ NOTGREATERTHAN,
+ LESSTHAN,
+ NOTLESSTHAN
+ };
+
+ // construction/destruction
+ ioport_condition() { reset(); }
+ ioport_condition(condition_t condition, const char *tag, ioport_value mask, ioport_value value) { set(condition, tag, mask, value); }
+
+ // getters
+ const char *tag() const { return m_tag; }
+
+ // operators
+ bool operator==(const ioport_condition &rhs) const { return (m_mask == rhs.m_mask && m_value == rhs.m_value && m_condition == rhs.m_condition && strcmp(m_tag, rhs.m_tag) == 0); }
+ bool eval(device_t &device) const;
+ bool none() const { return (m_condition == ALWAYS); }
+
+ // configuration
+ void reset() { set(ALWAYS, NULL, 0, 0); }
+ void set(condition_t condition, const char *tag, ioport_value mask, ioport_value value)
+ {
+ m_condition = condition;
+ m_tag = tag;
+ m_mask = mask;
+ m_value = value;
+ }
+
+private:
+ // internal state
+ condition_t m_condition; // condition to use
+ const char * m_tag; // tag of port whose condition is to be tested
+ ioport_value m_mask; // mask to apply to the port
+ ioport_value m_value; // value to compare against
};
-/* a single input port configuration */
-class input_port_config
+
+// ======================> ioport_setting
+
+// a single setting for a configuration or DIP switch
+class ioport_setting
{
- DISABLE_COPYING(input_port_config);
- friend class simple_list<input_port_config>;
+ DISABLE_COPYING(ioport_setting);
+ friend class simple_list<ioport_setting>;
public:
// construction/destruction
- input_port_config(device_t &owner, const char *tag);
-
+ ioport_setting(ioport_field &field, ioport_value value, const char *name);
+
// getters
- input_port_config *next() const { return m_next; }
- device_t &owner() const { return m_owner; }
+ ioport_setting *next() const { return m_next; }
+ ioport_field &field() const { return m_field; }
+ device_t &device() const;
running_machine &machine() const;
- input_field_config *first_field() const { return m_fieldlist.first(); }
- simple_list<input_field_config> &fieldlist() { return m_fieldlist; }
- const char *tag() const { return m_tag; }
- int modcount() const { return m_modcount; }
+ ioport_value value() const { return m_value; }
+ ioport_condition &condition() { return m_condition; }
+ const char *name() const { return m_name; }
- void bump_modcount() { m_modcount++; }
+ // helpers
+ bool enabled() { return m_condition.eval(device()); }
- void collapse_fields(astring &errorbuf);
+private:
+ // internal state
+ ioport_setting * m_next; // pointer to next setting in sequence
+ ioport_field & m_field; // pointer back to the field that owns us
+ ioport_value m_value; // value of the bits in this setting
+ const char * m_name; // user-friendly name to display
+ ioport_condition m_condition; // condition under which this setting is valid
+};
- /* these fields are only valid if the port is live */
- input_port_state * state; /* live state of port (NULL if not live) */
- input_port_value active; /* mask of active bits in the port */
+
+// ======================> ioport_diplocation
+
+// a mapping from a bit to a physical DIP switch description
+class ioport_diplocation
+{
+ DISABLE_COPYING(ioport_diplocation);
+ friend class simple_list<ioport_diplocation>;
+
+public:
+ // construction/destruction
+ ioport_diplocation(const char *name, UINT8 swnum, bool invert);
+
+ // getters
+ ioport_diplocation *next() const { return m_next; }
+ const char *name() const { return m_name; }
+ UINT8 number() const { return m_number; }
+ bool inverted() const { return m_invert; }
private:
- input_port_config * m_next; /* pointer to next port */
- device_t & m_owner; /* associated device, when appropriate */
- simple_list<input_field_config> m_fieldlist; /* list of input_field_configs */
- astring m_tag; /* pointer to this port's tag */
- int m_modcount;
+ ioport_diplocation * m_next; // pointer to the next bit
+ astring m_name; // name of the physical DIP switch
+ UINT8 m_number; // physical switch number
+ bool m_invert; // is this an active-high DIP?
};
-/* describes a fundamental input type, including default input sequences */
-class input_type_entry
+// ======================> ioport_field
+
+// a single bitfield within an input port
+class ioport_field
{
- friend class simple_list<input_type_entry>;
+ DISABLE_COPYING(ioport_field);
+ friend class simple_list<ioport_field>;
+ friend class ioport_configurer;
+ friend class dynamic_field;
+
+ // flags for ioport_fields
+ static const int FIELD_FLAG_UNUSED = 0x01; // set if this field is unused but relevant to other games on the same hw
+ static const int FIELD_FLAG_COCKTAIL = 0x02; // set if this field is relevant only for cocktail cabinets
+ static const int FIELD_FLAG_TOGGLE = 0x04; // set if this field should behave as a toggle
+ static const int FIELD_FLAG_ROTATED = 0x08; // set if this field represents a rotated control
+ static const int ANALOG_FLAG_REVERSE = 0x10; // analog only: reverse the sense of the axis
+ static const int ANALOG_FLAG_RESET = 0x20; // analog only: always preload in->default for relative axes, returning only deltas
+ static const int ANALOG_FLAG_WRAPS = 0x40; // analog only: positional count wraps around
+ static const int ANALOG_FLAG_INVERT = 0x80; // analog only: bitwise invert bits
public:
- input_type_entry(UINT32 type, ioport_group group, int player, const char *token, const char *name, input_seq standard);
- input_type_entry(UINT32 type, ioport_group group, int player, const char *token, const char *name, input_seq standard, input_seq decrement, input_seq increment);
-
- input_type_entry *next() const { return m_next; }
+ // construction/destruction
+ ioport_field(ioport_port &port, ioport_type type, ioport_value defvalue, ioport_value maskbits, const char *name = NULL);
+ ~ioport_field();
- UINT32 type; /* IPT_* for this entry */
- ioport_group group; /* which group the port belongs to */
- UINT8 player; /* player number (0 is player 1) */
- const char * token; /* token used to store settings */
- const char * name; /* user-friendly name */
- input_seq defseq[SEQ_TYPE_TOTAL];/* default input sequence */
- input_seq seq[SEQ_TYPE_TOTAL];/* currently configured sequences */
+ // getters
+ ioport_field *next() const { return m_next; }
+ ioport_port &port() const { return m_port; }
+ device_t &device() const;
+ ioport_manager &manager() const;
+ running_machine &machine() const;
+ int modcount() const { return m_modcount; }
+ ioport_setting *first_setting() const { return m_settinglist.first(); }
+ ioport_diplocation *first_diplocation() const { return m_diploclist.first(); }
+
+ ioport_value mask() const { return m_mask; }
+ ioport_value defvalue() const { return m_defvalue; }
+ ioport_condition &condition() { return m_condition; }
+ ioport_type type() const { return m_type; }
+ UINT8 player() const { return m_player + 1; }
+
+ bool unused() const { return ((m_flags & FIELD_FLAG_UNUSED) != 0); }
+ bool cocktail() const { return ((m_flags & FIELD_FLAG_COCKTAIL) != 0); }
+ bool toggle() const { return ((m_flags & FIELD_FLAG_TOGGLE) != 0); }
+ bool rotated() const { return ((m_flags & FIELD_FLAG_ROTATED) != 0); }
+ bool analog_reverse() const { return ((m_flags & ANALOG_FLAG_REVERSE) != 0); }
+ bool analog_reset() const { return ((m_flags & ANALOG_FLAG_RESET) != 0); }
+ bool analog_wraps() const { return ((m_flags & ANALOG_FLAG_WRAPS) != 0); }
+ bool analog_invert() const { return ((m_flags & ANALOG_FLAG_INVERT) != 0); }
+
+ UINT8 impulse() const { return m_impulse; }
+ const char *name() const;
+ const char *specific_name() const { return m_name; }
+ const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const;
+ bool has_dynamic_read() const { return !m_read.isnull(); }
+ bool has_dynamic_write() const { return !m_write.isnull(); }
+
+ ioport_value minval() const { return m_min; }
+ ioport_value maxval() const { return m_max; }
+ INT32 sensitivity() const { return m_sensitivity; }
+ INT32 delta() const { return m_delta; }
+ INT32 centerdelta() const { return m_centerdelta; }
+ crosshair_axis_t crosshair_axis() const { return m_crosshair_axis; }
+ double crosshair_scale() const { return m_crosshair_scale; }
+ double crosshair_offset() const { return m_crosshair_offset; }
+ UINT16 full_turn_count() const { return m_full_turn_count; }
+ const ioport_value *remap_table() const { return m_remap_table; }
+
+ UINT8 way() const { return m_way; }
+ unicode_char keyboard_code(int which) const;
+ ioport_field_live &live() const { assert(m_live != NULL); return *m_live; }
+
+ // setters
+ void set_crosshair_scale(double scale) { m_crosshair_scale = scale; }
+ void set_crosshair_offset(double offset) { m_crosshair_offset = offset; }
+
+ // derived getters
+ ioport_type_class type_class() const;
+ bool is_analog() const { return (m_type > IPT_ANALOG_FIRST && m_type < IPT_ANALOG_LAST); }
+ bool is_digital_joystick() const { return (m_type > IPT_DIGITAL_JOYSTICK_FIRST && m_type < IPT_DIGITAL_JOYSTICK_LAST); }
+
+ // additional operations
+ bool enabled() const { return m_condition.eval(device()); }
+ const char *setting_name() const;
+ bool has_previous_setting() const;
+ void select_previous_setting();
+ bool has_next_setting() const;
+ void select_next_setting();
+ void crosshair_position(float &x, float &y, bool &gotx, bool &goty);
+ void init_live_state(analog_field *analog);
+ void frame_update(ioport_value &result, bool mouse_down);
+ void reduce_mask(ioport_value bits_to_remove) { m_mask &= ~bits_to_remove; }
+
+ // user-controllable settings for a field
+ struct user_settings
+ {
+ ioport_value value; // for DIP switches
+ input_seq seq[SEQ_TYPE_TOTAL]; // sequences of all types
+ INT32 sensitivity; // for analog controls
+ INT32 delta; // for analog controls
+ INT32 centerdelta; // for analog controls
+ bool reverse; // for analog controls
+ };
+ void get_user_settings(user_settings &settings);
+ void set_user_settings(const user_settings &settings);
private:
- input_type_entry * m_next; /* next description in the list */
+ void expand_diplocation(const char *location, astring &errorbuf);
+
+ // internal state
+ ioport_field * m_next; // pointer to next field in sequence
+ ioport_port & m_port; // reference to the port that owns us
+ ioport_field_live * m_live; // live state of field (NULL if not live)
+ int m_modcount; // modification count
+ simple_list<ioport_setting> m_settinglist; // list of input_setting_configs
+ simple_list<ioport_diplocation> m_diploclist; // list of locations for various bits
+
+ // generally-applicable data
+ ioport_value m_mask; // mask of bits belonging to the field
+ ioport_value m_defvalue; // default value of these bits
+ ioport_condition m_condition; // condition under which this field is relevant
+ ioport_type m_type; // IPT_* type for this port
+ UINT8 m_player; // player number (0-based)
+ UINT32 m_flags; // combination of FIELD_FLAG_* and ANALOG_FLAG_* above
+ UINT8 m_impulse; // number of frames before reverting to defvalue
+ const char * m_name; // user-friendly name to display
+ input_seq m_seq[SEQ_TYPE_TOTAL];// sequences of all types
+ ioport_field_read_delegate m_read; // read callback routine
+ void * m_read_param; // parameter for read callback routine
+ ioport_field_write_delegate m_write; // write callback routine
+ void * m_write_param; // parameter for write callback routine
+
+ // data relevant to analog control types
+ ioport_value m_min; // minimum value for absolute axes
+ ioport_value m_max; // maximum value for absolute axes
+ INT32 m_sensitivity; // sensitivity (100=normal)
+ INT32 m_delta; // delta to apply each frame a digital inc/dec key is pressed
+ INT32 m_centerdelta; // delta to apply each frame no digital inputs are pressed
+ crosshair_axis_t m_crosshair_axis; // crosshair axis
+ double m_crosshair_scale; // crosshair scale
+ double m_crosshair_offset; // crosshair offset
+ double m_crosshair_altaxis;// crosshair alternate axis value
+ ioport_field_crossmap_delegate m_crosshair_mapper; // crosshair mapping function
+ UINT16 m_full_turn_count; // number of optical counts for 1 full turn of the original control
+ const ioport_value * m_remap_table; // pointer to an array that remaps the port value
+
+ // data relevant to other specific types
+ UINT8 m_way; // digital joystick 2/4/8-way descriptions
+ unicode_char m_chars[4]; // unicode key data
};
-/* header at the front of INP files */
-typedef struct _inp_header inp_header;
-struct _inp_header
+// ======================> ioport_list
+
+// class that holds a list of I/O ports
+class ioport_list : public tagged_list<ioport_port>
{
- char header[8]; /* +00: 8 byte header - must be "MAMEINP\0" */
- UINT64 basetime; /* +08: base time of recording */
- UINT8 majversion; /* +10: major INP version */
- UINT8 minversion; /* +11: minor INP version */
- UINT8 reserved[2]; /* +12: must be zero */
- char gamename[12]; /* +14: game name string, NULL-terminated */
- char version[32]; /* +20: system version string, NULL-terminated */
-};
+ DISABLE_COPYING(ioport_list);
+public:
+ // construction/destruction
+ ioport_list(resource_pool &pool = global_resource_pool())
+ : tagged_list<ioport_port>(pool) { }
-struct digital_joystick_state
-{
- const input_field_config * field[4]; /* input field for up, down, left, right respectively */
- UINT8 inuse; /* is this joystick used? */
- UINT8 current; /* current value */
- UINT8 current4way; /* current 4-way value */
- UINT8 previous; /* previous value */
+ using tagged_list<ioport_port>::append;
+ void append(device_t &device, astring &errorbuf);
};
-#define DIGITAL_JOYSTICKS_PER_PLAYER 3
-#define NUM_SIMUL_KEYS (UCHAR_SHIFT_END - UCHAR_SHIFT_BEGIN + 1)
-struct inputx_code
-{
- unicode_char ch;
- const input_field_config * field[NUM_SIMUL_KEYS];
-};
+// ======================> ioport_port
-struct key_buffer
+// a single input port configuration
+class ioport_port
{
- int begin_pos;
- int end_pos;
- unsigned int status_keydown : 1;
- int size;
- unicode_char *buffer;
+ DISABLE_COPYING(ioport_port);
+ friend class simple_list<ioport_port>;
+ friend class ioport_configurer;
+
+public:
+ // construction/destruction
+ ioport_port(device_t &owner, const char *tag);
+ ~ioport_port();
+
+ // getters
+ ioport_port *next() const { return m_next; }
+ ioport_manager &manager() const;
+ device_t &device() const { return m_device; }
+ running_machine &machine() const;
+ ioport_field *first_field() const { return m_fieldlist.first(); }
+ const char *tag() const { return m_tag; }
+ int modcount() const { return m_modcount; }
+ ioport_value active() const { return m_active; }
+ ioport_value active_safe(ioport_value defval) const { return (this == NULL) ? defval : active(); }
+ ioport_port_live &live() const { assert(m_live != NULL); return *m_live; }
+
+ // read/write to the port
+ ioport_value read();
+ ioport_value read_safe(ioport_value defval) { return (this == NULL) ? defval : read(); }
+ void write(ioport_value value, ioport_value mask = ~0);
+ void write_safe(ioport_value value, ioport_value mask = ~0) { if (this != NULL) write(value, mask); }
+
+ // other operations
+ ioport_field *field(ioport_value mask);
+ void collapse_fields(astring &errorbuf);
+ void frame_update(ioport_field *mouse_field);
+ void init_live_state();
+
+private:
+ void insert_field(ioport_field &newfield, ioport_value &disallowedbits, astring &errorbuf);
+
+ // internal state
+ ioport_port * m_next; // pointer to next port
+ device_t & m_device; // associated device
+ simple_list<ioport_field> m_fieldlist; // list of ioport_fields
+ astring m_tag; // copy of this port's tag
+ int m_modcount; // modification count
+ ioport_value m_active; // mask of active bits in the port
+ ioport_port_live * m_live; // live state of port (NULL if not live)
};
-/* private input port state */
+
+// ======================> ioport_manager
+
+// private input port state
class ioport_manager
{
+ DISABLE_COPYING(ioport_manager);
friend class device_t;
+ friend class ioport_configurer;
public:
// construction/destruction
@@ -929,368 +1235,406 @@ public:
// getters
running_machine &machine() const { return m_machine; }
- input_port_config *first_port() const { return m_portlist.first(); }
-
- /* global state */
- UINT8 safe_to_read; /* clear at start; set after state is loaded */
-
- /* types */
- simple_list<input_type_entry> typelist; /* list of live type states */
- input_type_entry * type_to_entry[__ipt_max][MAX_PLAYERS]; /* map from type/player to type state */
-
- /* specific special global input states */
- digital_joystick_state joystick_info[MAX_PLAYERS][DIGITAL_JOYSTICKS_PER_PLAYER]; /* joystick states */
-
- /* frame time tracking */
- attotime last_frame_time; /* time of the last frame callback */
- attoseconds_t last_delta_nsec; /* nanoseconds that passed since the previous callback */
-
- /* playback/record information */
- emu_file * record_file; /* recording file (NULL if not recording) */
- emu_file * playback_file; /* playback file (NULL if not recording) */
- UINT64 playback_accumulated_speed;/* accumulated speed during playback */
- UINT32 playback_accumulated_frames;/* accumulated frames during playback */
-
- /* inputx */
- inputx_code *codes;
- key_buffer keybuffer;
- emu_timer *inputx_timer;
- int (*queue_chars)(running_machine &machine, const unicode_char *text, size_t text_len);
- int (*accept_char)(running_machine &machine, unicode_char ch);
- int (*charqueue_empty)(running_machine &machine);
- attotime current_rate;
+ ioport_port *first_port() const { return m_portlist.first(); }
+ bool safe_to_read() const { return m_safe_to_read; }
+ natural_keyboard &natkeyboard() { return m_natkeyboard; }
+
+ // type helpers
+ input_type_entry *first_type() const { return m_typelist.first(); }
+ bool type_pressed(ioport_type type, int player = 0);
+ const char *type_name(ioport_type type, UINT8 player);
+ ioport_group type_group(ioport_type type, int player);
+ const input_seq &type_seq(ioport_type type, int player = 0, input_seq_type seqtype = SEQ_TYPE_STANDARD);
+ void set_type_seq(ioport_type type, int player, input_seq_type seqtype, const input_seq &newseq);
+ static bool type_is_analog(ioport_type type) { return (type > IPT_ANALOG_FIRST && type < IPT_ANALOG_LAST); }
+ bool type_class_present(ioport_type_class inputclass);
+
+ // other helpers
+ digital_joystick &digjoystick(int player, int joysticknum);
+ int count_players() const;
+ bool crosshair_position(int player, float &x, float &y);
+ bool has_keyboard() const;
+ void setup_natural_keyboard(ioport_queue_chars_delegate queue_chars, ioport_accept_char_delegate accept_char, ioport_charqueue_empty_delegate charqueue_empty);
+ ioport_value frame_interpolate(ioport_value oldval, ioport_value newval);
+ ioport_type token_to_input_type(const char *string, int &player) const;
+ const char *input_type_to_token(astring &string, ioport_type type, int player);
+ void frame_update();
private:
- input_port_config *port(const char *tag) const { return m_portlist.find(tag); }
-
- // internals
- ioport_list m_portlist; // points to a list of input port configurations
+ // internal helpers
+ void init_port_types();
+ void init_autoselect_devices(int type1, int type2, int type3, const char *option, const char *ananame);
+
+ ioport_port *port(const char *tag) const { return m_portlist.find(tag); }
+ void exit();
+ input_seq_type token_to_seq_type(const char *string);
+ void update_defaults();
+
+ void load_config(int config_type, xml_data_node *parentnode);
+ void load_remap_table(xml_data_node *parentnode);
+ bool load_default_config(xml_data_node *portnode, int type, int player, const input_seq *newseq);
+ bool load_game_config(xml_data_node *portnode, int type, int player, const input_seq *newseq);
+
+ void save_config(int config_type, xml_data_node *parentnode);
+ void save_sequence(xml_data_node *parentnode, input_seq_type type, ioport_type porttype, const input_seq &seq);
+ bool save_this_input_field_type(ioport_type type);
+ void save_default_inputs(xml_data_node *parentnode);
+ void save_game_inputs(xml_data_node *parentnode);
+
+ template<typename _Type> _Type playback_read(_Type &result);
+ time_t playback_init();
+ void playback_end(const char *message = NULL);
+ void playback_frame(attotime curtime);
+ void playback_port(ioport_port &port);
+
+ template<typename _Type> void record_write(_Type value);
+ void record_init();
+ void record_end(const char *message = NULL);
+ void record_frame(attotime curtime);
+ void record_port(ioport_port &port);
// internal state
- running_machine & m_machine;
+ running_machine & m_machine; // reference to owning machine
+ bool m_safe_to_read; // clear at start; set after state is loaded
+ ioport_list m_portlist; // list of input port configurations
+
+ // types
+ simple_list<input_type_entry> m_typelist; // list of live type states
+ input_type_entry * m_type_to_entry[IPT_COUNT][MAX_PLAYERS]; // map from type/player to type state
+
+ // specific special global input states
+ simple_list<digital_joystick> m_joystick_list; // list of digital joysticks
+ natural_keyboard m_natkeyboard; // natural keyboard support
+
+ // frame time tracking
+ attotime m_last_frame_time; // time of the last frame callback
+ attoseconds_t m_last_delta_nsec; // nanoseconds that passed since the previous callback
+
+ // playback/record information
+ emu_file m_record_file; // recording file (NULL if not recording)
+ emu_file m_playback_file; // playback file (NULL if not recording)
+ UINT64 m_playback_accumulated_speed; // accumulated speed during playback
+ UINT32 m_playback_accumulated_frames; // accumulated frames during playback
};
-/***************************************************************************
- MACROS
-***************************************************************************/
+// ======================> ioport_configurer
-/* macro for a read callback function (PORT_CUSTOM) */
-#define CUSTOM_INPUT(name) input_port_value name(device_t &device, const input_field_config &field, void *param)
-#define CUSTOM_INPUT_MEMBER(name) input_port_value name(const input_field_config &field, void *param)
-#define DECLARE_CUSTOM_INPUT_MEMBER(name) input_port_value name(const input_field_config &field, void *param)
+// class to wrap helper functions
+class ioport_configurer
+{
+public:
+ // construction/destruction
+ ioport_configurer(device_t &owner, ioport_list &portlist, astring &errorbuf);
+
+ // static helpers
+ static const char *string_from_token(const char *string);
+
+ // port helpers
+ void port_alloc(const char *tag);
+ void port_modify(const char *tag);
+
+ // field helpers
+ void field_alloc(ioport_type type, ioport_value defval, ioport_value mask, const char *name = NULL);
+ void field_add_char(unicode_char ch);
+ void field_add_code(input_seq_type which, input_code code);
+ void field_set_way(int way) const { m_curfield->m_way = way; }
+ void field_set_rotated() const { m_curfield->m_flags |= ioport_field::FIELD_FLAG_ROTATED; }
+ void field_set_name(const char *name) const { m_curfield->m_name = string_from_token(name); }
+ void field_set_player(int player) const { m_curfield->m_player = player - 1; }
+ void field_set_cocktail() const { m_curfield->m_flags |= ioport_field::FIELD_FLAG_COCKTAIL; field_set_player(2); }
+ void field_set_toggle() const { m_curfield->m_flags |= ioport_field::FIELD_FLAG_TOGGLE; }
+ void field_set_impulse(UINT8 impulse) const { m_curfield->m_impulse = impulse; }
+ void field_set_analog_reverse() const { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_REVERSE; }
+ void field_set_analog_reset() const { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_RESET; }
+ void field_set_unused() const { m_curfield->m_flags |= ioport_field::FIELD_FLAG_UNUSED; }
+ void field_set_min_max(ioport_value minval, ioport_value maxval) const { m_curfield->m_min = minval; m_curfield->m_max = maxval; }
+ void field_set_sensitivity(INT32 sensitivity) const { m_curfield->m_sensitivity = sensitivity; }
+ void field_set_delta(INT32 delta) const { m_curfield->m_centerdelta = m_curfield->m_delta = delta; }
+ void field_set_centerdelta(INT32 delta) const { m_curfield->m_centerdelta = delta; }
+ void field_set_crosshair(crosshair_axis_t axis, double altaxis, double scale, double offset) const { m_curfield->m_crosshair_axis = axis; m_curfield->m_crosshair_altaxis = altaxis; m_curfield->m_crosshair_scale = scale; m_curfield->m_crosshair_offset = offset; }
+ void field_set_crossmapper(ioport_field_crossmap_delegate callback) const { m_curfield->m_crosshair_mapper = callback; }
+ void field_set_full_turn_count(UINT16 count) const { m_curfield->m_full_turn_count = count; }
+ void field_set_analog_wraps() const { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_WRAPS; }
+ void field_set_remap_table(const ioport_value *table) { m_curfield->m_remap_table = table; }
+ void field_set_analog_invert() const { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_INVERT; }
+ void field_set_dynamic_read(ioport_field_read_delegate delegate, void *param = NULL) const { m_curfield->m_read = delegate; m_curfield->m_read_param = param; }
+ void field_set_dynamic_write(ioport_field_write_delegate delegate, void *param = NULL) const { m_curfield->m_write = delegate; m_curfield->m_write_param = param; }
+ void field_set_diplocation(const char *location) const { m_curfield->expand_diplocation(location, m_errorbuf); }
+
+ // setting helpers
+ void setting_alloc(ioport_value value, const char *name);
+
+ // misc helpers
+ void set_condition(ioport_condition::condition_t condition, const char *tag, ioport_value mask, ioport_value value);
+ void onoff_alloc(const char *name, ioport_value defval, ioport_value mask, const char *diplocation);
-/* macro for port write callback functions (PORT_CHANGED) */
-#define INPUT_CHANGED(name) void name(device_t &device, const input_field_config &field, void *param, input_port_value oldval, input_port_value newval)
-#define INPUT_CHANGED_MEMBER(name) void name(const input_field_config &field, void *param, input_port_value oldval, input_port_value newval)
-#define DECLARE_INPUT_CHANGED_MEMBER(name) void name(const input_field_config &field, void *param, input_port_value oldval, input_port_value newval)
+private:
+ // internal state
+ device_t & m_owner;
+ ioport_list & m_portlist;
+ astring & m_errorbuf;
+
+ ioport_port * m_curport;
+ ioport_field * m_curfield;
+ ioport_setting * m_cursetting;
+};
-/* macro for port changed callback functions (PORT_CROSSHAIR_MAPPER) */
-#define CROSSHAIR_MAPPER(name) float name(device_t &device, const input_field_config &field, float linear_value)
-#define CROSSHAIR_MAPPER_MEMBER(name) float name(const input_field_config &field, float linear_value)
-#define DECLARE_CROSSHAIR_MAPPER_MEMBER(name) float name(const input_field_config &field, float linear_value)
-/* macro for wrapping a default string */
-#define DEF_STR(str_num) ((const char *)INPUT_STRING_##str_num)
+//**************************************************************************
+// MACROS
+//**************************************************************************
-template<int (*_FunctionPointer)(device_t *)>
-input_port_value ioport_read_line_wrapper(device_t &device, const input_field_config &field, void *param)
-{
- return (*_FunctionPointer)(&device);
-}
+#define UCHAR_MAMEKEY(code) (UCHAR_MAMEKEY_BEGIN + ITEM_ID_##code)
-template<class _FunctionClass, int (_FunctionClass::*_FunctionPointer)()>
-input_port_value ioport_read_line_wrapper(_FunctionClass &device, const input_field_config &field, void *param)
-{
- return (device.*_FunctionPointer)();
-}
+// macro for a read callback function (PORT_CUSTOM)
+#define CUSTOM_INPUT(name) ioport_value name(device_t &device, ioport_field &field, void *param)
+#define CUSTOM_INPUT_MEMBER(name) ioport_value name(ioport_field &field, void *param)
+#define DECLARE_CUSTOM_INPUT_MEMBER(name) ioport_value name(ioport_field &field, void *param)
-template<void (*_FunctionPointer)(device_t *, int)>
-void ioport_write_line_wrapper(device_t &device, const input_field_config &field, void *param, input_port_value oldval, input_port_value newval)
-{
- return (*_FunctionPointer)(&device, newval);
-}
+// macro for port write callback functions (PORT_CHANGED)
+#define INPUT_CHANGED(name) void name(device_t &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
+#define INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
+#define DECLARE_INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
-template<class _FunctionClass, void (_FunctionClass::*_FunctionPointer)(int)>
-void ioport_write_line_wrapper(_FunctionClass &device, const input_field_config &field, void *param, input_port_value oldval, input_port_value newval)
-{
- return (device.*_FunctionPointer)(newval);
-}
+// macro for port changed callback functions (PORT_CROSSHAIR_MAPPER)
+#define CROSSHAIR_MAPPER(name) float name(device_t &device, ioport_field &field, float linear_value)
+#define CROSSHAIR_MAPPER_MEMBER(name) float name(ioport_field &field, float linear_value)
+#define DECLARE_CROSSHAIR_MAPPER_MEMBER(name) float name(ioport_field &field, float linear_value)
+// macro for wrapping a default string
+#define DEF_STR(str_num) ((const char *)INPUT_STRING_##str_num)
-/***************************************************************************
- MACROS FOR BUILDING INPUT PORTS
-***************************************************************************/
-typedef void (*ioport_constructor)(device_t &owner, ioport_list &portlist, astring &errorbuf);
+//**************************************************************************
+// MACROS FOR BUILDING INPUT PORTS
+//**************************************************************************
-/* so that "0" can be used for unneeded input ports */
+// so that "0" can be used for unneeded input ports
#define construct_ioport_0 NULL
-/* name of table */
+// name of table
#define INPUT_PORTS_NAME(_name) construct_ioport_##_name
-/* start of table */
+// start of table
#define INPUT_PORTS_START(_name) \
ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, astring &errorbuf) \
{ \
- astring fulltag; \
- input_setting_config *cursetting = NULL; \
- input_field_config *curfield = NULL; \
- input_port_config *curport = NULL; \
- input_port_value maskbits = 0; \
- (void)cursetting; (void)curfield; (void)curport; (void)maskbits; \
-
-/* end of table */
+ ioport_configurer configurer(owner, portlist, errorbuf); \
+
+// end of table
#define INPUT_PORTS_END \
}
-/* aliasing */
+// aliasing
#define INPUT_PORTS_EXTERN(_name) \
extern void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, astring &errorbuf)
-/* including */
+// including
#define PORT_INCLUDE(_name) \
INPUT_PORTS_NAME(_name)(owner, portlist, errorbuf); \
-/* start of a new input port (with included tag) */
+// start of a new input port (with included tag)
#define PORT_START(_tag) \
- curport = ioconfig_alloc_port(portlist, owner, _tag); \
- curfield = NULL; \
- cursetting = NULL; \
- maskbits = 0; \
+ configurer.port_alloc(_tag); \
-/* modify an existing port */
+// modify an existing port
#define PORT_MODIFY(_tag) \
- curport = ioconfig_modify_port(portlist, owner, _tag); \
- curfield = NULL; \
- cursetting = NULL; \
- maskbits = 0; \
+ configurer.port_modify(_tag); \
-/* input bit definition */
+// input bit definition
#define PORT_BIT(_mask, _default, _type) \
- curfield = ioconfig_alloc_field(*curport, (_type), (_default), (_mask)); \
- cursetting = NULL;
+ configurer.field_alloc((_type), (_default), (_mask)); \
-#define PORT_SPECIAL_ONOFF(_mask, _default, _strindex) PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, _strindex, NULL)
+#define PORT_SPECIAL_ONOFF(_mask, _default, _strindex) \
+ PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, _strindex, NULL)
#define PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, _strindex, _diploc) \
- curfield = ioconfig_alloc_onoff(*curport, DEF_STR(_strindex), _default, _mask, _diploc, errorbuf); \
- cursetting = NULL;
+ configurer.onoff_alloc(DEF_STR(_strindex), _default, _mask, _diploc); \
-/* append a code */
+// append a code
#define PORT_CODE(_code) \
- ioconfig_add_code(*curfield, SEQ_TYPE_STANDARD, _code);
+ configurer.field_add_code(SEQ_TYPE_STANDARD, _code);
#define PORT_CODE_DEC(_code) \
- ioconfig_add_code(*curfield, SEQ_TYPE_DECREMENT, _code);
+ configurer.field_add_code(SEQ_TYPE_DECREMENT, _code);
#define PORT_CODE_INC(_code) \
- ioconfig_add_code(*curfield, SEQ_TYPE_INCREMENT, _code);
+ configurer.field_add_code(SEQ_TYPE_INCREMENT, _code);
-/* joystick flags */
+// joystick flags
#define PORT_2WAY \
- curfield->way = 2;
+ configurer.field_set_way(2);
#define PORT_4WAY \
- curfield->way = 4;
+ configurer.field_set_way(4);
#define PORT_8WAY \
- curfield->way = 8;
+ configurer.field_set_way(8);
#define PORT_16WAY \
- curfield->way = 16;
+ configurer.field_set_way(16);
#define PORT_ROTATED \
- curfield->flags |= FIELD_FLAG_ROTATED
+ configurer.field_set_rotated();
-/* general flags */
+// general flags
#define PORT_NAME(_name) \
- curfield->name = input_port_string_from_token(_name);
+ configurer.field_set_name(_name);
#define PORT_PLAYER(_player) \
- curfield->player = (_player) - 1;
+ configurer.field_set_player(_player);
#define PORT_COCKTAIL \
- curfield->flags |= FIELD_FLAG_COCKTAIL; \
- curfield->player = 1;
+ configurer.field_set_cocktail();
#define PORT_TOGGLE \
- curfield->flags |= FIELD_FLAG_TOGGLE;
+ configurer.field_set_toggle();
#define PORT_IMPULSE(_duration) \
- curfield->impulse = _duration;
+ configurer.field_set_impulse(_duration);
#define PORT_REVERSE \
- curfield->flags |= ANALOG_FLAG_REVERSE;
+ configurer.field_set_analog_reverse();
#define PORT_RESET \
- curfield->flags |= ANALOG_FLAG_RESET;
+ configurer.field_set_analog_reset();
#define PORT_UNUSED \
- curfield->flags |= FIELD_FLAG_UNUSED;
+ configurer.field_set_unused();
-/* analog settings */
-/* if this macro is not used, the minimum defaluts to 0 and maximum defaults to the mask value */
+// analog settings
+// if this macro is not used, the minimum defaluts to 0 and maximum defaults to the mask value
#define PORT_MINMAX(_min, _max) \
- curfield->min = _min; \
- curfield->max = _max;
+ configurer.field_set_min_max(_min, _max);
#define PORT_SENSITIVITY(_sensitivity) \
- curfield->sensitivity = _sensitivity;
+ configurer.field_set_sensitivity(_sensitivity);
#define PORT_KEYDELTA(_delta) \
- curfield->delta = curfield->centerdelta = _delta;
+ configurer.field_set_delta(_delta); \
-/* note that PORT_CENTERDELTA must appear after PORT_KEYDELTA */
+// note that PORT_CENTERDELTA must appear after PORT_KEYDELTA
#define PORT_CENTERDELTA(_delta) \
- curfield->centerdelta = _delta;
+ configurer.field_set_centerdelta(_delta);
#define PORT_CROSSHAIR(axis, scale, offset, altaxis) \
- curfield->crossaxis = CROSSHAIR_AXIS_##axis; \
- curfield->crossaltaxis = altaxis; \
- curfield->crossscale = scale; \
- curfield->crossoffset = offset;
+ configurer.field_set_crosshair(CROSSHAIR_AXIS_##axis, altaxis, scale, offset);
#define PORT_CROSSHAIR_MAPPER(_callback) \
- curfield->crossmapper = input_field_crossmap_delegate(_callback, #_callback, (device_t *)NULL); \
- curfield->crossmapper_device = DEVICE_SELF;
+ configurer.field_set_crossmapper(ioport_field_crossmap_delegate(_callback, #_callback, DEVICE_SELF, (device_t *)NULL));
#define PORT_CROSSHAIR_MAPPER_MEMBER(_device, _class, _member) \
- curfield->crossmapper = input_field_crossmap_delegate(&_class::_member, #_class "::" #_member, (_class *)NULL); \
- curfield->crossmapper_device = _device;
+ configurer.field_set_crossmapper(ioport_field_crossmap_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)NULL));
-/* how many optical counts for 1 full turn of the control */
+// how many optical counts for 1 full turn of the control
#define PORT_FULL_TURN_COUNT(_count) \
- curfield->full_turn_count = _count;
+ configurer.field_set_full_turn_count(_count);
-/* positional controls can be binary or 1 of X */
-/* 1 of X not completed yet */
-/* if it is specified as PORT_REMAP_TABLE then it is binary, but remapped */
-/* otherwise it is binary */
+// positional controls can be binary or 1 of X
+// 1 of X not completed yet
+// if it is specified as PORT_REMAP_TABLE then it is binary, but remapped
+// otherwise it is binary
#define PORT_POSITIONS(_positions) \
- curfield->max = _positions;
+ configurer.field_set_min_max(0, _positions);
-/* positional control wraps at min/max */
+// positional control wraps at min/max
#define PORT_WRAPS \
- curfield->flags |= ANALOG_FLAG_WRAPS;
+ configurer.field_set_analog_wraps();
-/* positional control uses this remap table */
+// positional control uses this remap table
#define PORT_REMAP_TABLE(_table) \
- curfield->remap_table = _table;
+ configurer.field_set_remap_table(_table);
-/* positional control bits are active low */
+// positional control bits are active low
#define PORT_INVERT \
- curfield->flags |= ANALOG_FLAG_INVERT;
+ configurer.field_set_analog_invert();
-/* read callbacks */
+// read callbacks
#define PORT_CUSTOM(_callback, _param) \
- curfield->read = input_field_read_delegate(_callback, #_callback, (device_t *)NULL); \
- curfield->read_param = (void *)(_param); \
- curfield->read_device = DEVICE_SELF;
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(_callback, #_callback, DEVICE_SELF, (device_t *)NULL), (void *)(_param));
#define PORT_CUSTOM_MEMBER(_device, _class, _member, _param) \
- curfield->read = input_field_read_delegate(&_class::_member, #_class "::" #_member, (_class *)NULL); \
- curfield->read_param = (void *)(_param); \
- curfield->read_device = (_device);
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)NULL), (void *)(_param));
-/* write callbacks */
+// write callbacks
#define PORT_CHANGED(_callback, _param) \
- curfield->write = input_field_write_delegate(_callback, #_callback, (device_t *)NULL); \
- curfield->write_param = (void *)(_param); \
- curfield->write_device = DEVICE_SELF;
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(_callback, #_callback, DEVICE_SELF, (device_t *)NULL), (void *)(_param));
#define PORT_CHANGED_MEMBER(_device, _class, _member, _param) \
- curfield->write = input_field_write_delegate(&_class::_member, #_class "::" #_member, (_class *)NULL); \
- curfield->write_param = (void *)(_param); \
- curfield->write_device = (_device);
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)NULL), (void *)(_param));
-/* input device handler */
+// input device handler
#define PORT_READ_LINE_DEVICE(_device, _read_line_device) \
- curfield->read = input_field_read_delegate(&ioport_read_line_wrapper<_read_line_device>, #_read_line_device, (device_t *)NULL); \
- curfield->read_param = NULL; \
- curfield->read_device = _device;
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(&ioport_read_line_wrapper<_read_line_device>, #_read_line_device, _device, (device_t *)NULL));
#define PORT_READ_LINE_DEVICE_MEMBER(_device, _class, _member) \
- curfield->read = input_field_read_delegate(&ioport_read_line_wrapper<_class, &_class::_member>, #_class "::" #_member, (_class *)NULL); \
- curfield->read_param = NULL; \
- curfield->read_device = _device;
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(&ioport_read_line_wrapper<_class, &_class::_member>, #_class "::" #_member, _device, (_class *)NULL));
-/* output device handler */
+// output device handler
#define PORT_WRITE_LINE_DEVICE(_device, _write_line_device) \
- curfield->write = input_field_write_delegate(&ioport_write_line_wrapper<_write_line_device>, #_write_line_device, (device_t *)NULL); \
- curfield->write_param = NULL; \
- curfield->write_device = _device;
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(&ioport_write_line_wrapper<_write_line_device>, #_write_line_device, _device, (device_t *)NULL));
#define PORT_WRITE_LINE_DEVICE_MEMBER(_device, _class, _member) \
- curfield->write = input_field_write_delegate(&ioport_write_line_wrapper<_class, &_class::_member>, #_class "::" #_member, (_class *)NULL); \
- curfield->write_param = NULL; \
- curfield->write_device = _device;
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(&ioport_write_line_wrapper<_class, &_class::_member>, #_class "::" #_member, _device, (_class *)NULL));
-/* dip switch definition */
+// dip switch definition
#define PORT_DIPNAME(_mask, _default, _name) \
- curfield = ioconfig_alloc_field(*curport, IPT_DIPSWITCH, (_default), (_mask), (_name)); \
- cursetting = NULL;
+ configurer.field_alloc(IPT_DIPSWITCH, (_default), (_mask), (_name)); \
#define PORT_DIPSETTING(_default, _name) \
- cursetting = ioconfig_alloc_setting(*curfield, (_default) & curfield->mask, (_name));
+ configurer.setting_alloc((_default), (_name)); \
-/* physical location, of the form: name:[!]sw,[name:][!]sw,... */
-/* note that these are specified LSB-first */
+// physical location, of the form: name:[!]sw,[name:][!]sw,...
+// note that these are specified LSB-first
#define PORT_DIPLOCATION(_location) \
- diplocation_list_alloc(*curfield, _location, errorbuf);
+ configurer.field_set_diplocation(_location); \
-/* conditionals for dip switch settings */
+// conditionals for dip switch settings
#define PORT_CONDITION(_tag, _mask, _condition, _value) \
-{ \
- input_condition &condition = (cursetting != NULL) ? cursetting->condition : curfield->condition; \
- condition.tag = (_tag); \
- condition.mask = (_mask); \
- condition.condition = (_condition); \
- condition.value = (_value); \
-}
+ configurer.set_condition(ioport_condition::_condition, _tag, _mask, _value); \
-/* analog adjuster definition */
+// analog adjuster definition
#define PORT_ADJUSTER(_default, _name) \
- curfield = ioconfig_alloc_field(*curport, IPT_ADJUSTER, (_default), 0xff, (_name)); \
- cursetting = NULL; \
+ configurer.field_alloc(IPT_ADJUSTER, (_default), 0xff, (_name)); \
-/* config definition */
+// config definition
#define PORT_CONFNAME(_mask, _default, _name) \
- curfield = ioconfig_alloc_field(*curport, IPT_CONFIG, (_default), (_mask), (_name)); \
- cursetting = NULL; \
+ configurer.field_alloc(IPT_CONFIG, (_default), (_mask), (_name)); \
#define PORT_CONFSETTING(_default, _name) \
- cursetting = ioconfig_alloc_setting(*curfield, (_default) & curfield->mask, (_name));
+ configurer.setting_alloc((_default), (_name));
-/* keyboard chars */
+// keyboard chars
#define PORT_CHAR(_ch) \
- ioconfig_field_add_char(*curfield, _ch, errorbuf);
+ configurer.field_add_char(_ch);
-/* name of table */
+// name of table
#define DEVICE_INPUT_DEFAULTS_NAME(_name) device_iptdef_##_name
#define device_iptdef_0 NULL
#define device_iptdef___null NULL
-/* start of table */
+// start of table
#define DEVICE_INPUT_DEFAULTS_START(_name) \
const input_device_default DEVICE_INPUT_DEFAULTS_NAME(_name)[] = {
-/* end of table */
+// end of table
#define DEVICE_INPUT_DEFAULTS(_tag,_mask,_defval) \
{ _tag ,_mask, _defval }, \
-/* end of table */
+// end of table
#define DEVICE_INPUT_DEFAULTS_END \
{NULL,0,0} };
-/***************************************************************************
- HELPER MACROS
-***************************************************************************/
+
+
+//**************************************************************************
+// HELPER MACROS
+//**************************************************************************
#define PORT_DIPUNUSED_DIPLOC(_mask, _default, _diploc) \
PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, Unused, _diploc)
@@ -1313,181 +1657,51 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, a
#define PORT_SERVICE_NO_TOGGLE(_mask, _default) \
PORT_BIT( _mask, _mask & _default, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode ))
+#define PORT_VBLANK(_screen) \
+ PORT_READ_LINE_DEVICE_MEMBER(_screen, screen_device, vblank_port_read)
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-
-/* ----- port configurations ----- */
-
-/* initialize an input port list structure and allocate ports according to the given tokens */
-void input_port_list_init(device_t &device, ioport_list &portlist, astring &errorbuf);
-
-/* return the field that matches the given tag and mask */
-const input_field_config *input_field_by_tag_and_mask(running_machine &machine, const char *tag, input_port_value mask);
-
-
-
-/* ----- accessors for input types ----- */
-
-/* return TRUE if the given type represents an analog control */
-int input_type_is_analog(int type);
-
-/* return the name for the given type/player */
-const char *input_type_name(running_machine &machine, int type, int player);
-
-/* return the group for the given type/player */
-int input_type_group(running_machine &machine, int type, int player);
-
-/* return the global input mapping sequence for the given type/player */
-const input_seq &input_type_seq(running_machine &machine, int type, int player, input_seq_type seqtype);
-/* change the global input sequence for the given type/player */
-void input_type_set_seq(running_machine &machine, int type, int player, input_seq_type seqtype, const input_seq *newseq);
+//**************************************************************************
+// INLINE TEMPLATES
+//**************************************************************************
-/* return TRUE if the sequence for the given input type/player is pressed */
-int input_type_pressed(running_machine &machine, int type, int player);
-
-/* return the list of default mappings */
-const simple_list<input_type_entry> &input_type_list(running_machine &machine);
-
-
-
-/* ----- accessors for input fields ----- */
-
-/* return the expanded string name of the field */
-const char *input_field_name(const input_field_config *field);
-
-/* return the input sequence for the given input field */
-const input_seq &input_field_seq(const input_field_config *field, input_seq_type seqtype);
-
-/* return the current settings for the given input field */
-void input_field_get_user_settings(const input_field_config *field, input_field_user_settings *settings);
-
-/* modify the current settings for the given input field */
-void input_field_set_user_settings(const input_field_config *field, const input_field_user_settings *settings);
-
-/* return the expanded setting name for a field */
-const char *input_field_setting_name(const input_field_config *field);
-
-/* return TRUE if the given field has a "previous" setting */
-int input_field_has_previous_setting(const input_field_config *field);
-
-/* select the previous item for a DIP switch or configuration field */
-void input_field_select_previous_setting(const input_field_config *field);
-
-/* return TRUE if the given field has a "next" setting */
-int input_field_has_next_setting(const input_field_config *field);
-
-/* select the next item for a DIP switch or configuration field */
-void input_field_select_next_setting(const input_field_config *field);
-
-
-/* ----- port checking ----- */
-
-/* return whether an input port exists */
-bool input_port_exists(running_machine &machine, const char *tag);
-
-/* return a bitmask of which bits of an input port are active (i.e. not unused or unknown) */
-input_port_value input_port_active(running_machine &machine, const char *tag);
-
-/* return a bitmask of which bits of an input port are active (i.e. not unused or unknown), or a default value if the port does not exist */
-input_port_value input_port_active_safe(running_machine &machine, const char *tag, input_port_value defvalue);
-
-
-/* ----- port reading ----- */
-
-/* return the value of an input port */
-input_port_value input_port_read_direct(const input_port_config *port);
-
-/* return the value of an input port specified by tag */
-input_port_value input_port_read(running_machine &machine, const char *tag);
-
-/* return the value of a device input port specified by tag */
-input_port_value input_port_read(device_t &device, const char *tag);
-
-/* return the value of an input port specified by tag, or a default value if the port does not exist */
-input_port_value input_port_read_safe(running_machine &machine, const char *tag, input_port_value defvalue);
-
-/* return the extracted crosshair values for the given player */
-int input_port_get_crosshair_position(running_machine &machine, int player, float *x, float *y);
-
-/* force an update to the input port values based on current conditions */
-void input_port_update_defaults(running_machine &machine);
-
-
-
-/* ----- port writing ----- */
-
-/* write a value to a port */
-void input_port_write_direct(const input_port_config *port, input_port_value value, input_port_value mask);
-
-/* write a value to a port specified by tag */
-void input_port_write(running_machine &machine, const char *tag, input_port_value value, input_port_value mask);
-
-/* write a value to a port, ignore if the port does not exist */
-void input_port_write_safe(running_machine &machine, const char *tag, input_port_value value, input_port_value mask);
-
-
-
-/* ----- misc helper functions ----- */
-
-/* return the TRUE if the given condition attached is true */
-int input_condition_true(running_machine &machine, const input_condition *condition,device_t &owner);
-
-/* convert an input_port_token to a default string */
-const char *input_port_string_from_token(const char *token);
-
-/* return TRUE if machine use full keyboard emulation */
-int input_machine_has_keyboard(running_machine &machine);
-
-/* these are called by the core; they should not be called from FEs */
-void inputx_init(running_machine &machine);
-
-/* called by drivers to setup natural keyboard support */
-void inputx_setup_natural_keyboard(running_machine &machine,
- int (*queue_chars)(running_machine &machine, const unicode_char *text, size_t text_len),
- int (*accept_char)(running_machine &machine, unicode_char ch),
- int (*charqueue_empty)(running_machine &machine));
-
-/* validity checks */
-int validate_natural_keyboard_statics(void);
-
-/* these can be called from FEs */
-int inputx_can_post(running_machine &machine);
-
-/* various posting functions; can be called from FEs */
-void inputx_postc(running_machine &machine, unicode_char ch);
-void inputx_post_utf8(running_machine &machine, const char *text);
-void inputx_post_utf8_rate(running_machine &machine, const char *text, attotime rate);
-int inputx_is_posting(running_machine &machine);
+template<int (*_FunctionPointer)(device_t *)>
+ioport_value ioport_read_line_wrapper(device_t &device, ioport_field &field, void *param)
+{
+ return (*_FunctionPointer)(&device);
+}
-/* miscellaneous functions */
-int input_classify_port(const input_field_config *field);
-int input_has_input_class(running_machine &machine, int inputclass);
-int input_player_number(const input_field_config *field);
-int input_count_players(running_machine &machine);
+template<class _FunctionClass, int (_FunctionClass::*_FunctionPointer)()>
+ioport_value ioport_read_line_wrapper(_FunctionClass &device, ioport_field &field, void *param)
+{
+ return (device.*_FunctionPointer)();
+}
+template<void (*_FunctionPointer)(device_t *, int)>
+void ioport_write_line_wrapper(device_t &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
+{
+ return (*_FunctionPointer)(&device, newval);
+}
-inline running_machine &input_field_config::machine() const
+template<class _FunctionClass, void (_FunctionClass::*_FunctionPointer)(int)>
+void ioport_write_line_wrapper(_FunctionClass &device, ioport_field &field, void *param, ioport_value oldval, ioport_value newval)
{
- return m_port.machine();
+ return (device.*_FunctionPointer)(newval);
}
-// temporary construction helpers
-void field_config_insert(input_field_config &newfield, input_port_value &disallowedbits, astring &errorbuf);
-void diplocation_list_alloc(input_field_config &field, const char *location, astring &errorbuf);
+//**************************************************************************
+// INLINE FUNCITONS
+//**************************************************************************
+
+inline ioport_manager &ioport_field::manager() const { return m_port.manager(); }
+inline device_t &ioport_field::device() const { return m_port.device(); }
+inline running_machine &ioport_field::machine() const { return m_port.machine(); }
+
+inline device_t &ioport_setting::device() const { return m_field.device(); }
+inline running_machine &ioport_setting::machine() const { return m_field.machine(); }
-input_port_config *ioconfig_alloc_port(ioport_list &portlist, device_t &device, const char *tag);
-input_port_config *ioconfig_modify_port(ioport_list &portlist, device_t &device, const char *tag);
-input_field_config *ioconfig_alloc_field(input_port_config &port, int type, input_port_value defval, input_port_value mask, const char *name = NULL);
-input_field_config *ioconfig_alloc_onoff(input_port_config &port, const char *name, input_port_value defval, input_port_value mask, const char *diplocation, astring &errorbuf);
-input_setting_config *ioconfig_alloc_setting(input_field_config &field, input_port_value value, const char *name);
-void ioconfig_field_add_char(input_field_config &field, unicode_char ch, astring &errorbuf);
-void ioconfig_add_code(input_field_config &field, int which, input_code code);
-#endif /* __INPTPORT_H__ */
+#endif // __INPTPORT_H__ */