Skip to content

Commit

Permalink
Added X-Way Joystick option to analog controls menu only for IPT_DIAL…
Browse files Browse the repository at this point in the history
… and IPT_DIAL_V devices. When option is on, it prevents one rotary step of the joystick from sometimes rotating the character 2 steps. (libretro#514)
  • Loading branch information
zorro2055 authored Jun 6, 2024
1 parent 9ed9b3b commit 7630b90
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 100 deletions.
107 changes: 68 additions & 39 deletions src/inptport.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
TODO: remove the 1 analog device per port limitation
support for inputports producing interrupts
support for extra "real" hardware (PC throttle's, spinners etc)
Controller-Specific Input Port Mappings
---------------------------------------
The main purpose of the controller-specific configuration is to remap
inputs. This is handled via two mechanisms: key re-mapping and
The main purpose of the controller-specific configuration is to remap
inputs. This is handled via two mechanisms: key re-mapping and
sequence re-mapping.
Key re-mapping occurs at the most basic level. The specified keycode is
replaced where ever it occurs (in all sequences) with the specified
replacement. Only single keycodes can be used as a replacement (that is, a
replaced where ever it occurs (in all sequences) with the specified
replacement. Only single keycodes can be used as a replacement (that is, a
single key cannot be replaced with a key sequence).
Sequence mapping occurs at a higher level. In this case, the entire
Expand All @@ -27,15 +27,15 @@ sequence.
Keycodes are specified as a single keyword. Key sequences are specified
as a series of keycodes separated by spaces (the full sequence must be
enclosed in quotes if spaces exist). Two special keywords are available
for defining key sequences, CODE_OR and CODE_NOT (which can abbreviated |
for defining key sequences, CODE_OR and CODE_NOT (which can abbreviated |
and ! respectively).
When two keycodes are specified together (separated by only whitespace),
the default action is a logical AND, such that both keys must be pressed
at the same time for the action to occur. Often it desired that either
key can be pressed for the action to occur (for example LEFT CTRL and
key can be pressed for the action to occur (for example LEFT CTRL and
Joystick Button 0), in which case the two keycodes need to be separated
by a CODE_OR (|) keyword. Finally, certain combinations may be
by a CODE_OR (|) keyword. Finally, certain combinations may be
undesirable and warrant no action by MAME. For these, the keywords should
be specified by a CODE_NOT (!) (for example, ALT-TAB on a windows machine).
Expand All @@ -57,9 +57,9 @@ Specifies the directory that contains the controller customization .ini files.
-ctrlr "name"
Specifies a controller name for customization. The .ini files for the
Specifies a controller name for customization. The .ini files for the
controller are stored in either a directory or a .zip file with the same
name as the specified controller.
name as the specified controller.
The first file in the directory/zip to be scanned is the file default.ini.
From there, game-specific files are scanned starting with the top-most
Expand All @@ -85,20 +85,20 @@ enabled on those games that require it. If all games for this controller
require joystick and/or mouse support, those keywords can be placed in
the main default.ini file.
All of the options that can be specified on the command-line or in the
main mame.ini file can be specified in the controller-specific ini files,
though because of when these files are parsed, the specified options may
All of the options that can be specified on the command-line or in the
main mame.ini file can be specified in the controller-specific ini files,
though because of when these files are parsed, the specified options may
have no effect. The only two general options guaranteed to be supported
are mouse and joystick. Note that command-line specification of these
options takes precedence. Since most front-ends, including MAME32,
options takes precedence. Since most front-ends, including MAME32,
specify these options through the command-line, the mouse and/or joystick
options specified in the .ini files will be ignored.
Another custom keyword is:
ctrlrname "name"
This keyword defines a detailed name for the selected controller. Names
This keyword defines a detailed name for the selected controller. Names
that include spaces must be enclosed in quotes.
Expand All @@ -107,8 +107,8 @@ that include spaces must be enclosed in quotes.
Keywords are separated into two categories, keycodes and input port
definitions. To specify a key re-mapping, specify the keycode as the
keyword to re-define (that is, on the left-hand side) followed by the
replacement code. To specify a sequence re-map, specify the input port
keyword to re-define (that is, on the left-hand side) followed by the
replacement code. To specify a sequence re-map, specify the input port
code to be re-defined on the left followed by the sequence.
In addition to the standard codes, additional OSD specific codes may be
Expand All @@ -131,8 +131,8 @@ connected. In the codes listed above, the Wingman Warrior was connected as
the first joystick (J1). If it had been configured as a different input,
the generated codes would have a different Jx number.
All keyword matching including the standard keywords is case sensitive.
Also, some of the automatically generated OSD codes may be redundant.
All keyword matching including the standard keywords is case sensitive.
Also, some of the automatically generated OSD codes may be redundant.
For example, J1_Button_0 is the same as JOYCODE_1_BUTTON1. Standard codes
are preferred over OSD codes.
Expand Down Expand Up @@ -240,15 +240,15 @@ P2_JOYSTICKLEFT_RIGHT
P3_JOYSTICK_UP P3_JOYSTICK_DOWN P3_JOYSTICK_LEFT
P3_JOYSTICK_RIGHT P3_BUTTON1 P3_BUTTON2
P3_BUTTON3 P3_BUTTON4
P3_BUTTON3 P3_BUTTON4
P4_JOYSTICK_UP P4_JOYSTICK_DOWN P4_JOYSTICK_LEFT
P4_JOYSTICK_RIGHT P4_BUTTON1 P4_BUTTON2
P4_BUTTON3 P4_BUTTON4
P4_BUTTON3 P4_BUTTON4
P1_PEDAL P1_PEDAL_EXT P2_PEDAL
P2_PEDAL_EXT P3_PEDAL P3_PEDAL_EXT
P4_PEDAL P4_PEDAL_EXT
P4_PEDAL P4_PEDAL_EXT
P1_PADDLE P1_PADDLE_EXT P2_PADDLE
P2_PADDLE_EXT P3_PADDLE P3_PADDLE_EXT
Expand All @@ -266,19 +266,19 @@ P4_DIAL_V_EXT
P1_TRACKBALL_X P1_TRACKBALL_X_EXT P2_TRACKBALL_X
P2_TRACKBALL_X_EXT P3_TRACKBALL_X P3_TRACKBALL_X_EXT
P4_TRACKBALL_X P4_TRACKBALL_X_EXT
P4_TRACKBALL_X P4_TRACKBALL_X_EXT
P1_TRACKBALL_Y P1_TRACKBALL_Y_EXT P2_TRACKBALL_Y
P2_TRACKBALL_Y_EXT P3_TRACKBALL_Y P3_TRACKBALL_Y_EXT
P4_TRACKBALL_Y P4_TRACKBALL_Y_EXT
P4_TRACKBALL_Y P4_TRACKBALL_Y_EXT
P1_AD_STICK_X P1_AD_STICK_X_EXT P2_AD_STICK_X
P2_AD_STICK_X_EXT P3_AD_STICK_X P3_AD_STICK_X_EXT
P4_AD_STICK_X P4_AD_STICK_X_EXT
P4_AD_STICK_X P4_AD_STICK_X_EXT
P1_AD_STICK_Y P1_AD_STICK_Y_EXT P2_AD_STICK_Y
P2_AD_STICK_Y_EXT P3_AD_STICK_Y P3_AD_STICK_Y_EXT
P4_AD_STICK_Y P4_AD_STICK_Y_EXT
P4_AD_STICK_Y P4_AD_STICK_Y_EXT
OSD_1 OSD_2 OSD_3
OSD_4
Expand All @@ -290,6 +290,7 @@ OSD_4
#include <math.h>
#include "driver.h"
#include "config.h"
#include "cpuexec.h"


/***************************************************************************
Expand Down Expand Up @@ -1673,7 +1674,7 @@ static void load_default_keys(void)
config_read_default_ports(cfg, inputport_defaults);
config_close(cfg);
}

osd_customize_inputport_defaults(inputport_defaults);
}

Expand All @@ -1691,19 +1692,19 @@ static void save_default_keys(void)
memcpy(inputport_defaults,inputport_defaults_backup,sizeof(inputport_defaults_backup));
}

/*
/*
* void reset_default_inputs(void)
* repopulate mappings from the defaults specified in the inptport source
* repopulate mappings from the defaults specified in the inptport source
*/
void reset_default_inputs(void)
{
memcpy(inputport_defaults,inputport_defaults_backup,sizeof(inputport_defaults_backup));
save_default_keys();
}

/*
/*
* void reset_default_inputs(void)
* repopulate mappings from the defaults specified in the driver source
* repopulate mappings from the defaults specified in the driver source
*/
void reset_driver_inputs(void)
{
Expand Down Expand Up @@ -1871,6 +1872,9 @@ void update_analog_port(int port)
InputSeq* decseq;
int keydelta;
int player;
int xwayjoy;
int last_frame;
static int last_frame_inc = 0, last_frame_dec = 0;

/* get input definition */
in = input_analog[port];
Expand Down Expand Up @@ -1942,7 +1946,7 @@ void update_analog_port(int port)
delta = 0;

player = IP_GET_PLAYER(in);

/* if second player on a dial, and dial sharing turned on, use Y axis from player 1 */
if (options.dial_share_xy && type == IPT_DIAL && player == 1)
{
Expand All @@ -1952,11 +1956,30 @@ void update_analog_port(int port)

delta = mouse_delta_axis[player][axis];

if (seq_pressed(decseq)) delta -= keydelta;
xwayjoy = (in+2)->type & IPF_XWAYJOY;
last_frame = cpu_getcurrentframe() - 1;

if (seq_pressed(decseq))
/* Don't register button press if xwayjoy is on, is DIAL(_V) type, and button was pressed last frame */
if ( !( (xwayjoy == IPF_XWAYJOY)
&& ((type == IPT_DIAL) || (type == IPT_DIAL_V))
&& (last_frame == last_frame_dec) ) )
{
delta -= keydelta;
last_frame_dec = last_frame + 1;
}

if (type != IPT_PEDAL && type != IPT_PEDAL2)
{
if (seq_pressed(incseq)) delta += keydelta;
if (seq_pressed(incseq))
/* Don't register button press if xwayjoy is on, is DIAL(_V) type, and button was pressed last frame */
if ( !( (xwayjoy == IPF_XWAYJOY)
&& ((type == IPT_DIAL) || (type == IPT_DIAL_V))
&& (last_frame == last_frame_inc) ) )
{
delta += keydelta;
last_frame_inc = last_frame + 1;
}
}
else
{
Expand Down Expand Up @@ -2250,19 +2273,19 @@ ScanJoysticks( struct InputPort *in )
}

}
else if (options.restrict_4_way) //start use alternative code
else if (options.restrict_4_way) //start use alternative code
{
if(options.content_flags[CONTENT_ROTATE_JOY_45])
{
if ( (mJoyCurrent[i]) && (mJoyCurrent[i] !=1) &&
(mJoyCurrent[i] !=2) && (mJoyCurrent[i] !=4) &&
(mJoyCurrent[i] !=8) )
{
(mJoyCurrent[i] !=8) )
{
if (mJoyCurrent[i] == 9) mJoy4Way[i]=1;
else if (mJoyCurrent[i] == 6) mJoy4Way[i]=2;
else if (mJoyCurrent[i] == 5) mJoy4Way[i]=4;
else if (mJoyCurrent[i] == 10) mJoy4Way[i]=8;
}
}
else if (mJoy4Way[i])
mJoy4Way[i]=0;
}
Expand Down Expand Up @@ -2679,7 +2702,13 @@ struct InputPort* input_port_allocate(const struct InputPortTiny *src)
InputCode seq_default;

if (type > IPT_ANALOG_START && type < IPT_ANALOG_END)
src_end = src + 2;
{
if ((type == IPT_DIAL) || (type == IPT_DIAL_V))
/* third port stores additional data */
src_end = src + 3;
else
src_end = src + 2;
}
else
src_end = src + 1;

Expand Down
18 changes: 12 additions & 6 deletions src/inptport.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ enum { IPT_END=1,IPT_PORT,

#define IPF_RESETCPU 0x02000000 /* when the key is pressed, reset the first CPU */

#define IPF_XWAYJOY 0x04000000 /* block detected analog key/joy just pressed for one frame */
#define IPF_XWAYJOY_OFF 0x00000000 /* xwayjoy set to off */

/* The "arg" field contains 4 bytes fields */
#define IPF_SENSITIVITY(percent) ((percent & 0xff) << 8)
Expand Down Expand Up @@ -218,13 +220,17 @@ enum { IPT_END=1,IPT_PORT,
/* analog input */
#define PORT_ANALOG(mask,default,type,sensitivity,delta,min,max) \
PORT_BIT(mask, default, type) \
{ min, max, IPT_EXTENSION | IPF_SENSITIVITY(sensitivity) | IPF_DELTA(delta), IP_NAME_DEFAULT },
{ min, max, IPT_EXTENSION | IPF_SENSITIVITY(sensitivity) | IPF_DELTA(delta), IP_NAME_DEFAULT }, \
{ 0, 0, IPF_XWAYJOY_OFF, IP_NAME_DEFAULT },
/* Both zeros above are not used */

#define PORT_ANALOGX(mask,default,type,sensitivity,delta,min,max,keydec,keyinc,joydec,joyinc) \
PORT_BIT(mask, default, type) \
{ min, max, IPT_EXTENSION | IPF_SENSITIVITY(sensitivity) | IPF_DELTA(delta), IP_NAME_DEFAULT }, \
{ 0, 0, IPF_XWAYJOY_OFF, IP_NAME_DEFAULT }, \
PORT_CODE(keydec,joydec) \
PORT_CODE(keyinc,joyinc)
/* Both zeros above are not used */

/* dip switch definition */
#define PORT_DIPNAME(mask,default,name) \
Expand All @@ -244,7 +250,7 @@ enum { IPT_END=1,IPT_PORT,

#define MAX_DEFSTR_LEN 20
extern const char ipdn_defaultstrings[][MAX_DEFSTR_LEN];
#define PORT_ADJUSTER(default,name)
#define PORT_ADJUSTER(default,name)

/* this must match the ipdn_defaultstrings list in inptport.c */
enum {
Expand Down Expand Up @@ -412,15 +418,15 @@ extern int num_ik;
void seq_set_string(InputSeq* a, const char *buf);
const char *generic_ctrl_label(int input);

/*
/*
* void reset_default_inputs(void)
* repopulate mappings from the defaults specified in the inptport source
* repopulate mappings from the defaults specified in the inptport source
*/
void reset_default_inputs(void);

/*
/*
* void reset_default_keys(void)
* repopulate mappings from the defaults specified in the driver source
* repopulate mappings from the defaults specified in the driver source
*/
void reset_driver_inputs(void);

Expand Down
5 changes: 3 additions & 2 deletions src/ui_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ static const char *mame_default_text[] =
"Bookkeeping Info",
"Input (this game)",
"Flush Current CFG",
"Flush All CFGs",
"Flush All CFGs",
"Game Information",
"Game History",
"Reset Game",
"Generate XML DAT",
"Generate XML DAT",
"Return to Game",
"Cheat",
"Memory Card",
Expand All @@ -93,6 +93,7 @@ static const char *mame_default_text[] =
"Key/Joy Speed",
"Reverse",
"Sensitivity",
"X-Way Joystick",

/* stats */
"Tickets dispensed",
Expand Down
5 changes: 3 additions & 2 deletions src/ui_text.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ enum
UI_bookkeeping,
UI_inputspecific,
UI_flush_current_cfg,
UI_flush_all_cfg,
UI_flush_all_cfg,
UI_gameinfo,
UI_history,
UI_resetgame,
UI_generate_xml_dat,
UI_generate_xml_dat,
UI_returntogame,
UI_cheat,
UI_memorycard,
Expand All @@ -92,6 +92,7 @@ enum
UI_keyjoyspeed,
UI_reverse,
UI_sensitivity,
UI_xwayjoy,

/* stats */
UI_tickets,
Expand Down
Loading

0 comments on commit 7630b90

Please sign in to comment.