Let retroarch-joyconfig write autoconfigs.

This commit is contained in:
Themaister 2013-04-26 13:25:40 +02:00
parent 42a9e46cb2
commit 0ac849d825
7 changed files with 208 additions and 179 deletions

View File

@ -34,6 +34,10 @@ Use config file found in PATH as a base. Old configuration values can be overwri
\fB--output PATH, -o PATH\fR \fB--output PATH, -o PATH\fR
Writes the final config to a file, rather than \fBstdout\fR. If -i and -o point to the same file, the file found in PATH will simply be updated with the new configs. Writes the final config to a file, rather than \fBstdout\fR. If -i and -o point to the same file, the file found in PATH will simply be updated with the new configs.
.TP
\fB-a PATH, --autoconfig PATH\fR
Also writes an autoconfigure file for the joypad which was configured. It can be used by RetroArch to automatically configure a joypad when it's plugged in.
.TP .TP
\fB--misc, -m\fR \fB--misc, -m\fR
Also configure some binds that aren't directly related to RetroPad, such as save states, fullscreen toggling, etc. Also configure some binds that aren't directly related to RetroPad, such as save states, fullscreen toggling, etc.

View File

@ -555,6 +555,13 @@ static bool dinput_joypad_query_pad(unsigned pad)
return pad < MAX_PLAYERS && g_pads[pad].joypad; return pad < MAX_PLAYERS && g_pads[pad].joypad;
} }
static const char *dinput_joypad_name(unsigned pad)
{
(unsigned)pad;
// FIXME
return NULL;
}
const rarch_joypad_driver_t dinput_joypad = { const rarch_joypad_driver_t dinput_joypad = {
dinput_joypad_init, dinput_joypad_init,
dinput_joypad_query_pad, dinput_joypad_query_pad,
@ -562,6 +569,7 @@ const rarch_joypad_driver_t dinput_joypad = {
dinput_joypad_button, dinput_joypad_button,
dinput_joypad_axis, dinput_joypad_axis,
dinput_joypad_poll, dinput_joypad_poll,
dinput_joypad_name,
"dinput", "dinput",
}; };

View File

@ -86,6 +86,14 @@ void input_joypad_poll(const rarch_joypad_driver_t *driver)
driver->poll(); driver->poll();
} }
const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joypad)
{
if (!driver)
return NULL;
return driver->name(joypad);
}
bool input_joypad_pressed(const rarch_joypad_driver_t *driver, bool input_joypad_pressed(const rarch_joypad_driver_t *driver,
unsigned port, const struct retro_keybind *key) unsigned port, const struct retro_keybind *key)
{ {
@ -507,68 +515,68 @@ static const char *bind_player_prefix[MAX_PLAYERS] = {
"input_player8", "input_player8",
}; };
#define DECLARE_BIND(x, bind) { true, false, #x, bind } #define DECLARE_BIND(x, bind, desc) { true, false, #x, desc, bind }
#define DECLARE_META_BIND(x, bind) { true, true, #x, bind } #define DECLARE_META_BIND(x, bind, desc) { true, true, #x, desc, bind }
const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
DECLARE_BIND(b, RETRO_DEVICE_ID_JOYPAD_B), DECLARE_BIND(b, RETRO_DEVICE_ID_JOYPAD_B, "B button (down)"),
DECLARE_BIND(y, RETRO_DEVICE_ID_JOYPAD_Y), DECLARE_BIND(y, RETRO_DEVICE_ID_JOYPAD_Y, "Y button (left)"),
DECLARE_BIND(select, RETRO_DEVICE_ID_JOYPAD_SELECT), DECLARE_BIND(select, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select button"),
DECLARE_BIND(start, RETRO_DEVICE_ID_JOYPAD_START), DECLARE_BIND(start, RETRO_DEVICE_ID_JOYPAD_START, "Start button"),
DECLARE_BIND(up, RETRO_DEVICE_ID_JOYPAD_UP), DECLARE_BIND(up, RETRO_DEVICE_ID_JOYPAD_UP, "Up D-pad"),
DECLARE_BIND(down, RETRO_DEVICE_ID_JOYPAD_DOWN), DECLARE_BIND(down, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down D-pad"),
DECLARE_BIND(left, RETRO_DEVICE_ID_JOYPAD_LEFT), DECLARE_BIND(left, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left D-pad"),
DECLARE_BIND(right, RETRO_DEVICE_ID_JOYPAD_RIGHT), DECLARE_BIND(right, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right D-pad"),
DECLARE_BIND(a, RETRO_DEVICE_ID_JOYPAD_A), DECLARE_BIND(a, RETRO_DEVICE_ID_JOYPAD_A, "A button (right)"),
DECLARE_BIND(x, RETRO_DEVICE_ID_JOYPAD_X), DECLARE_BIND(x, RETRO_DEVICE_ID_JOYPAD_X, "X button (top)"),
DECLARE_BIND(l, RETRO_DEVICE_ID_JOYPAD_L), DECLARE_BIND(l, RETRO_DEVICE_ID_JOYPAD_L, "L button (left shoulder)"),
DECLARE_BIND(r, RETRO_DEVICE_ID_JOYPAD_R), DECLARE_BIND(r, RETRO_DEVICE_ID_JOYPAD_R, "R button (right shoulder)"),
DECLARE_BIND(l2, RETRO_DEVICE_ID_JOYPAD_L2), DECLARE_BIND(l2, RETRO_DEVICE_ID_JOYPAD_L2, "L2 button (left shoulder #2)"),
DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2), DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2, "R2 button (right shoulder #2)"),
DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3), DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3, "L3 button (left analog button)"),
DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3), DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3, "R3 button (right analog button)"),
DECLARE_BIND(turbo, RARCH_TURBO_ENABLE), DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, "Turbo enable"),
DECLARE_BIND(l_x_plus, RARCH_ANALOG_LEFT_X_PLUS), DECLARE_BIND(l_x_plus, RARCH_ANALOG_LEFT_X_PLUS, "Left analog X+ (right)"),
DECLARE_BIND(l_x_minus, RARCH_ANALOG_LEFT_X_MINUS), DECLARE_BIND(l_x_minus, RARCH_ANALOG_LEFT_X_MINUS, "Left analog X- (left)"),
DECLARE_BIND(l_y_plus, RARCH_ANALOG_LEFT_Y_PLUS), DECLARE_BIND(l_y_plus, RARCH_ANALOG_LEFT_Y_PLUS, "Left analog Y+ (down)"),
DECLARE_BIND(l_y_minus, RARCH_ANALOG_LEFT_Y_MINUS), DECLARE_BIND(l_y_minus, RARCH_ANALOG_LEFT_Y_MINUS, "Left analog Y- (up)"),
DECLARE_BIND(r_x_plus, RARCH_ANALOG_RIGHT_X_PLUS), DECLARE_BIND(r_x_plus, RARCH_ANALOG_RIGHT_X_PLUS, "Right analog X+ (right)"),
DECLARE_BIND(r_x_minus, RARCH_ANALOG_RIGHT_X_MINUS), DECLARE_BIND(r_x_minus, RARCH_ANALOG_RIGHT_X_MINUS, "Right analog X- (left)"),
DECLARE_BIND(r_y_plus, RARCH_ANALOG_RIGHT_Y_PLUS), DECLARE_BIND(r_y_plus, RARCH_ANALOG_RIGHT_Y_PLUS, "Right analog Y+ (down)"),
DECLARE_BIND(r_y_minus, RARCH_ANALOG_RIGHT_Y_MINUS), DECLARE_BIND(r_y_minus, RARCH_ANALOG_RIGHT_Y_MINUS, "Right analog Y- (up)"),
DECLARE_META_BIND(toggle_fast_forward, RARCH_FAST_FORWARD_KEY), DECLARE_META_BIND(toggle_fast_forward, RARCH_FAST_FORWARD_KEY, "Fast forward toggle"),
DECLARE_META_BIND(hold_fast_forward, RARCH_FAST_FORWARD_HOLD_KEY), DECLARE_META_BIND(hold_fast_forward, RARCH_FAST_FORWARD_HOLD_KEY, "Fast forward hold"),
DECLARE_META_BIND(load_state, RARCH_LOAD_STATE_KEY), DECLARE_META_BIND(load_state, RARCH_LOAD_STATE_KEY, "Load state"),
DECLARE_META_BIND(save_state, RARCH_SAVE_STATE_KEY), DECLARE_META_BIND(save_state, RARCH_SAVE_STATE_KEY, "Save state"),
DECLARE_META_BIND(toggle_fullscreen, RARCH_FULLSCREEN_TOGGLE_KEY), DECLARE_META_BIND(toggle_fullscreen, RARCH_FULLSCREEN_TOGGLE_KEY, "Fullscreen toggle"),
DECLARE_META_BIND(exit_emulator, RARCH_QUIT_KEY), DECLARE_META_BIND(exit_emulator, RARCH_QUIT_KEY, "Quit RetroArch"),
DECLARE_META_BIND(state_slot_increase, RARCH_STATE_SLOT_PLUS), DECLARE_META_BIND(state_slot_increase, RARCH_STATE_SLOT_PLUS, "Savestate slot +"),
DECLARE_META_BIND(state_slot_decrease, RARCH_STATE_SLOT_MINUS), DECLARE_META_BIND(state_slot_decrease, RARCH_STATE_SLOT_MINUS, "Savestate slot -"),
DECLARE_META_BIND(rewind, RARCH_REWIND), DECLARE_META_BIND(rewind, RARCH_REWIND, "Rewind"),
DECLARE_META_BIND(movie_record_toggle, RARCH_MOVIE_RECORD_TOGGLE), DECLARE_META_BIND(movie_record_toggle, RARCH_MOVIE_RECORD_TOGGLE, "Movie record toggle"),
DECLARE_META_BIND(pause_toggle, RARCH_PAUSE_TOGGLE), DECLARE_META_BIND(pause_toggle, RARCH_PAUSE_TOGGLE, "Pause toggle"),
DECLARE_META_BIND(frame_advance, RARCH_FRAMEADVANCE), DECLARE_META_BIND(frame_advance, RARCH_FRAMEADVANCE, "Frameadvance"),
DECLARE_META_BIND(reset, RARCH_RESET), DECLARE_META_BIND(reset, RARCH_RESET, "Reset game"),
DECLARE_META_BIND(shader_next, RARCH_SHADER_NEXT), DECLARE_META_BIND(shader_next, RARCH_SHADER_NEXT, "Next shader"),
DECLARE_META_BIND(shader_prev, RARCH_SHADER_PREV), DECLARE_META_BIND(shader_prev, RARCH_SHADER_PREV, "Previous shader"),
DECLARE_META_BIND(cheat_index_plus, RARCH_CHEAT_INDEX_PLUS), DECLARE_META_BIND(cheat_index_plus, RARCH_CHEAT_INDEX_PLUS, "Cheat index +"),
DECLARE_META_BIND(cheat_index_minus, RARCH_CHEAT_INDEX_MINUS), DECLARE_META_BIND(cheat_index_minus, RARCH_CHEAT_INDEX_MINUS, "Cheat index -"),
DECLARE_META_BIND(cheat_toggle, RARCH_CHEAT_TOGGLE), DECLARE_META_BIND(cheat_toggle, RARCH_CHEAT_TOGGLE, "Cheat toggle"),
DECLARE_META_BIND(screenshot, RARCH_SCREENSHOT), DECLARE_META_BIND(screenshot, RARCH_SCREENSHOT, "Take screenshot"),
DECLARE_META_BIND(dsp_config, RARCH_DSP_CONFIG), DECLARE_META_BIND(dsp_config, RARCH_DSP_CONFIG, "DSP config"),
DECLARE_META_BIND(audio_mute, RARCH_MUTE), DECLARE_META_BIND(audio_mute, RARCH_MUTE, "Audio mute toggle"),
DECLARE_META_BIND(netplay_flip_players, RARCH_NETPLAY_FLIP), DECLARE_META_BIND(netplay_flip_players, RARCH_NETPLAY_FLIP, "Netplay flip players"),
DECLARE_META_BIND(slowmotion, RARCH_SLOWMOTION), DECLARE_META_BIND(slowmotion, RARCH_SLOWMOTION, "Slow motion"),
DECLARE_META_BIND(enable_hotkey, RARCH_ENABLE_HOTKEY), DECLARE_META_BIND(enable_hotkey, RARCH_ENABLE_HOTKEY, "Enable hotkeys"),
DECLARE_META_BIND(volume_up, RARCH_VOLUME_UP), DECLARE_META_BIND(volume_up, RARCH_VOLUME_UP, "Volume +"),
DECLARE_META_BIND(volume_down, RARCH_VOLUME_DOWN), DECLARE_META_BIND(volume_down, RARCH_VOLUME_DOWN, "Volume -"),
DECLARE_META_BIND(overlay_next, RARCH_OVERLAY_NEXT), DECLARE_META_BIND(overlay_next, RARCH_OVERLAY_NEXT, "Overlay next"),
DECLARE_META_BIND(disk_eject_toggle, RARCH_DISK_EJECT_TOGGLE), DECLARE_META_BIND(disk_eject_toggle, RARCH_DISK_EJECT_TOGGLE, "Disk eject toggle"),
DECLARE_META_BIND(disk_next, RARCH_DISK_NEXT), DECLARE_META_BIND(disk_next, RARCH_DISK_NEXT, "Disk next"),
DECLARE_META_BIND(grab_mouse_toggle, RARCH_GRAB_MOUSE_TOGGLE), DECLARE_META_BIND(grab_mouse_toggle, RARCH_GRAB_MOUSE_TOGGLE, "Grab mouse toggle"),
#ifdef HAVE_RGUI #ifdef HAVE_RGUI
DECLARE_META_BIND(menu_toggle, RARCH_MENU_TOGGLE), DECLARE_META_BIND(menu_toggle, RARCH_MENU_TOGGLE, "RGUI menu toggle"),
#endif #endif
}; };

