[wrap]
/***************************************************************************
inptport.h
Handle input ports and mappings.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#pragma once
#ifndef __INPTPORT_H__
#define __INPTPORT_H__
#include <time.h>
#include "memory.h"
#include "inputseq.h"
#include "tokenize.h"
#include "unicode.h"
/***************************************************************************
CONSTANTS
***************************************************************************/
#define MAX_PLAYERS 8
#define IP_ACTIVE_HIGH 0x00000000
#define 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 */
/* INP file information */
#define INP_HEADER_SIZE 64
#define INP_HEADER_MAJVERSION 2
#define INP_HEADER_MINVERSION 0
/* sequence types for input_port_seq() call */
enum _input_seq_type
{
SEQ_TYPE_STANDARD = 0,
SEQ_TYPE_INCREMENT,
SEQ_TYPE_DECREMENT,
SEQ_TYPE_TOTAL
};
typedef enum _input_seq_type 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_AXIS_NONE = 0,
CROSSHAIR_AXIS_X,
CROSSHAIR_AXIS_Y
};
/* groups for input ports */
enum
{
IPG_UI = 0,
IPG_PLAYER1,
IPG_PLAYER2,
IPG_PLAYER3,
IPG_PLAYER4,
IPG_PLAYER5,
IPG_PLAYER6,
IPG_PLAYER7,
IPG_PLAYER8,
IPG_OTHER,
IPG_TOTAL_GROUPS,
IPG_INVALID
};
/* various input port types */
enum
{
/* pseudo-port types */
IPT_INVALID = 0,
IPT_UNUSED,
IPT_END,
IPT_UNKNOWN,
IPT_PORT,
IPT_DIPSWITCH,
IPT_VBLANK,
IPT_CONFIG,
IPT_CATEGORY, /* MESS only */
/* start buttons */
IPT_START1,
IPT_START2,
IPT_START3,
IPT_START4,
IPT_START5,
IPT_START6,
IPT_START7,
IPT_START8,
/* coin slots */
IPT_COIN1,
IPT_COIN2,
IPT_COIN3,
IPT_COIN4,
IPT_COIN5,
IPT_COIN6,
IPT_COIN7,
IPT_COIN8,
IPT_BILL1,
/* service coin */
IPT_SERVICE1,
IPT_SERVICE2,
IPT_SERVICE3,
IPT_SERVICE4,
/* 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_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_BUTTON1,
IPT_BUTTON2,
IPT_BUTTON3,
IPT_BUTTON4,
IPT_BUTTON5,
IPT_BUTTON6,
IPT_BUTTON7,
IPT_BUTTON8,
IPT_BUTTON9,
IPT_BUTTON10,
IPT_BUTTON11,
IPT_BUTTON12,
IPT_BUTTON13,
IPT_BUTTON14,
IPT_BUTTON15,
IPT_BUTTON16,
/* mahjong inputs */
IPT_MAHJONG_A,
IPT_MAHJONG_B,
IPT_MAHJONG_C,
IPT_MAHJONG_D,
IPT_MAHJONG_E,
IPT_MAHJONG_F,
IPT_MAHJONG_G,
IPT_MAHJONG_H,
IPT_MAHJONG_I,
IPT_MAHJONG_J,
IPT_MAHJONG_K,
IPT_MAHJONG_L,
IPT_MAHJONG_M,
IPT_MAHJONG_N,
IPT_MAHJONG_O,
IPT_MAHJONG_P,
IPT_MAHJONG_Q,
IPT_MAHJONG_KAN,
IPT_MAHJONG_PON,
IPT_MAHJONG_CHI,
IPT_MAHJONG_REACH,
IPT_MAHJONG_RON,
IPT_MAHJONG_BET,
IPT_MAHJONG_LAST_CHANCE,
IPT_MAHJONG_SCORE,
IPT_MAHJONG_DOUBLE_UP,
IPT_MAHJONG_FLIP_FLOP,
IPT_MAHJONG_BIG,
IPT_MAHJONG_SMALL,
/* analog inputs */
#define __ipt_analog_start IPT_PADDLE
#define __ipt_analog_absolute_start IPT_PADDLE
IPT_PADDLE, /* absolute */
IPT_PADDLE_V, /* absolute */
IPT_AD_STICK_X, /* absolute */
IPT_AD_STICK_Y, /* absolute */
IPT_AD_STICK_Z, /* absolute */
IPT_LIGHTGUN_X, /* absolute */
IPT_LIGHTGUN_Y, /* absolute */
IPT_PEDAL, /* absolute */
IPT_PEDAL2, /* absolute */
IPT_PEDAL3, /* absolute */
IPT_POSITIONAL, /* absolute */
IPT_POSITIONAL_V, /* absolute */
#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 */
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_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,
IPT_UI_TOGGLE_CROSSHAIR,
/* 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 */
IPT_OTHER,
/* special meaning handled by custom code */
IPT_SPECIAL,
__ipt_max
};
/* token types */
enum
{
INPUT_TOKEN_INVALID,
INPUT_TOKEN_END,
INPUT_TOKEN_INCLUDE,
INPUT_TOKEN_START,
INPUT_TOKEN_MODIFY,
INPUT_TOKEN_FIELD,
INPUT_TOKEN_SPECIAL_ONOFF,
INPUT_TOKEN_CODE,
INPUT_TOKEN_CODE_DEC,
INPUT_TOKEN_CODE_INC,
INPUT_TOKEN_2WAY,
INPUT_TOKEN_4WAY,
INPUT_TOKEN_8WAY,
INPUT_TOKEN_16WAY,
INPUT_TOKEN_ROTATED,
INPUT_TOKEN_PLAYER1,
INPUT_TOKEN_PLAYER2,
INPUT_TOKEN_PLAYER3,
INPUT_TOKEN_PLAYER4,
INPUT_TOKEN_PLAYER5,
INPUT_TOKEN_PLAYER6,
INPUT_TOKEN_PLAYER7,
INPUT_TOKEN_PLAYER8,
INPUT_TOKEN_COCKTAIL,
INPUT_TOKEN_TOGGLE,
INPUT_TOKEN_NAME,
INPUT_TOKEN_IMPULSE,
INPUT_TOKEN_REVERSE,
INPUT_TOKEN_RESET,
INPUT_TOKEN_MINMAX,
INPUT_TOKEN_SENSITIVITY,
INPUT_TOKEN_KEYDELTA,
INPUT_TOKEN_CENTERDELTA,
INPUT_TOKEN_CROSSHAIR,
INPUT_TOKEN_FULL_TURN_COUNT,
INPUT_TOKEN_POSITIONS,
INPUT_TOKEN_WRAPS,
INPUT_TOKEN_REMAP_TABLE,
INPUT_TOKEN_INVERT,
INPUT_TOKEN_UNUSED,
INPUT_TOKEN_CUSTOM,
INPUT_TOKEN_CHANGED,
INPUT_TOKEN_DIPNAME,
INPUT_TOKEN_DIPSETTING,
INPUT_TOKEN_DIPLOCATION,
INPUT_TOKEN_CONDITION,
INPUT_TOKEN_ADJUSTER,
INPUT_TOKEN_CONFNAME,
INPUT_TOKEN_CONFSETTING,
INPUT_TOKEN_CHAR,
INPUT_TOKEN_CATEGORY,
INPUT_TOKEN_CATEGORY_NAME,
INPUT_TOKEN_CATEGORY_SETTING
};
/* default strings used in port definitions */
enum
{
INPUT_STRING_Off = 1,
INPUT_STRING_On,
INPUT_STRING_No,
INPUT_STRING_Yes,
INPUT_STRING_Lives,
INPUT_STRING_Bonus_Life,
INPUT_STRING_Difficulty,
INPUT_STRING_Demo_Sounds,
INPUT_STRING_Coinage,
INPUT_STRING_Coin_A,
INPUT_STRING_Coin_B,
INPUT_STRING_9C_1C,
INPUT_STRING_8C_1C,
INPUT_STRING_7C_1C,
INPUT_STRING_6C_1C,
INPUT_STRING_5C_1C,
INPUT_STRING_4C_1C,
INPUT_STRING_3C_1C,
INPUT_STRING_8C_3C,
INPUT_STRING_4C_2C,
INPUT_STRING_2C_1C,
INPUT_STRING_5C_3C,
INPUT_STRING_3C_2C,
INPUT_STRING_4C_3C,
INPUT_STRING_4C_4C,
INPUT_STRING_3C_3C,
INPUT_STRING_2C_2C,
INPUT_STRING_1C_1C,
INPUT_STRING_4C_5C,
INPUT_STRING_3C_4C,
INPUT_STRING_2C_3C,
INPUT_STRING_4C_7C,
INPUT_STRING_2C_4C,
INPUT_STRING_1C_2C,
INPUT_STRING_2C_5C,
INPUT_STRING_2C_6C,
INPUT_STRING_1C_3C,
INPUT_STRING_2C_7C,
INPUT_STRING_2C_8C,
INPUT_STRING_1C_4C,
INPUT_STRING_1C_5C,
INPUT_STRING_1C_6C,
INPUT_STRING_1C_7C,
INPUT_STRING_1C_8C,
INPUT_STRING_1C_9C,
INPUT_STRING_Free_Play,
INPUT_STRING_Cabinet,
INPUT_STRING_Upright,
INPUT_STRING_Cocktail,
INPUT_STRING_Flip_Screen,
INPUT_STRING_Service_Mode,
INPUT_STRING_Pause,
INPUT_STRING_Test,
INPUT_STRING_Tilt,
INPUT_STRING_Version,
INPUT_STRING_Region,
INPUT_STRING_International,
INPUT_STRING_Japan,
INPUT_STRING_USA,
INPUT_STRING_Europe,
INPUT_STRING_Asia,
INPUT_STRING_World,
INPUT_STRING_Hispanic,
INPUT_STRING_Language,
INPUT_STRING_English,
INPUT_STRING_Japanese,
INPUT_STRING_German,
INPUT_STRING_French,
INPUT_STRING_Italian,
INPUT_STRING_Spanish,
INPUT_STRING_Very_Easy,
INPUT_STRING_Easiest,
INPUT_STRING_Easier,
INPUT_STRING_Easy,
INPUT_STRING_Normal,
INPUT_STRING_Medium,
INPUT_STRING_Hard,
INPUT_STRING_Harder,
INPUT_STRING_Hardest,
INPUT_STRING_Very_Hard,
INPUT_STRING_Very_Low,
INPUT_STRING_Low,
INPUT_STRING_High,
INPUT_STRING_Higher,
INPUT_STRING_Highest,
INPUT_STRING_Very_High,
INPUT_STRING_Players,
INPUT_STRING_Controls,
INPUT_STRING_Dual,
INPUT_STRING_Single,
INPUT_STRING_Game_Time,
INPUT_STRING_Continue_Price,
INPUT_STRING_Controller,
INPUT_STRING_Light_Gun,
INPUT_STRING_Joystick,
INPUT_STRING_Trackball,
INPUT_STRING_Continues,
INPUT_STRING_Allow_Continue,
INPUT_STRING_Level_Select,
INPUT_STRING_Infinite,
INPUT_STRING_Stereo,
INPUT_STRING_Mono,
INPUT_STRING_Unused,
INPUT_STRING_Unknown,
INPUT_STRING_Standard,
INPUT_STRING_Reverse,
INPUT_STRING_Alternate,
INPUT_STRING_None,
INPUT_STRING_COUNT
};
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
/* input ports support up to 32 bits each */
typedef UINT32 input_port_value;
/* opaque types pointing to live state */
typedef struct _input_port_state input_port_state;
typedef struct _input_field_state input_field_state;
/* forward declarations */
typedef struct _input_port_config input_port_config;
typedef struct _input_field_config input_field_config;
/* custom input port callback function */
typedef UINT32 (*input_field_custom_func)(const input_field_config *field, void *param);
/* input port changed callback function */
typedef void (*input_field_changed_func)(const input_field_config *field, void *param, UINT32 oldval, UINT32 newval);
/* this type is used to encode input port definitions */
typedef union _input_port_token input_port_token;
union _input_port_token
{
TOKEN_COMMON_FIELDS
const input_port_token * tokenptr;
input_field_custom_func customptr;
input_field_changed_func changedptr;
};
/* encapsulates a condition on a port field or setting */
typedef struct _input_condition input_condition;
struct _input_condition
{
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 */
};
/* a single setting for a configuration or DIP switch */
typedef struct _input_setting_config input_setting_config;
struct _input_setting_config
{
const input_setting_config *next; /* pointer to next setting in sequence */
const input_field_config * field; /* pointer back to the field that owns us */
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 */
UINT16 category; /* (MESS-specific) category */
};
/* a mapping from a bit to a physical DIP switch description */
typedef struct _input_field_diplocation input_field_diplocation;
struct _input_field_diplocation
{
input_field_diplocation * next; /* pointer to the next bit */
const char * swname; /* name of the physical DIP switch */
UINT8 swnum; /* physical switch number */
UINT8 invert; /* is this an active-high DIP? */
};
/* a single bitfield within an input port */
struct _input_field_config
{
/* generally-applicable data */
const input_field_config * next; /* pointer to next field in sequence */
const input_port_config * port; /* pointer back to the port that owns us */
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) */
UINT16 category; /* (MESS-specific) category */
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_custom_func custom; /* custom callback routine */
void * custom_param; /* parameter for custom callback routine */
input_field_changed_func changed; /* changed callback routine */
void * changed_param; /* parameter for changed 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 */
float crossscale; /* crosshair scale */
float crossoffset; /* crosshair offset */
float crossaltaxis; /* crosshair alternate axis value */
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 */
const input_setting_config *settinglist; /* list of input_setting_configs */
const input_field_diplocation *diploclist; /* list of locations for various bits */
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) */
};
/* 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 */
};
/* a single input port configuration */
struct _input_port_config
{
const input_port_config * next; /* pointer to next port */
const char * tag; /* pointer to this port's tag */
const input_field_config * fieldlist; /* list of input_field_configs */
/* these two fields are only valid if the port is live */
input_port_state * state; /* live state of port (NULL if not live) */
running_machine * machine; /* machine if port is live */
};
/* describes a fundamental input type, including default input sequences */
typedef struct _input_type_desc input_type_desc;
struct _input_type_desc
{
input_type_desc * next; /* next description in the list */
UINT32 type; /* IPT_* for this entry */
UINT8 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 seq[SEQ_TYPE_TOTAL];/* default input sequence */
};
/* heaeder at the front of INP files */
typedef struct _inp_header inp_header;
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 */
};
/***************************************************************************
MACROS
***************************************************************************/
/* macro for a custom callback functions (PORT_CUSTOM) */
#define CUSTOM_INPUT(name) UINT32 name(const input_field_config *field, void *param)
/* macro for port changed callback functions (PORT_CHANGED) */
#define INPUT_CHANGED(name) void name(const input_field_config *field, void *param, UINT32 oldval, UINT32 newval)
/* macro for wrapping a default string */
#define DEF_STR(str_num) ((const char *)INPUT_STRING_##str_num)
/* macros for referencing input ports in place of read handlers */
#define HANDLER_PORT(name, type) ((type)("\0\0\0\0" name))
#define DEVICE8_PORT(name) HANDLER_PORT(name, read8_device_func)
#define MACHINE8_PORT(name) HANDLER_PORT(name, read8_space_func)
#define IS_HANDLER_PORT(ptr) (((const char *)(ptr))[0] == 0 && ((const char *)(ptr))[1] == 0 && ((const char *)(ptr))[2] == 0 && ((const char *)(ptr))[3] == 0)
#define CALL_DEVICE8_READ(ptr,d,offs) (IS_HANDLER_PORT(ptr) ? input_port_read((d)->machine, ((const char *)(ptr)) + 4) : (*ptr)(d, offs))
#define CALL_MACHINE8_READ(ptr,m,offs) (IS_HANDLER_PORT(ptr) ? input_port_read((m), ((const char *)(ptr)) + 4) : (*ptr)(m, offs))
/***************************************************************************
MACROS FOR BUILDING INPUT PORTS
***************************************************************************/
/* start of table */
#define INPUT_PORTS_START(_name) \
const input_port_token ipt_##_name[] = {
/* end of table */
#define INPUT_PORTS_END \
TOKEN_UINT32_PACK1(INPUT_TOKEN_END, 8) };
/* aliasing */
#define INPUT_PORTS_EXTERN(_name) \
extern const input_port_token ipt_##_name[]
/* including */
#define PORT_INCLUDE(_name) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_INCLUDE, 8), \
TOKEN_PTR(tokenptr, &ipt_##_name[0]),
/* start of a new input port (with included tag) */
#define PORT_START(_tag) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_START, 8), \
TOKEN_STRING(_tag),
/* modify an existing port */
#define PORT_MODIFY(_tag) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_MODIFY, 8), \
TOKEN_STRING(_tag),
/* input bit definition */
#define PORT_BIT(_mask, _default, _type) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_FIELD, 8, _type, 24), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32),
#define PORT_SPECIAL_ONOFF(_mask, _default, _strindex) \
TOKEN_UINT32_PACK3(INPUT_TOKEN_SPECIAL_ONOFF, 8, FALSE, 1, INPUT_STRING_##_strindex, 23), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32),
#define PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, _strindex, _diploc) \
TOKEN_UINT32_PACK3(INPUT_TOKEN_SPECIAL_ONOFF, 8, TRUE, 1, INPUT_STRING_##_strindex, 23), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32), \
TOKEN_STRING(_diploc),
/* append a code */
#define PORT_CODE(_code) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_CODE, 8, _code, 32),
#define PORT_CODE_DEC(_code) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_CODE_DEC, 8, _code, 32),
#define PORT_CODE_INC(_code) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_CODE_INC, 8, _code, 32),
/* joystick flags */
#define PORT_2WAY \
TOKEN_UINT32_PACK1(INPUT_TOKEN_2WAY, 8),
#define PORT_4WAY \
TOKEN_UINT32_PACK1(INPUT_TOKEN_4WAY, 8),
#define PORT_8WAY \
TOKEN_UINT32_PACK1(INPUT_TOKEN_8WAY, 8),
#define PORT_16WAY \
TOKEN_UINT32_PACK1(INPUT_TOKEN_16WAY, 8),
#define PORT_ROTATED \
TOKEN_UINT32_PACK1(INPUT_TOKEN_ROTATED, 8),
/* general flags */
#define PORT_NAME(_name) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_NAME, 8), \
TOKEN_STRING(_name),
#define PORT_PLAYER(player_) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_PLAYER1 + (((player_) - 1) % MAX_PLAYERS), 8),
#define PORT_COCKTAIL \
TOKEN_UINT32_PACK1(INPUT_TOKEN_COCKTAIL, 8),
#define PORT_TOGGLE \
TOKEN_UINT32_PACK1(INPUT_TOKEN_TOGGLE, 8),
#define PORT_IMPULSE(_duration) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_IMPULSE, 8, _duration, 24),
#define PORT_REVERSE \
TOKEN_UINT32_PACK1(INPUT_TOKEN_REVERSE, 8),
#define PORT_RESET \
TOKEN_UINT32_PACK1(INPUT_TOKEN_RESET, 8),
#define PORT_UNUSED \
TOKEN_UINT32_PACK1(INPUT_TOKEN_UNUSED, 8),
/* 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) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_MINMAX, 8), \
TOKEN_UINT64_PACK2(_min, 32, _max, 32),
#define PORT_SENSITIVITY(_sensitivity) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_SENSITIVITY, 8, _sensitivity, 24),
#define PORT_KEYDELTA(_delta) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_KEYDELTA, 8, _delta, 24),
/* note that PORT_CENTERDELTA must appear after PORT_KEYDELTA */
#define PORT_CENTERDELTA(_delta) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_CENTERDELTA, 8, _delta, 24),
#define PORT_CROSSHAIR(axis, scale, offset, altaxis) \
TOKEN_UINT32_PACK3(INPUT_TOKEN_CROSSHAIR, 8, CROSSHAIR_AXIS_##axis, 4, (INT32)((altaxis) * 65536.0f), 20), \
TOKEN_UINT64_PACK2((INT32)((scale) * 65536.0f), 32, (INT32)((offset) * 65536.0f), 32),
/* how many optical counts for 1 full turn of the control */
#define PORT_FULL_TURN_COUNT(_count) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_FULL_TURN_COUNT, 8, _count, 24),
/* 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) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_POSITIONS, 8, _positions, 24),
/* positional control wraps at min/max */
#define PORT_WRAPS \
TOKEN_UINT32_PACK1(INPUT_TOKEN_WRAPS, 8),
/* positional control uses this remap table */
#define PORT_REMAP_TABLE(_table) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_REMAP_TABLE, 8), \
TOKEN_PTR(ui32ptr, _table),
/* positional control bits are active low */
#define PORT_INVERT \
TOKEN_UINT32_PACK1(INPUT_TOKEN_INVERT, 8),
/* custom callbacks */
#define PORT_CUSTOM(_callback, _param) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_CUSTOM, 8), \
TOKEN_PTR(customptr, _callback), \
TOKEN_PTR(voidptr, _param),
/* changed callbacks */
#define PORT_CHANGED(_callback, _param) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_CHANGED, 8), \
TOKEN_PTR(changedptr, _callback), \
TOKEN_PTR(voidptr, _param),
/* dip switch definition */
#define PORT_DIPNAME(_mask, _default, _name) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_DIPNAME, 8), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32), \
TOKEN_STRING(_name),
#define PORT_DIPSETTING(_default, _name) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_DIPSETTING, 8, _default, 32), \
TOKEN_STRING(_name),
/* physical location, of the form: name:[!]sw,[name:][!]sw,... */
/* note that these are specified LSB-first */
#define PORT_DIPLOCATION(_location) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_DIPLOCATION, 8), \
TOKEN_STRING(_location),
/* conditionals for dip switch settings */
#define PORT_CONDITION(_tag, _mask, _condition, _value) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_CONDITION, 8, _condition, 24), \
TOKEN_UINT64_PACK2(_mask, 32, _value, 32), \
TOKEN_STRING(_tag),
/* analog adjuster definition */
#define PORT_ADJUSTER(_default, _name) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_ADJUSTER, 8, _default, 32), \
TOKEN_STRING(_name),
/* config definition */
#define PORT_CONFNAME(_mask, _default, _name) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_CONFNAME, 8), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32), \
TOKEN_STRING(_name),
#define PORT_CONFSETTING(_default, _name) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_CONFSETTING, 8, _default, 32), \
TOKEN_STRING(_name),
/* keyboard chars */
#define PORT_CHAR(_ch) \
TOKEN_UINT64_PACK2(INPUT_TOKEN_CHAR, 8, _ch, 32), \
/* categories */
#define PORT_CATEGORY(_category) \
TOKEN_UINT32_PACK2(INPUT_TOKEN_CATEGORY, 8, _category, 24),
#define PORT_CATEGORY_CLASS(_mask, _default, _name) \
TOKEN_UINT32_PACK1(INPUT_TOKEN_CATEGORY_NAME, 8), \
TOKEN_UINT64_PACK2(_mask, 32, _default, 32), \
TOKEN_STRING(_name),
#define PORT_CATEGORY_ITEM(_default, _name, _category) \
TOKEN_UINT64_PACK3(INPUT_TOKEN_CATEGORY_SETTING, 8, _default, 32, _category, 16), \
TOKEN_STRING(_name),
/***************************************************************************
HELPER MACROS
***************************************************************************/
#define PORT_DIPUNUSED_DIPLOC(_mask, _default, _diploc) \
PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, Unused, _diploc)
#define PORT_DIPUNUSED(_mask, _default) \
PORT_SPECIAL_ONOFF(_mask, _default, Unused)
#define PORT_DIPUNKNOWN_DIPLOC(_mask, _default, _diploc) \
PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, Unknown, _diploc)
#define PORT_DIPUNKNOWN(_mask, _default) \
PORT_SPECIAL_ONOFF(_mask, _default, Unknown)
#define PORT_SERVICE_DIPLOC(_mask, _default, _diploc) \
PORT_SPECIAL_ONOFF_DIPLOC(_mask, _default, Service_Mode, _diploc)
#define PORT_SERVICE(_mask, _default) \
PORT_SPECIAL_ONOFF(_mask, _default, Service_Mode)
#define PORT_SERVICE_NO_TOGGLE(_mask, _default) \
PORT_BIT( _mask, _mask & _default, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode ))
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
/* ----- core system management ----- */
/* initialize the input ports, processing the given token list */
time_t input_port_init(running_machine *machine, const input_port_token *tokens);
/* ----- port configurations ----- */
/* allocate a list of input ports from the given token list */
const input_port_config *input_port_config_alloc(const input_port_token *tokens, char *errorbuf, int errorbuflen);
/* free memory allocated from input_port_alloc */
void input_port_config_free(const input_port_config *portlist);
/* return the config that matches the given tag */
const input_port_config *input_port_by_tag(const input_port_config *portlist, const char *tag);
/* return the config that matches the given tag */
const input_port_config *input_port_by_index(const input_port_config *portlist, int index);
/* return the field that matches the given tag and mask */
const input_field_config *input_field_by_tag_and_mask(const input_port_config *portlist, 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);
/* 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 input_type_desc *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 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 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);
/* ----- misc helper functions ----- */
/* return the TRUE if the given condition attached is true */
int input_condition_true(running_machine *machine, const input_condition *condition);
/* convert an input_port_token to a default string */
const char *input_port_string_from_token(const input_port_token token);
/* return a memory handler corresponding to a given input port tag */
read8_space_func input_port_read_handler8(const input_port_config *portlist, const char *tag);
read16_space_func input_port_read_handler16(const input_port_config *portlist, const char *tag);
read32_space_func input_port_read_handler32(const input_port_config *portlist, const char *tag);
read64_space_func input_port_read_handler64(const input_port_config *portlist, const char *tag);
#endif /* __INPTPORT_H__ */