gamepad options menu improvements
This commit is contained in:
parent
3fb8d9efca
commit
671f3b8d3a
6 changed files with 94 additions and 35 deletions
|
@ -45,7 +45,9 @@ typedef enum {
|
|||
|
||||
// EF_Gamepad
|
||||
E_GamepadKeyDown,
|
||||
E_GamepadKeyUp
|
||||
E_GamepadKeyUp,
|
||||
E_GamepadAxis,
|
||||
E_GamepadAxisValue,
|
||||
} EventType;
|
||||
|
||||
typedef void(*EventHandler)(EventType, int, void*);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
static struct {
|
||||
int initialized;
|
||||
SDL_Joystick *device;
|
||||
int axis[GAMEPAD_AXES];
|
||||
signed char *axis;
|
||||
} gamepad;
|
||||
|
||||
void gamepad_init(void) {
|
||||
|
@ -51,6 +51,8 @@ void gamepad_init(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
gamepad.axis = malloc(SDL_JoystickNumAxes(gamepad.device));
|
||||
|
||||
printf("gamepad_init(): using device #%i: %s\n", dev, gamepad_devicename(dev));
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
gamepad.initialized = 1;
|
||||
|
@ -66,6 +68,9 @@ void gamepad_shutdown(void) {
|
|||
if(gamepad.device)
|
||||
SDL_JoystickClose(gamepad.device);
|
||||
|
||||
free(gamepad.axis);
|
||||
gamepad.axis = NULL;
|
||||
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
gamepad.initialized = 0;
|
||||
|
@ -125,17 +130,13 @@ float gamepad_axis_sens(int id) {
|
|||
}
|
||||
|
||||
void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void *arg) {
|
||||
int *a = gamepad.axis;
|
||||
int val = AXISVAL(raw);
|
||||
int free = config_get_int(CONFIG_GAMEPAD_AXIS_FREE);
|
||||
signed char *a = gamepad.axis;
|
||||
signed char val = AXISVAL(raw);
|
||||
bool free = config_get_int(CONFIG_GAMEPAD_AXIS_FREE);
|
||||
|
||||
int menu = flags & EF_Menu;
|
||||
int game = flags & EF_Game;
|
||||
|
||||
if(id >= GAMEPAD_AXES) {
|
||||
warnx("gamepad_axis(): axis %i is out of range (%i axes supported)", id, GAMEPAD_AXES);
|
||||
return;
|
||||
}
|
||||
bool menu = flags & EF_Menu;
|
||||
bool game = flags & EF_Game;
|
||||
bool gp = flags & EF_Gamepad;
|
||||
|
||||
//printf("axis: %i %i %i\n", id, val, raw);
|
||||
|
||||
|
@ -145,12 +146,12 @@ void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void
|
|||
double sens = gamepad_axis_sens(id);
|
||||
int sens_sign = SIGN(sens);
|
||||
|
||||
double x = raw / (double)GAMEPAD_AXIS_RANGE;
|
||||
double x = raw / (double)GAMEPAD_AXIS_MAX;
|
||||
int in_sign = SIGN(x);
|
||||
|
||||
x = pow(fabs(x), 1.0 / fabs(sens)) * in_sign * sens_sign;
|
||||
x = x ? x : 0;
|
||||
x = clamp(x * GAMEPAD_AXIS_RANGE, -GAMEPAD_AXIS_RANGE-1, GAMEPAD_AXIS_RANGE);
|
||||
x = clamp(x * GAMEPAD_AXIS_MAX, GAMEPAD_AXIS_MIN, GAMEPAD_AXIS_MAX);
|
||||
|
||||
handler(evt, x, arg);
|
||||
}
|
||||
|
@ -179,6 +180,12 @@ void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void
|
|||
}
|
||||
a[id] = AXISVAL_NULL;
|
||||
}
|
||||
|
||||
if(gp) {
|
||||
// we probably need a better way to pass more than an int to the handler...
|
||||
handler(E_GamepadAxis, id, arg);
|
||||
handler(E_GamepadAxisValue, raw, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void gamepad_button(int button, int state, EventHandler handler, EventFlags flags, void *arg) {
|
||||
|
@ -227,7 +234,7 @@ void gamepad_event(SDL_Event *event, EventHandler handler, EventFlags flags, voi
|
|||
return;
|
||||
|
||||
int val;
|
||||
int sens = clamp(config_get_float(CONFIG_GAMEPAD_AXIS_DEADZONE), 0, 1) * GAMEPAD_AXIS_RANGE;
|
||||
int sens = clamp(config_get_float(CONFIG_GAMEPAD_AXIS_DEADZONE), 0, 1) * GAMEPAD_AXIS_MAX;
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
|
|
|
@ -41,8 +41,8 @@ enum {
|
|||
AXISVAL_NULL = 0
|
||||
};
|
||||
|
||||
#define GAMEPAD_AXES 8
|
||||
#define GAMEPAD_AXIS_RANGE 32767
|
||||
#define GAMEPAD_AXIS_MAX 32767
|
||||
#define GAMEPAD_AXIS_MIN -32768
|
||||
#define AXISVAL SIGN
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,6 +77,16 @@ OptionBinding* bind_gpbinding(int cfgentry) {
|
|||
return bind;
|
||||
}
|
||||
|
||||
// BT_GamepadAxisBinding: gamepad axis mapping options
|
||||
OptionBinding* bind_gpaxisbinding(int cfgentry) {
|
||||
OptionBinding *bind = bind_new();
|
||||
|
||||
bind->configentry = cfgentry;
|
||||
bind->type = BT_GamepadAxisBinding;
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
// BT_StrValue: with a half-assed "textbox"
|
||||
OptionBinding* bind_stroption(ConfigIndex cfgentry) {
|
||||
OptionBinding *bind = bind_new();
|
||||
|
@ -442,27 +452,27 @@ void options_sub_gamepad(MenuData *parent, void *arg) {
|
|||
|
||||
add_menu_separator(m);
|
||||
|
||||
add_menu_entry(m, "UD axis (Vertical)", do_nothing,
|
||||
b = bind_option(CONFIG_GAMEPAD_AXIS_UD, bind_common_intget, bind_common_intset)
|
||||
); bind_setvaluerange_fancy(b, GAMEPAD_AXES-1);
|
||||
add_menu_entry(m, "X axis", do_nothing,
|
||||
b = bind_gpaxisbinding(CONFIG_GAMEPAD_AXIS_LR)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "LR axis (Horizontal)", do_nothing,
|
||||
b = bind_option(CONFIG_GAMEPAD_AXIS_LR, bind_common_intget, bind_common_intset)
|
||||
); bind_setvaluerange_fancy(b, GAMEPAD_AXES-1);
|
||||
add_menu_entry(m, "Y axis", do_nothing,
|
||||
b = bind_gpaxisbinding(CONFIG_GAMEPAD_AXIS_UD)
|
||||
);
|
||||
|
||||
add_menu_entry(m, "Axes mode", do_nothing,
|
||||
b = bind_option(CONFIG_GAMEPAD_AXIS_FREE, bind_common_onoffget, bind_common_onoffset)
|
||||
); bind_addvalue(b, "free");
|
||||
bind_addvalue(b, "restricted");
|
||||
|
||||
add_menu_entry(m, "UD axis sensitivity", do_nothing,
|
||||
b = bind_scale(CONFIG_GAMEPAD_AXIS_UD_SENS, -2, 2, 0.05)
|
||||
); bind_setdependence(b, gamepad_sens_depencence);
|
||||
|
||||
add_menu_entry(m, "LR axis sensitivity", do_nothing,
|
||||
add_menu_entry(m, "X axis sensitivity", do_nothing,
|
||||
b = bind_scale(CONFIG_GAMEPAD_AXIS_LR_SENS, -2, 2, 0.05)
|
||||
); bind_setdependence(b, gamepad_sens_depencence);
|
||||
|
||||
add_menu_entry(m, "Y axis sensitivity", do_nothing,
|
||||
b = bind_scale(CONFIG_GAMEPAD_AXIS_UD_SENS, -2, 2, 0.05)
|
||||
); bind_setdependence(b, gamepad_sens_depencence);
|
||||
|
||||
add_menu_entry(m, "Dead zone", do_nothing,
|
||||
b = bind_scale(CONFIG_GAMEPAD_AXIS_DEADZONE, 0, 1, 0.01)
|
||||
);
|
||||
|
@ -694,13 +704,19 @@ void draw_options_menu(MenuData *menu) {
|
|||
break;
|
||||
}
|
||||
|
||||
case BT_GamepadKeyBinding: {
|
||||
case BT_GamepadKeyBinding:
|
||||
case BT_GamepadAxisBinding: {
|
||||
bool is_axis = (bind->type == BT_GamepadAxisBinding);
|
||||
|
||||
if(bind->blockinput) {
|
||||
glColor4f(0.5, 1, 0.5, 1);
|
||||
draw_text(AL_Right, origin, 20*i, "Press a button to assign, ESC to cancel", _fonts.standard);
|
||||
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",
|
||||
_fonts.standard);
|
||||
} else if(config_get_int(bind->configentry) >= 0) {
|
||||
char tmp[32];
|
||||
snprintf(tmp, 32, "Button %i", config_get_int(bind->configentry) + 1);
|
||||
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);
|
||||
} else {
|
||||
draw_text(AL_Right, origin, 20*i, "Unbound", _fonts.standard);
|
||||
|
@ -787,7 +803,7 @@ void bind_input_event(EventType type, int state, void *arg) {
|
|||
switch(type) {
|
||||
case E_KeyDown: {
|
||||
int esc = scan == SDL_SCANCODE_ESCAPE;
|
||||
if(b->type == BT_GamepadKeyBinding) {
|
||||
if(b->type == BT_GamepadKeyBinding || b->type == BT_GamepadAxisBinding) {
|
||||
if(esc)
|
||||
b->blockinput = false;
|
||||
break;
|
||||
|
@ -808,6 +824,12 @@ void bind_input_event(EventType type, int state, void *arg) {
|
|||
}
|
||||
|
||||
case E_GamepadKeyDown: {
|
||||
if(b->type != BT_GamepadKeyBinding) {
|
||||
if(b->type == BT_GamepadAxisBinding)
|
||||
b->blockinput = false;
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = CONFIG_GAMEPAD_KEY_FIRST; i <= CONFIG_GAMEPAD_KEY_LAST; ++i) {
|
||||
if(config_get_int(i) == scan) {
|
||||
config_set_int(i, config_get_int(b->configentry));
|
||||
|
@ -819,6 +841,30 @@ void bind_input_event(EventType type, int state, void *arg) {
|
|||
break;
|
||||
}
|
||||
|
||||
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) {
|
||||
config_set_int(CONFIG_GAMEPAD_AXIS_LR, config_get_int(CONFIG_GAMEPAD_AXIS_UD));
|
||||
}
|
||||
} else if(b->configentry == CONFIG_GAMEPAD_AXIS_LR) {
|
||||
if(config_get_int(CONFIG_GAMEPAD_AXIS_UD) == state) {
|
||||
config_set_int(CONFIG_GAMEPAD_AXIS_UD, config_get_int(CONFIG_GAMEPAD_AXIS_LR));
|
||||
}
|
||||
}
|
||||
|
||||
config_set_int(b->configentry, state);
|
||||
b->blockinput = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case E_CharTyped: {
|
||||
if(c != ':') {
|
||||
char s[] = {c, 0};
|
||||
|
@ -907,7 +953,9 @@ static void options_input_event(EventType type, int state, void *arg) {
|
|||
menu->selected = menu->cursor;
|
||||
|
||||
if(bind) switch(bind->type) {
|
||||
case BT_KeyBinding: case BT_GamepadKeyBinding:
|
||||
case BT_KeyBinding:
|
||||
case BT_GamepadKeyBinding:
|
||||
case BT_GamepadAxisBinding:
|
||||
bind->blockinput = true;
|
||||
break;
|
||||
|
||||
|
@ -944,6 +992,7 @@ void options_menu_input(MenuData *menu) {
|
|||
case BT_StrValue: flags = EF_Text; break;
|
||||
case BT_KeyBinding: flags = EF_Keyboard; break;
|
||||
case BT_GamepadKeyBinding: flags = EF_Gamepad | EF_Keyboard; break;
|
||||
case BT_GamepadAxisBinding: flags = EF_Gamepad | EF_Keyboard; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ typedef enum BindingType {
|
|||
BT_StrValue,
|
||||
BT_Resolution,
|
||||
BT_Scale,
|
||||
BT_GamepadKeyBinding
|
||||
BT_GamepadKeyBinding,
|
||||
BT_GamepadAxisBinding,
|
||||
} BindingType;
|
||||
|
||||
typedef struct OptionBinding {
|
||||
|
|
|
@ -339,7 +339,7 @@ bool player_applymovement_gamepad(Player *plr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
complex direction = (plr->axis_lr + plr->axis_ud*I) / (double)GAMEPAD_AXIS_RANGE;
|
||||
complex direction = (plr->axis_lr + plr->axis_ud*I) / (double)GAMEPAD_AXIS_MAX;
|
||||
if(cabs(direction) > 1)
|
||||
direction /= cabs(direction);
|
||||
|
||||
|
|
Loading…
Reference in a new issue