View File

@ -66,6 +66,7 @@ typedef struct rarch_joypad_driver
bool (*button)(unsigned, uint16_t); bool (*button)(unsigned, uint16_t);
int16_t (*axis)(unsigned, uint32_t); int16_t (*axis)(unsigned, uint32_t);
void (*poll)(void); void (*poll)(void);
const char *(*name)(unsigned);
const char *ident; const char *ident;
} rarch_joypad_driver_t; } rarch_joypad_driver_t;
@ -87,6 +88,7 @@ bool input_joypad_hat_raw(const rarch_joypad_driver_t *driver,
unsigned joypad, unsigned hat_dir, unsigned hat); unsigned joypad, unsigned hat_dir, unsigned hat);
void input_joypad_poll(const rarch_joypad_driver_t *driver); void input_joypad_poll(const rarch_joypad_driver_t *driver);
const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joypad);
extern const rarch_joypad_driver_t dinput_joypad; extern const rarch_joypad_driver_t dinput_joypad;
extern const rarch_joypad_driver_t linuxraw_joypad; extern const rarch_joypad_driver_t linuxraw_joypad;
@ -113,6 +115,7 @@ struct input_bind_map
bool valid; bool valid;
bool meta; // Meta binds get input as prefix, not input_playerN" bool meta; // Meta binds get input as prefix, not input_playerN"
const char *base; const char *base;
const char *desc;
unsigned retro_key; unsigned retro_key;
}; };
extern const struct input_bind_map input_config_bind_map[]; extern const struct input_bind_map input_config_bind_map[];

