From 10b6e7e106ad706c29b8e25cbac0b990f0cdb501 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Mon, 7 Sep 2009 00:53:53 +0000 Subject: [PATCH] Added PORT_CROSSHAIR_MAPPER() allowing you to specify an alternate, non-linear mapping function from the raw crosshair value to its position onscreen. [Aaron Giles] --- src/emu/crsshair.c | 9 ++++++--- src/emu/inptport.c | 15 +++++++++++++++ src/emu/inptport.h | 13 +++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/emu/crsshair.c b/src/emu/crsshair.c index 937a07d6e67..2b1fb1674a4 100644 --- a/src/emu/crsshair.c +++ b/src/emu/crsshair.c @@ -332,9 +332,13 @@ void crosshair_set_user_settings(running_machine *machine, UINT8 player, crossha static void animate(const device_config *device, void *param, int vblank_state) { int player; + + /* only animate once per frame, when vblank_state is 1 */ + if (!vblank_state) + return; /* increment animation counter */ - global.animation_counter += 0x04; + global.animation_counter += 0x08; /* compute a fade factor from the current animation value */ if (global.animation_counter < 0x80) @@ -362,11 +366,10 @@ static void animate(const device_config *device, void *param, int vblank_state) else { /* see if the player has been motionless for time specified */ - /* note that the animate() routine is called twice per frame */ /* slightly confusing formula, but the effect is: */ /* auto_time = 0 makes the crosshair barely visible while moved */ /* every increment in auto_time is about .2s at 60Hz */ - if (global.time[player] > global.auto_time * 24 + 4) + if (global.time[player] > global.auto_time * 12 + 2) /* time exceeded so turn crosshair invisible */ global.visible[player] = FALSE; diff --git a/src/emu/inptport.c b/src/emu/inptport.c index 36902c7938b..98b6a68eef1 100644 --- a/src/emu/inptport.c +++ b/src/emu/inptport.c @@ -1320,6 +1320,10 @@ int input_port_get_crosshair_position(running_machine *machine, int player, floa else value *= field->crossscale; value += field->crossoffset; + + /* apply custom mapping if necessary */ + if (field->crossmapper != NULL) + value = (*field->crossmapper)(field, value); /* handle X axis */ if (field->crossaxis == CROSSHAIR_AXIS_X) @@ -2713,6 +2717,17 @@ static input_port_config *port_config_detokenize(input_port_config *listhead, co curfield->crossoffset *= 1.0f / 65536.0f; break; + /* crosshair mapper callback */ + case INPUT_TOKEN_CROSSHAIR_MAPPER: + if (curfield == NULL) + { + error_buf_append(errorbuf, errorbuflen, "INPUT_TOKEN_CROSSHAIR_MAPPER encountered with no active field\n"); + TOKEN_SKIP_PTR(ipt); + break; + } + curfield->crossmapper = TOKEN_GET_PTR(ipt, crossmapptr); + break; + /* analog decrement sequence */ case INPUT_TOKEN_CODE_DEC: TOKEN_UNGET_UINT32(ipt); diff --git a/src/emu/inptport.h b/src/emu/inptport.h index d6658697bc4..ede24036c0e 100644 --- a/src/emu/inptport.h +++ b/src/emu/inptport.h @@ -399,6 +399,7 @@ enum INPUT_TOKEN_KEYDELTA, INPUT_TOKEN_CENTERDELTA, INPUT_TOKEN_CROSSHAIR, + INPUT_TOKEN_CROSSHAIR_MAPPER, INPUT_TOKEN_FULL_TURN_COUNT, INPUT_TOKEN_POSITIONS, INPUT_TOKEN_WRAPS, @@ -569,6 +570,9 @@ typedef UINT32 (*input_field_custom_func)(const input_field_config *field, void /* input port changed callback function */ typedef void (*input_field_changed_func)(const input_field_config *field, void *param, UINT32 oldval, UINT32 newval); +/* crosshair mapping function */ +typedef float (*input_field_crossmap_func)(const input_field_config *field, float linear_value); + /* this type is used to encode input port definitions */ typedef union _input_port_token input_port_token; @@ -578,6 +582,7 @@ union _input_port_token const input_port_token * tokenptr; input_field_custom_func customptr; input_field_changed_func changedptr; + input_field_crossmap_func crossmapptr; }; @@ -647,6 +652,7 @@ struct _input_field_config float crossscale; /* crosshair scale */ float crossoffset; /* crosshair offset */ float crossaltaxis; /* crosshair alternate axis value */ + input_field_crossmap_func crossmapper; /* crosshair mapping function */ 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 */ @@ -726,6 +732,9 @@ struct _inp_header /* 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 port changed callback functions (PORT_CROSSHAIR_MAPPER) */ +#define CROSSHAIR_MAPPER(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) @@ -848,6 +857,10 @@ struct _inp_header 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), +#define PORT_CROSSHAIR_MAPPER(_callback) \ + TOKEN_UINT32_PACK1(INPUT_TOKEN_CROSSHAIR_MAPPER, 8), \ + TOKEN_PTR(crossmapptr, _callback), + /* 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),