improved gamepad support using SDL GameController API
still WIP, but it's better than it was todo (maybe): - handle hotplugging - enable gamepad support by default - treat analog triggers as buttons - better way of saving which device to use to the config, the index is virtually useless
This commit is contained in:
parent
70933bcd4e
commit
57a138c1d1
5 changed files with 234 additions and 119 deletions
20
src/config.c
20
src/config.c
|
@ -16,7 +16,7 @@ static bool config_initialized = false;
|
|||
CONFIGDEFS_EXPORT ConfigEntry configdefs[] = {
|
||||
#define CONFIGDEF(type,entryname,default,ufield) {type, entryname, {.ufield = default}, NULL},
|
||||
#define CONFIGDEF_KEYBINDING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_KEYBINDING, entryname, default, i)
|
||||
#define CONFIGDEF_GPKEYBINDING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_INT, entryname, default, i)
|
||||
#define CONFIGDEF_GPKEYBINDING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_GPKEYBINDING, entryname, default, i)
|
||||
#define CONFIGDEF_INT(id,entryname,default) CONFIGDEF(CONFIG_TYPE_INT, entryname, default, i)
|
||||
#define CONFIGDEF_FLOAT(id,entryname,default) CONFIGDEF(CONFIG_TYPE_FLOAT, entryname, default, f)
|
||||
#define CONFIGDEF_STRING(id,entryname,default) CONFIGDEF(CONFIG_TYPE_STRING, entryname, NULL, s)
|
||||
|
@ -156,6 +156,7 @@ static void config_set_val(ConfigIndex idx, ConfigValue v) {
|
|||
switch(e->type) {
|
||||
case CONFIG_TYPE_INT:
|
||||
case CONFIG_TYPE_KEYBINDING:
|
||||
case CONFIG_TYPE_GPKEYBINDING:
|
||||
difference = e->val.i != v.i;
|
||||
break;
|
||||
|
||||
|
@ -184,6 +185,7 @@ static void config_set_val(ConfigIndex idx, ConfigValue v) {
|
|||
switch(e->type) {
|
||||
case CONFIG_TYPE_INT:
|
||||
case CONFIG_TYPE_KEYBINDING:
|
||||
case CONFIG_TYPE_GPKEYBINDING:
|
||||
e->val.i = v.i;
|
||||
PRINTVAL(i)
|
||||
break;
|
||||
|
@ -290,6 +292,10 @@ void config_save(void) {
|
|||
SDL_RWprintf(out, "%s = %s\n", e->name, SDL_GetScancodeName(e->val.i));
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_GPKEYBINDING:
|
||||
SDL_RWprintf(out, "%s = %s\n", e->name, SDL_GameControllerGetStringForButton(e->val.i));
|
||||
break;
|
||||
|
||||
case CONFIG_TYPE_STRING:
|
||||
SDL_RWprintf(out, "%s = %s\n", e->name, e->val.s);
|
||||
break;
|
||||
|
@ -344,6 +350,18 @@ static void config_set(const char *key, const char *val, void *data) {
|
|||
break;
|
||||
}
|
||||
|
||||
case CONFIG_TYPE_GPKEYBINDING: {
|
||||
SDL_GameControllerButton btn = SDL_GameControllerGetButtonFromString(val);
|
||||
|
||||
if(btn == SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
log_warn("Unknown gamepad key '%s'", val);
|
||||
} else {
|
||||
e->val.i = btn;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CONFIG_TYPE_STRING:
|
||||
stralloc(&e->val.s, val);
|
||||
break;
|
||||
|
|
18
src/config.h
18
src/config.h
|
@ -56,15 +56,14 @@
|
|||
|
||||
|
||||
#define GPKEYDEFS \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_UP, "gamepad_key_up", -1) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_DOWN, "gamepad_key_down", -1) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_LEFT, "gamepad_key_left", -1) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_RIGHT, "gamepad_key_right", -1) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_FOCUS, "gamepad_key_focus", 0) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_SHOT, "gamepad_key_shot", 1) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_BOMB, "gamepad_key_bomb", 2) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_SKIP, "gamepad_key_skip", 3) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_PAUSE, "gamepad_key_pause", 4) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_UP, "gamepad_key_up", SDL_CONTROLLER_BUTTON_DPAD_UP) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_DOWN, "gamepad_key_down", SDL_CONTROLLER_BUTTON_DPAD_DOWN) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_LEFT, "gamepad_key_left", SDL_CONTROLLER_BUTTON_DPAD_LEFT) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_RIGHT, "gamepad_key_right", SDL_CONTROLLER_BUTTON_DPAD_RIGHT) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_FOCUS, "gamepad_key_focus", SDL_CONTROLLER_BUTTON_X) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_SHOT, "gamepad_key_shot", SDL_CONTROLLER_BUTTON_A) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_BOMB, "gamepad_key_bomb", SDL_CONTROLLER_BUTTON_Y) \
|
||||
CONFIGDEF_GPKEYBINDING(KEY_SKIP, "gamepad_key_skip", SDL_CONTROLLER_BUTTON_B) \
|
||||
|
||||
|
||||
#define CONFIGDEFS \
|
||||
|
@ -153,6 +152,7 @@ typedef enum ConfigEntryType {
|
|||
CONFIG_TYPE_INT,
|
||||
CONFIG_TYPE_STRING,
|
||||
CONFIG_TYPE_KEYBINDING,
|
||||
CONFIG_TYPE_GPKEYBINDING,
|
||||
CONFIG_TYPE_FLOAT
|
||||
} ConfigEntryType;
|
||||
|
||||
|
|
248
src/gamepad.c
248
src/gamepad.c
|
@ -13,66 +13,98 @@
|
|||
|
||||
static struct {
|
||||
int initialized;
|
||||
SDL_Joystick *device;
|
||||
SDL_GameController *device;
|
||||
SDL_JoystickID instance;
|
||||
signed char *axis;
|
||||
|
||||
struct {
|
||||
int *id_map;
|
||||
size_t count;
|
||||
} devices;
|
||||
} gamepad;
|
||||
|
||||
static void gamepad_update_device_list(void) {
|
||||
int cnt = SDL_NumJoysticks();
|
||||
log_info("Updating gamepad devices list");
|
||||
|
||||
free(gamepad.devices.id_map);
|
||||
memset(&gamepad.devices, 0, sizeof(gamepad.devices));
|
||||
|
||||
if(!cnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
int *idmap_ptr = gamepad.devices.id_map = malloc(sizeof(int) * cnt);
|
||||
|
||||
for(int i = 0; i < cnt; ++i) {
|
||||
if(!SDL_IsGameController(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*idmap_ptr = i;
|
||||
log_info("Gamepad device #%"PRIuMAX": %s", (uintmax_t)(idmap_ptr - gamepad.devices.id_map), SDL_GameControllerNameForIndex(i));
|
||||
++idmap_ptr;
|
||||
}
|
||||
|
||||
gamepad.devices.count = (uintptr_t)(idmap_ptr - gamepad.devices.id_map);
|
||||
}
|
||||
|
||||
void gamepad_init(void) {
|
||||
memset(&gamepad, 0, sizeof(gamepad));
|
||||
|
||||
if(!config_get_int(CONFIG_GAMEPAD_ENABLED))
|
||||
if(!config_get_int(CONFIG_GAMEPAD_ENABLED) || gamepad.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(gamepad.initialized)
|
||||
return;
|
||||
|
||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
|
||||
if(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
log_warn("SDL_InitSubSystem() failed: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
int i, cnt = gamepad_devicecount();
|
||||
log_info("Found %i devices", cnt);
|
||||
for(i = 0; i < cnt; ++i)
|
||||
log_info("Device #%i: %s", i, SDL_JoystickNameForIndex(i));
|
||||
gamepad_update_device_list();
|
||||
|
||||
int dev = config_get_int(CONFIG_GAMEPAD_DEVICE);
|
||||
if(dev < 0 || dev >= cnt) {
|
||||
if(dev < 0 || dev >= gamepad.devices.count) {
|
||||
log_warn("Device #%i is not available", dev);
|
||||
gamepad_shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
gamepad.device = SDL_JoystickOpen(dev);
|
||||
gamepad.device = SDL_GameControllerOpen(dev);
|
||||
if(!gamepad.device) {
|
||||
log_warn("Failed to open device %i: %s", dev, SDL_GetError());
|
||||
gamepad_shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
gamepad.axis = malloc(SDL_JoystickNumAxes(gamepad.device));
|
||||
SDL_Joystick *joy = SDL_GameControllerGetJoystick(gamepad.device);
|
||||
gamepad.instance = SDL_JoystickInstanceID(joy);
|
||||
gamepad.axis = malloc(max(SDL_JoystickNumAxes(joy), 1));
|
||||
|
||||
log_info("Using device #%i: %s", dev, gamepad_devicename(dev));
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
SDL_GameControllerEventState(SDL_ENABLE);
|
||||
|
||||
gamepad.initialized = 1;
|
||||
}
|
||||
|
||||
void gamepad_shutdown(void) {
|
||||
if(!gamepad.initialized)
|
||||
if(!gamepad.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(gamepad.initialized != 2)
|
||||
if(gamepad.initialized != 2) {
|
||||
log_info("Disabled the gamepad subsystem");
|
||||
}
|
||||
|
||||
if(gamepad.device)
|
||||
SDL_JoystickClose(gamepad.device);
|
||||
if(gamepad.device) {
|
||||
SDL_GameControllerClose(gamepad.device);
|
||||
}
|
||||
|
||||
free(gamepad.axis);
|
||||
gamepad.axis = NULL;
|
||||
free(gamepad.devices.id_map);
|
||||
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
gamepad.initialized = 0;
|
||||
SDL_GameControllerEventState(SDL_IGNORE);
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
|
||||
memset(&gamepad, 0, sizeof(gamepad));
|
||||
}
|
||||
|
||||
void gamepad_restart(void) {
|
||||
|
@ -80,7 +112,7 @@ void gamepad_restart(void) {
|
|||
gamepad_init();
|
||||
}
|
||||
|
||||
int gamepad_axis2gamekey(int id, int val) {
|
||||
int gamepad_axis2gamekey(SDL_GameControllerAxis id, int val) {
|
||||
val *= sign(gamepad_axis_sens(id));
|
||||
|
||||
if(!val) {
|
||||
|
@ -98,17 +130,17 @@ int gamepad_axis2gamekey(int id, int val) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int gamepad_axis2menuevt(int id, int val) {
|
||||
if(id == config_get_int(CONFIG_GAMEPAD_AXIS_LR))
|
||||
int gamepad_axis2menuevt(SDL_GameControllerAxis id, int val) {
|
||||
if(id == SDL_CONTROLLER_AXIS_LEFTX || id == SDL_CONTROLLER_AXIS_RIGHTX)
|
||||
return val == AXISVAL_LEFT ? E_CursorLeft : E_CursorRight;
|
||||
|
||||
if(id == config_get_int(CONFIG_GAMEPAD_AXIS_UD))
|
||||
if(id == SDL_CONTROLLER_AXIS_LEFTY || id == SDL_CONTROLLER_AXIS_RIGHTY)
|
||||
return val == AXISVAL_UP ? E_CursorUp : E_CursorDown;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gamepad_axis2gameevt(int id) {
|
||||
int gamepad_axis2gameevt(SDL_GameControllerAxis id) {
|
||||
if(id == config_get_int(CONFIG_GAMEPAD_AXIS_LR))
|
||||
return E_PlrAxisLR;
|
||||
|
||||
|
@ -118,7 +150,7 @@ int gamepad_axis2gameevt(int id) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
float gamepad_axis_sens(int id) {
|
||||
float gamepad_axis_sens(SDL_GameControllerAxis id) {
|
||||
if(id == config_get_int(CONFIG_GAMEPAD_AXIS_LR))
|
||||
return config_get_float(CONFIG_GAMEPAD_AXIS_LR_SENS);
|
||||
|
||||
|
@ -128,7 +160,7 @@ float gamepad_axis_sens(int id) {
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void *arg) {
|
||||
void gamepad_axis(SDL_GameControllerAxis id, int raw, EventHandler handler, EventFlags flags, void *arg) {
|
||||
signed char *a = gamepad.axis;
|
||||
signed char val = AXISVAL(raw);
|
||||
bool free = config_get_int(CONFIG_GAMEPAD_AXIS_FREE);
|
||||
|
@ -162,14 +194,16 @@ void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void
|
|||
|
||||
if(game && !free) {
|
||||
int key = gamepad_axis2gamekey(id, val);
|
||||
if(key >= 0)
|
||||
if(key >= 0) {
|
||||
handler(E_PlrKeyDown, key, arg);
|
||||
}
|
||||
}
|
||||
|
||||
if(menu) {
|
||||
int evt = gamepad_axis2menuevt(id, val);
|
||||
if(evt >= 0)
|
||||
if(evt >= 0) {
|
||||
handler(evt, 0, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // simulate release
|
||||
|
@ -187,7 +221,7 @@ void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void
|
|||
}
|
||||
}
|
||||
|
||||
void gamepad_button(int button, int state, EventHandler handler, EventFlags flags, void *arg) {
|
||||
void gamepad_button(SDL_GameControllerButton button, int state, EventHandler handler, EventFlags flags, void *arg) {
|
||||
int menu = flags & EF_Menu;
|
||||
int game = flags & EF_Game;
|
||||
int gpad = flags & EF_Gamepad;
|
||||
|
@ -195,36 +229,46 @@ void gamepad_button(int button, int state, EventHandler handler, EventFlags flag
|
|||
int gpkey = config_gamepad_key_from_gamepad_button(button);
|
||||
int key = config_key_from_gamepad_key(gpkey);
|
||||
|
||||
//printf("button: %i %i\n", button, state);
|
||||
//printf("gpkey: %i\n", gpkey);
|
||||
//printf("key: %i\n", key);
|
||||
|
||||
if(state == SDL_PRESSED) {
|
||||
if(game) {
|
||||
if(gpkey == GAMEPAD_KEY_PAUSE) {
|
||||
handler(E_Pause, 0, arg);
|
||||
} else if(key >= 0) {
|
||||
handler(E_PlrKeyDown, key, arg);
|
||||
}
|
||||
if(game) switch(button) {
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
handler(E_Pause, 0, arg); break;
|
||||
|
||||
default:
|
||||
if(key >= 0) {
|
||||
handler(E_PlrKeyDown, key, arg);
|
||||
} break;
|
||||
}
|
||||
|
||||
if(menu) switch(key) {
|
||||
case KEY_UP: handler(E_CursorUp, 0, arg); break;
|
||||
case KEY_DOWN: handler(E_CursorDown, 0, arg); break;
|
||||
case KEY_LEFT: handler(E_CursorLeft, 0, arg); break;
|
||||
case KEY_RIGHT: handler(E_CursorRight, 0, arg); break;
|
||||
case KEY_FOCUS: handler(E_MenuAbort, 0, arg); break;
|
||||
case KEY_SHOT: handler(E_MenuAccept, 0, arg); break;
|
||||
if(menu) switch(button) {
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP: handler(E_CursorUp, 0, arg); break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: handler(E_CursorDown, 0, arg); break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: handler(E_CursorLeft, 0, arg); break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: handler(E_CursorRight, 0, arg); break;
|
||||
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
handler(E_MenuAccept, 0, arg); break;
|
||||
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
handler(E_MenuAbort, 0, arg); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(gpad)
|
||||
if(gpad) {
|
||||
handler(E_GamepadKeyDown, button, arg);
|
||||
}
|
||||
} else {
|
||||
if(game && key >= 0)
|
||||
if(game && key >= 0) {
|
||||
handler(E_PlrKeyUp, key, arg);
|
||||
}
|
||||
|
||||
if(gpad)
|
||||
if(gpad) {
|
||||
handler(E_GamepadKeyUp, button, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,36 +282,45 @@ void gamepad_event(SDL_Event *event, EventHandler handler, EventFlags flags, voi
|
|||
int minval = clamp(deadzone, 0, 1) * GAMEPAD_AXIS_MAX;
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
val = event->jaxis.value;
|
||||
vsign = sign(val);
|
||||
val = abs(val);
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if(event->caxis.which == gamepad.instance) {
|
||||
val = event->caxis.value;
|
||||
vsign = sign(val);
|
||||
val = abs(val);
|
||||
|
||||
if(val < minval) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = vsign * clamp((val - minval) / (1.0 - deadzone), 0, GAMEPAD_AXIS_MAX);
|
||||
if(val < minval) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = vsign * clamp((val - minval) / (1.0 - deadzone), 0, GAMEPAD_AXIS_MAX);
|
||||
}
|
||||
|
||||
gamepad_axis(event->caxis.axis, val, handler, flags, arg);
|
||||
}
|
||||
|
||||
gamepad_axis(event->jaxis.axis, val, handler, flags, arg);
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP:
|
||||
gamepad_button(event->jbutton.button, event->jbutton.state, handler, flags, arg);
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
if(event->cbutton.which == gamepad.instance) {
|
||||
gamepad_button(event->cbutton.button, event->cbutton.state, handler, flags, arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int gamepad_devicecount(void) {
|
||||
return SDL_NumJoysticks();
|
||||
return gamepad.devices.count;
|
||||
}
|
||||
|
||||
char* gamepad_devicename(int id) {
|
||||
return (char*)SDL_JoystickNameForIndex(id);
|
||||
const char* gamepad_devicename(int id) {
|
||||
if(id < 0 || id >= gamepad.devices.count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SDL_GameControllerNameForIndex(gamepad.devices.id_map[id]);
|
||||
}
|
||||
|
||||
bool gamepad_buttonpressed(int btn) {
|
||||
return SDL_JoystickGetButton(gamepad.device, btn);
|
||||
bool gamepad_buttonpressed(SDL_GameControllerButton btn) {
|
||||
return SDL_GameControllerGetButton(gamepad.device, btn);
|
||||
}
|
||||
|
||||
bool gamepad_gamekeypressed(KeyIndex key) {
|
||||
|
@ -287,18 +340,65 @@ bool gamepad_gamekeypressed(KeyIndex key) {
|
|||
}
|
||||
|
||||
void gamepad_init_bare(void) {
|
||||
if(gamepad.initialized)
|
||||
if(gamepad.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
|
||||
if(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
log_warn("SDL_InitSubSystem() failed: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
gamepad_update_device_list();
|
||||
gamepad.initialized = 2;
|
||||
}
|
||||
|
||||
void gamepad_shutdown_bare(void) {
|
||||
if(gamepad.initialized == 2)
|
||||
if(gamepad.initialized == 2) {
|
||||
gamepad_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
const char* gamepad_button_name(SDL_GameControllerButton btn) {
|
||||
static const char *const map[] = {
|
||||
"A",
|
||||
"B",
|
||||
"X",
|
||||
"Y",
|
||||
"Back",
|
||||
"Guide",
|
||||
"Start",
|
||||
"Left Stick",
|
||||
"Right Stick",
|
||||
"Left Bumper",
|
||||
"Right Bumper",
|
||||
"Up",
|
||||
"Down",
|
||||
"Left",
|
||||
"Right",
|
||||
};
|
||||
|
||||
if(btn > SDL_CONTROLLER_BUTTON_INVALID && btn < SDL_CONTROLLER_BUTTON_MAX) {
|
||||
return map[btn];
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char* gamepad_axis_name(SDL_GameControllerAxis axis) {
|
||||
static const char *const map[] = {
|
||||
"Left X",
|
||||
"Left Y",
|
||||
"Right X",
|
||||
"Right Y",
|
||||
"Left Trigger",
|
||||
"Right Trigger",
|
||||
};
|
||||
|
||||
|
||||
if(axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX) {
|
||||
return map[axis];
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
|
|
@ -19,12 +19,15 @@ void gamepad_shutdown(void);
|
|||
void gamepad_restart(void);
|
||||
int gamepad_devicecount(void);
|
||||
float gamepad_axis_sens(int);
|
||||
char* gamepad_devicename(int);
|
||||
const char* gamepad_devicename(int);
|
||||
void gamepad_event(SDL_Event*, EventHandler, EventFlags, void*);
|
||||
|
||||
bool gamepad_buttonpressed(int btn);
|
||||
bool gamepad_gamekeypressed(KeyIndex key);
|
||||
|
||||
const char* gamepad_button_name(SDL_GameControllerButton btn);
|
||||
const char* gamepad_axis_name(SDL_GameControllerAxis btn);
|
||||
|
||||
// shitty workaround for the options menu. Used to list devices while the gamepad subsystem is off.
|
||||
// only initializes the SDL subsystem so you can use gamepad_devicecount/gamepad_devicename.
|
||||
// if gamepad has been initialized already, these do nothing.
|
||||
|
|
|
@ -391,30 +391,6 @@ void options_sub_gamepad_controls(MenuData *parent, void *arg) {
|
|||
|
||||
create_options_menu_basic(m, "Gamepad Controls");
|
||||
|
||||
add_menu_entry(m, "Fire / Accept", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_SHOT)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Focus / Abort", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_FOCUS)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Bomb", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_BOMB)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Pause", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_PAUSE)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Skip dialog", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_SKIP)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Move up", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_UP)
|
||||
);
|
||||
|
@ -431,6 +407,26 @@ void options_sub_gamepad_controls(MenuData *parent, void *arg) {
|
|||
bind_gpbinding(CONFIG_GAMEPAD_KEY_RIGHT)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Fire", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_SHOT)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Focus", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_FOCUS)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Bomb", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_BOMB)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "Skip dialog", do_nothing,
|
||||
bind_gpbinding(CONFIG_GAMEPAD_KEY_SKIP)
|
||||
);
|
||||
|
||||
add_menu_separator(m);
|
||||
add_menu_entry(m, "Back", menu_commonaction_close, NULL);
|
||||
|
||||
|
@ -733,13 +729,13 @@ void draw_options_menu(MenuData *menu) {
|
|||
if(bind->blockinput) {
|
||||
glColor4f(0.5, 1, 0.5, 1);
|
||||
draw_text(AL_Right, origin, 20*i,
|
||||
is_axis ? "Move an axis to assign, press any button to cancel"
|
||||
: "Press a button to assign, move an axis to cancel",
|
||||
is_axis ? "Move an axis to assign, Back to cancel"
|
||||
: "Press a button to assign, Back to cancel",
|
||||
_fonts.standard);
|
||||
} else if(config_get_int(bind->configentry) >= 0) {
|
||||
char tmp[32];
|
||||
snprintf(tmp, 32, is_axis ? "Axis %i" : "Button %i", config_get_int(bind->configentry) + 1);
|
||||
draw_text(AL_Right, origin, 20*i, tmp, _fonts.standard);
|
||||
int id = config_get_int(bind->configentry);
|
||||
const char *name = (is_axis ? gamepad_axis_name(id) : gamepad_button_name(id));
|
||||
draw_text(AL_Right, origin, 20*i, name, _fonts.standard);
|
||||
} else {
|
||||
draw_text(AL_Right, origin, 20*i, "Unbound", _fonts.standard);
|
||||
}
|
||||
|
@ -850,6 +846,9 @@ void bind_input_event(EventType type, int state, void *arg) {
|
|||
if(b->type == BT_GamepadAxisBinding)
|
||||
b->blockinput = false;
|
||||
break;
|
||||
} else if(scan == SDL_CONTROLLER_BUTTON_BACK || scan == SDL_CONTROLLER_BUTTON_START) {
|
||||
b->blockinput = false;
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = CONFIG_GAMEPAD_KEY_FIRST; i <= CONFIG_GAMEPAD_KEY_LAST; ++i) {
|
||||
|
@ -864,11 +863,6 @@ void bind_input_event(EventType type, int state, void *arg) {
|
|||
}
|
||||
|
||||
case E_GamepadAxis: {
|
||||
if(b->type == BT_GamepadKeyBinding) {
|
||||
b->blockinput = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(b->type == BT_GamepadAxisBinding) {
|
||||
if(b->configentry == CONFIG_GAMEPAD_AXIS_UD) {
|
||||
if(config_get_int(CONFIG_GAMEPAD_AXIS_LR) == state) {
|
||||
|
|
Loading…
Reference in a new issue