View File

@ -292,6 +292,14 @@ static bool linuxraw_joypad_query_pad(unsigned pad)
return pad < MAX_PLAYERS && g_pads[pad].fd >= 0; return pad < MAX_PLAYERS && g_pads[pad].fd >= 0;
} }
static const char *linuxraw_joypad_name(unsigned pad)
{
if (pad >= MAX_PLAYERS)
return NULL;
return *g_pads[pad].ident ? g_pads[pad].ident : NULL;
}
const rarch_joypad_driver_t linuxraw_joypad = { const rarch_joypad_driver_t linuxraw_joypad = {
linuxraw_joypad_init, linuxraw_joypad_init,
linuxraw_joypad_query_pad, linuxraw_joypad_query_pad,
@ -299,6 +307,7 @@ const rarch_joypad_driver_t linuxraw_joypad = {
linuxraw_joypad_button, linuxraw_joypad_button,
linuxraw_joypad_axis, linuxraw_joypad_axis,
linuxraw_joypad_poll, linuxraw_joypad_poll,
linuxraw_joypad_name,
"linuxraw", "linuxraw",
}; };

View File

@ -155,6 +155,14 @@ static bool sdl_joypad_query_pad(unsigned pad)
return pad < MAX_PLAYERS && g_pads[pad].joypad; return pad < MAX_PLAYERS && g_pads[pad].joypad;
} }
static const char *sdl_joypad_name(unsigned pad)
{
if (pad >= MAX_PLAYERS)
return NULL;
return SDL_JoystickName(pad);
}
const rarch_joypad_driver_t sdl_joypad = { const rarch_joypad_driver_t sdl_joypad = {
sdl_joypad_init, sdl_joypad_init,
sdl_joypad_query_pad, sdl_joypad_query_pad,
@ -162,6 +170,7 @@ const rarch_joypad_driver_t sdl_joypad = {
sdl_joypad_button, sdl_joypad_button,
sdl_joypad_axis, sdl_joypad_axis,
sdl_joypad_poll, sdl_joypad_poll,
sdl_joypad_name,
"sdl", "sdl",
}; };

View File

@ -37,6 +37,7 @@ static int g_player = 1;
static int g_joypad = 0; static int g_joypad = 0;
static char *g_in_path = NULL; static char *g_in_path = NULL;
static char *g_out_path = NULL; static char *g_out_path = NULL;
static char *g_auto_path = NULL;
static bool g_use_misc = false; static bool g_use_misc = false;
static void print_help(void) static void print_help(void)
@ -44,91 +45,18 @@ static void print_help(void)
puts("=================="); puts("==================");
puts("retroarch-joyconfig"); puts("retroarch-joyconfig");
puts("=================="); puts("==================");
puts("Usage: retroarch-joyconfig [ -p/--player <1-5> | -j/--joypad <num> | -i/--input <file> | -o/--output <file> | -h/--help ]"); puts("Usage: retroarch-joyconfig [ -p/--player <1-8> | -j/--joypad <num> | -i/--input <file> | -o/--output <file> | -h/--help ]");
puts(""); puts("");
puts("-p/--player: Which player to configure for (1 up to and including 5)."); puts("-p/--player: Which player to configure for (1 up to and including 8).");
puts("-j/--joypad: Which joypad to use when configuring (first joypad is 0)."); puts("-j/--joypad: Which joypad to use when configuring (first joypad is 0).");
puts("-i/--input: Input file to configure with. Binds will be added on or overwritten."); puts("-i/--input: Input file to configure with. Binds will be added on or overwritten.");
puts("\tIf not selected, an empty config will be used as a base."); puts("\tIf not selected, an empty config will be used as a base.");
puts("-o/--output: Output file to write to. If not selected, config file will be dumped to stdout."); puts("-o/--output: Output file to write to. If not selected, config file will be dumped to stdout.");
puts("-a/--autoconfig: Outputs an autoconfig file for joypad which was configured.");
puts("-m/--misc: Also configure various keybinds that are not directly libretro related. These configurations are for player 1 only."); puts("-m/--misc: Also configure various keybinds that are not directly libretro related. These configurations are for player 1 only.");
puts("-h/--help: This help."); puts("-h/--help: This help.");
} }
struct bind
{
const char *keystr;
const char *confbtn[MAX_PLAYERS];
const char *confaxis[MAX_PLAYERS];
bool is_misc;
};
#define BIND(x, k) { x, { "input_player1_" #k "_btn", "input_player2_" #k "_btn", "input_player3_" #k "_btn", "input_player4_" #k "_btn", "input_player5_" #k "_btn" }, {"input_player1_" #k "_axis", "input_player2_" #k "_axis", "input_player3_" #k "_axis", "input_player4_" #k "_axis", "input_player5_" #k "_axis"}, false}
#define MISC_BIND(x, k) { x, { "input_" #k "_btn" }, { "input_" #k "_axis" }, true}
static struct bind binds[] = {
BIND("A button (right)", a),
BIND("B button (down)", b),
BIND("X button (top)", x),
BIND("Y button (left)", y),
BIND("L button (left shoulder)", l),
BIND("R button (right shoulder)", r),
BIND("L2 button (left shoulder #2)", l2),
BIND("R2 button (right shoulder #2)", r2),
BIND("L3 button (left analog button)", l3),
BIND("R3 button (right analog button)", r3),
BIND("Start button", start),
BIND("Select button", select),
BIND("Left D-pad", left),
BIND("Up D-pad", up),
BIND("Right D-pad", right),
BIND("Down D-pad", down),
BIND("Left analog X+ (right)", l_x_plus),
BIND("Left analog Y+ (down)", l_y_plus),
BIND("Left analog X- (left)", l_x_minus),
BIND("Left analog Y- (up)", l_y_minus),
BIND("Right analog X+ (right)", r_x_plus),
BIND("Right analog Y+ (down)", r_y_plus),
BIND("Right analog X- (left)", r_x_minus),
BIND("Right analog Y- (up)", r_y_minus),
MISC_BIND("Save state", save_state),
MISC_BIND("Load state", load_state),
MISC_BIND("Exit emulator", exit_emulator),
MISC_BIND("Toggle fullscreen", toggle_fullscreen),
MISC_BIND("Save state slot increase", state_slot_increase),
MISC_BIND("Save state slot decrease", state_slot_decrease),
MISC_BIND("Toggle fast forward", toggle_fast_forward),
MISC_BIND("Hold fast forward", hold_fast_forward),
MISC_BIND("Audio input rate step up", rate_step_up),
MISC_BIND("Audio input rate step down", rate_step_down),
MISC_BIND("Rewind", rewind),
MISC_BIND("Movie recording toggle", movie_record_toggle),
MISC_BIND("Pause", pause_toggle),
MISC_BIND("Frame advance", frame_advance),
MISC_BIND("Reset", reset),
MISC_BIND("Next shader", shader_next),
MISC_BIND("Previous shader", shader_prev),
MISC_BIND("Toggle cheat on/off", cheat_toggle),
MISC_BIND("Cheat index plus", cheat_index_plus),
MISC_BIND("Cheat index minus", cheat_index_minus),
MISC_BIND("Screenshot", screenshot),
MISC_BIND("DSP config", dsp_config),
MISC_BIND("Audio mute/unmute", audio_mute),
MISC_BIND("Netplay player flip", netplay_flip_players),
MISC_BIND("Slow motion", slowmotion),
MISC_BIND("Hotkey enable", enable_hotkey),
MISC_BIND("Volume up", volume_up),
MISC_BIND("Volume down", volume_down),
MISC_BIND("Next overlay", overlay_next),
MISC_BIND("Disk eject toggle", disk_eject_toggle),
MISC_BIND("Disk next cycle", disk_next),
MISC_BIND("Grab mouse toggle", grab_mouse_toggle),
MISC_BIND("Menu toggle", menu_toggle),
};
#define MAX_BUTTONS 32 #define MAX_BUTTONS 32
#define MAX_AXES 32 #define MAX_AXES 32
#define MAX_HATS 32 #define MAX_HATS 32
@ -163,7 +91,7 @@ static void poll_joypad(const rarch_joypad_driver_t *driver,
} }
} }
static void get_binds(config_file_t *conf, int player, int joypad) static void get_binds(config_file_t *conf, config_file_t *auto_conf, int player, int joypad)
{ {
const rarch_joypad_driver_t *driver = input_joypad_init_first(); const rarch_joypad_driver_t *driver = input_joypad_init_first();
if (!driver) if (!driver)
@ -179,6 +107,11 @@ static void get_binds(config_file_t *conf, int player, int joypad)
} }
fprintf(stderr, "Found joypad driver: %s\n", driver->ident); fprintf(stderr, "Found joypad driver: %s\n", driver->ident);
const char *joypad_name = input_joypad_name(driver, joypad);
fprintf(stderr, "Using joypad: %s\n", joypad_name ? joypad_name : "Unknown");
if (joypad_name && auto_conf)
config_set_string(auto_conf, "input_device", joypad_name);
int16_t initial_axes[MAX_AXES] = {0}; int16_t initial_axes[MAX_AXES] = {0};
struct poll_data old_poll = {{0}}; struct poll_data old_poll = {{0}};
@ -208,11 +141,15 @@ static void get_binds(config_file_t *conf, int player, int joypad)
fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n", fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n",
player + 1, joypad); player + 1, joypad);
for (unsigned i = 0; i < sizeof(binds) / sizeof(binds[0]) && (g_use_misc || !binds[i].is_misc) ; i++) for (unsigned i = 0; input_config_bind_map[i].valid &&
(g_use_misc || !input_config_bind_map[i].meta); i++)
{ {
fprintf(stderr, "%s\n", binds[i].keystr); if (i == RARCH_TURBO_ENABLE)
continue;
unsigned player_index = binds[i].is_misc ? 0 : player; fprintf(stderr, "%s\n", input_config_bind_map[i].desc);
unsigned player_index = input_config_bind_map[i].meta ? 0 : player;
for (;;) for (;;)
{ {
@ -229,51 +166,74 @@ static void get_binds(config_file_t *conf, int player, int joypad)
if (new_poll.buttons[j] && !old_poll.buttons[j]) if (new_poll.buttons[j] && !old_poll.buttons[j])
{ {
fprintf(stderr, "\tJoybutton pressed: %u\n", j); fprintf(stderr, "\tJoybutton pressed: %u\n", j);
config_set_int(conf, binds[i].confbtn[player_index], j); char key[64];
snprintf(key, sizeof(key), "%s_%s_btn",
input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base);
config_set_int(conf, key, j);
if (auto_conf)
{
snprintf(key, sizeof(key), "input_%s_btn",
input_config_bind_map[i].base);
config_set_int(auto_conf, key, j);
}
goto out; goto out;
} }
} }
for (int j = 0; j < MAX_AXES; j++) for (int j = 0; j < MAX_AXES; j++)
{ {
if (new_poll.axes[j] != old_poll.axes[j]) if (new_poll.axes[j] == old_poll.axes[j])
continue;
int16_t value = new_poll.axes[j];
bool same_axis = last_axis == j;
bool require_negative = initial_axes[j] > 0;
bool require_positive = initial_axes[j] < 0;
// Block the axis config until we're sure axes have returned to their neutral state.
if (same_axis)
{ {
int16_t value = new_poll.axes[j]; if (abs(value) < 10000 ||
bool same_axis = last_axis == j; (require_positive && value < 0) ||
bool require_negative = initial_axes[j] > 0; (require_negative && value > 0))
bool require_positive = initial_axes[j] < 0; block_axis = false;
}
// Block the axis config until we're sure axes have returned to their neutral state. // If axes are in their neutral state, we can't allow it.
if (same_axis) if (require_negative && value >= 0)
continue;
if (require_positive && value <= 0)
continue;
if (block_axis)
continue;
if (abs(value) > 20000)
{
last_axis = j;
fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", j, value);
char buf[8];
snprintf(buf, sizeof(buf),
value > 0 ? "+%d" : "-%d", j);
char key[64];
snprintf(key, sizeof(key), "%s_%s_axis",
input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base);
config_set_string(conf, key, buf);
if (auto_conf)
{ {
if (abs(value) < 10000 || snprintf(key, sizeof(key), "input_%s_axis",
(require_positive && value < 0) || input_config_bind_map[i].base);
(require_negative && value > 0)) config_set_string(auto_conf, key, buf);
block_axis = false;
} }
// If axes are in their neutral state, we can't allow it. block_axis = true;
if (require_negative && value >= 0) goto out;
continue;
if (require_positive && value <= 0)
continue;
if (block_axis)
continue;
if (abs(value) > 20000)
{
last_axis = j;
fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", j, value);
char buf[8];
snprintf(buf, sizeof(buf),
value > 0 ? "+%d" : "-%d", j);
config_set_string(conf, binds[i].confaxis[player_index], buf);
block_axis = true;
goto out;
}
} }
} }
@ -297,7 +257,20 @@ static void get_binds(config_file_t *conf, int player, int joypad)
fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark); fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark);
char buf[16]; char buf[16];
snprintf(buf, sizeof(buf), "h%d%s", j, quark); snprintf(buf, sizeof(buf), "h%d%s", j, quark);
config_set_string(conf, binds[i].confbtn[player_index], buf);
char key[64];
snprintf(key, sizeof(key), "%s_%s_btn",
input_config_get_prefix(player_index, input_config_bind_map[i].meta), input_config_bind_map[i].base);
config_set_string(conf, key, buf);
if (auto_conf)
{
snprintf(key, sizeof(key), "input_%s_btn",
input_config_bind_map[i].base);
config_set_string(auto_conf, key, buf);
}
goto out; goto out;
} }
} }
@ -309,10 +282,11 @@ out:
static void parse_input(int argc, char *argv[]) static void parse_input(int argc, char *argv[])
{ {
char optstring[] = "i:o:p:j:hm"; char optstring[] = "i:o:a:p:j:hm";
struct option opts[] = { struct option opts[] = {
{ "input", 1, NULL, 'i' }, { "input", 1, NULL, 'i' },
{ "output", 1, NULL, 'o' }, { "output", 1, NULL, 'o' },
{ "autoconfig", 1, NULL, 'a' },
{ "player", 1, NULL, 'p' }, { "player", 1, NULL, 'p' },
{ "joypad", 1, NULL, 'j' }, { "joypad", 1, NULL, 'j' },
{ "help", 0, NULL, 'h' }, { "help", 0, NULL, 'h' },
@ -341,6 +315,10 @@ static void parse_input(int argc, char *argv[])
g_out_path = strdup(optarg); g_out_path = strdup(optarg);
break; break;
case 'a':
g_auto_path = strdup(optarg);
break;
case 'm': case 'm':
g_use_misc = true; g_use_misc = true;
break; break;
@ -410,12 +388,22 @@ int main(int argc, char *argv[])
config_set_int(conf, index_list[g_player - 1], g_joypad); config_set_int(conf, index_list[g_player - 1], g_joypad);
get_binds(conf, g_player - 1, g_joypad); config_file_t *auto_conf = NULL;
if (g_auto_path)
auto_conf = config_file_new(NULL);
get_binds(conf, auto_conf, g_player - 1, g_joypad);
config_file_write(conf, g_out_path); config_file_write(conf, g_out_path);
config_file_free(conf); config_file_free(conf);
if (g_in_path) if (auto_conf)
free(g_in_path); {
if (g_out_path) fprintf(stderr, "Writing autoconfig profile to: %s.\n", g_auto_path);
free(g_out_path); config_file_write(auto_conf, g_auto_path);
config_file_free(auto_conf);
}
free(g_in_path);
free(g_out_path);
free(g_auto_path);
return 0; return 0;
} }