Skip to content
Permalink
Browse files

Merge branch 'Daivuk:axis_buttons' into master

Requested-by: Daivuk <#452>
  • Loading branch information...
vLKp committed Sep 1, 2019
2 parents 183f11c + 74ef8b0 commit d6b2ab51a7d5a43fa16c279eeb927450922361f4
Showing with 78 additions and 15 deletions.
  1. +1 −0 common/arch/sdl/event.cpp
  2. +70 −5 common/arch/sdl/joy.cpp
  3. +3 −0 common/include/joy.h
  4. +2 −2 common/main/kconfig.h
  5. +2 −8 similar/main/kconfig.cpp
@@ -90,6 +90,7 @@ window_event_result event_poll()
case SDL_JOYAXISMOTION:
if (CGameArg.CtlNoJoystick)
break;
highest_result = std::max(joy_axisbutton_handler(&event.jaxis), highest_result);
highest_result = std::max(joy_axis_handler(&event.jaxis), highest_result);
break;
case SDL_JOYHATMOTION:
@@ -129,6 +129,7 @@ class d_physical_joystick
VERB(button_map) \
VERB(axis_map) \
VERB(axis_value) \
VERB(axis_button_map) \

#if DXX_USE_SIZE_SORTED_TUPLE
template <typename... Ts>
@@ -164,12 +165,14 @@ class d_physical_joystick
struct tuple_member_type_button_map : array<unsigned, DXX_MAX_BUTTONS_PER_JOYSTICK> {};
struct tuple_member_type_axis_map : array<unsigned, DXX_MAX_AXES_PER_JOYSTICK> {};
struct tuple_member_type_axis_value : array<int, DXX_MAX_AXES_PER_JOYSTICK> {};
struct tuple_member_type_axis_button_map : array<unsigned, DXX_MAX_AXES_PER_JOYSTICK> {};
tuple_type<
tuple_member_type_handle,
maybe_empty_array<tuple_member_type_hat_map>,
maybe_empty_array<tuple_member_type_button_map>,
maybe_empty_array<tuple_member_type_axis_map>,
maybe_empty_array<tuple_member_type_axis_value>
maybe_empty_array<tuple_member_type_axis_value>,
maybe_empty_array<tuple_member_type_axis_button_map>
> t;
public:
for_each_tuple_item(define_handle_getter, define_array_getter);
@@ -247,6 +250,46 @@ window_event_result joy_hat_handler(SDL_JoyHatEvent *jhe)
#endif

#if DXX_MAX_AXES_PER_JOYSTICK
static window_event_result send_axis_button_event(unsigned button, event_type e)
{
Joystick.button_state[button] = (e == EVENT_JOYSTICK_BUTTON_UP) ? 0 : 1;
const d_event_joystickbutton event{ e, button };
con_printf(CON_DEBUG, "Sending event %s, button %d", (e == EVENT_JOYSTICK_BUTTON_UP) ? "EVENT_JOYSTICK_BUTTON_UP" : "EVENT_JOYSTICK_BUTTON_DOWN", event.button);
return event_send(event);
}

window_event_result joy_axisbutton_handler(SDL_JoyAxisEvent *jae)
{
auto &js = SDL_Joysticks[jae->which];
auto axis_value = js.axis_value()[jae->axis];
auto button = js.axis_button_map()[jae->axis];
window_event_result highest_result(window_event_result::ignored);

// We have to hardcode a deadzone here. It's not mapped into the settings.
// We could add another deadzone slider called "axis button deadzone".
// I think it's safe to assume a 30% deadzone on analog button presses for now.
const decltype(axis_value) deadzone = 38;
auto prev_value = apply_deadzone(axis_value, deadzone);
auto new_value = apply_deadzone(jae->value/256, deadzone);

if (prev_value <= 0 && new_value >= 0) // positive pressed
{
if (prev_value < 0) // Do previous direction release first if the case
highest_result = std::max(send_axis_button_event(button + 1, EVENT_JOYSTICK_BUTTON_UP), highest_result);
if (new_value > 0)
highest_result = std::max(send_axis_button_event(button, EVENT_JOYSTICK_BUTTON_DOWN), highest_result);
}
else if (prev_value >= 0 && new_value <= 0) // negative pressed
{
if (prev_value > 0) // Do previous direction release first if the case
highest_result = std::max(send_axis_button_event(button, EVENT_JOYSTICK_BUTTON_UP), highest_result);
if (new_value < 0)
highest_result = std::max(send_axis_button_event(button + 1, EVENT_JOYSTICK_BUTTON_DOWN), highest_result);
}

return highest_result;
}

window_event_result joy_axis_handler(SDL_JoyAxisEvent *jae)
{
auto &js = SDL_Joysticks[jae->which];
@@ -290,7 +333,7 @@ void joy_init()
#if DXX_MAX_AXES_PER_JOYSTICK
joyaxis_text.clear();
#endif
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK || DXX_MAX_AXES_PER_JOYSTICK
joybutton_text.clear();
#endif

@@ -320,13 +363,15 @@ void joy_init()
e.value = joystick_n_axes++;
snprintf(&text[0], sizeof(text), "J%d A%u", i + 1, e.idx);
}
#else
const auto n_axes = 0;
#endif

#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK || DXX_MAX_AXES_PER_JOYSTICK
const auto n_buttons = check_warn_joy_support_limit(SDL_JoystickNumButtons(handle), "button", DXX_MAX_BUTTONS_PER_JOYSTICK);
const auto n_hats = check_warn_joy_support_limit(SDL_JoystickNumHats(handle), "hat", DXX_MAX_HATS_PER_JOYSTICK);

joybutton_text.resize(joybutton_text.size() + n_buttons + (4 * n_hats));
joybutton_text.resize(joybutton_text.size() + n_buttons + (4 * n_hats) + (2 * n_axes));
#if DXX_MAX_BUTTONS_PER_JOYSTICK
range_for (auto &&e, enumerate(partial_range(joystick.button_map(), n_buttons), 1))
{
@@ -348,6 +393,16 @@ void joy_init()
snprintf(&joybutton_text[joystick_n_buttons++][0], sizeof(joybutton_text[0]), "J%u H%u%c", i + 1, e.idx, 0201);
}
#endif
#if DXX_MAX_AXES_PER_JOYSTICK
range_for (auto &&e, enumerate(partial_range(joystick.axis_button_map(), n_axes), 1))
{
e.value = joystick_n_buttons;
cf_assert(e.idx <= DXX_MAX_AXES_PER_JOYSTICK);
//an axis count as 2 buttons. negative - and positive +
snprintf(&joybutton_text[joystick_n_buttons++][0], sizeof(joybutton_text[0]), "J%u -A%u", i + 1, e.idx);
snprintf(&joybutton_text[joystick_n_buttons++][0], sizeof(joybutton_text[0]), "J%u +A%u", i + 1, e.idx);
}
#endif
#endif

num_joysticks++;
@@ -367,7 +422,7 @@ void joy_close()
#if DXX_MAX_AXES_PER_JOYSTICK
joyaxis_text.clear();
#endif
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK || DXX_MAX_AXES_PER_JOYSTICK
joybutton_text.clear();
#endif
}
@@ -401,5 +456,15 @@ int event_joystick_get_button(const d_event &event)
return e.button;
}

int apply_deadzone(int value, int deadzone)
{
if (value > deadzone)
return ((value - deadzone) * 128) / (128 - deadzone);
else if (value < -deadzone)
return ((value + deadzone) * 128) / (128 - deadzone);
else
return 0;
}

}
#endif
@@ -37,6 +37,7 @@ extern void joy_close();
const d_event_joystick_axis_value &event_joystick_get_axis(const d_event &event);
extern void joy_flush();
extern int event_joystick_get_button(const d_event &event);
extern int apply_deadzone(int value, int deadzone);

}
#else
@@ -60,9 +61,11 @@ extern window_event_result joy_hat_handler(SDL_JoyHatEvent *jhe);
#endif

#if DXX_MAX_AXES_PER_JOYSTICK
extern window_event_result joy_axisbutton_handler(SDL_JoyAxisEvent *jae);
extern window_event_result joy_axis_handler(SDL_JoyAxisEvent *jae);
#else
#define joy_axis_handler(jbe) (static_cast<SDL_JoyAxisEvent *const &>(jbe), window_event_result::ignored)
#define joy_axisbutton_handler(jbe) (static_cast<SDL_JoyAxisEvent *const &>(jbe), window_event_result::ignored)
#endif

}
@@ -169,9 +169,9 @@ using joyaxis_text_t = joystick_text_t<sizeof("J A") + joystick_text_length<DXX_
extern joyaxis_text_t joyaxis_text;
#endif

#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK || DXX_MAX_AXES_PER_JOYSTICK
#define DXX_JOY_MAX(A,B) ((A) < (B) ? (B) : (A))
using joybutton_text_t = joystick_text_t<joystick_text_length<DXX_MAX_JOYSTICKS>::value + DXX_JOY_MAX(sizeof("J H ") + joystick_text_length<DXX_MAX_HATS_PER_JOYSTICK>::value, sizeof("J B") + joystick_text_length<DXX_MAX_BUTTONS_PER_JOYSTICK>::value)>;
using joybutton_text_t = joystick_text_t<joystick_text_length<DXX_MAX_JOYSTICKS>::value + DXX_JOY_MAX(DXX_JOY_MAX(sizeof("J H ") + joystick_text_length<DXX_MAX_HATS_PER_JOYSTICK>::value, sizeof("J B") + joystick_text_length<DXX_MAX_BUTTONS_PER_JOYSTICK>::value), sizeof("J -A") + joystick_text_length<DXX_MAX_AXES_PER_JOYSTICK>::value)>;
#undef DXX_JOY_MAX
extern joybutton_text_t joybutton_text;
#endif
@@ -1114,7 +1114,7 @@ void kconfig_read_controls(const d_event &event, int automap_flag)
}
}
break;
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
#if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK || DXX_MAX_AXES_PER_JOYSTICK
case EVENT_JOYSTICK_BUTTON_DOWN:
case EVENT_JOYSTICK_BUTTON_UP:
if (!(PlayerCfg.ControlType & CONTROL_USING_JOYSTICK))
@@ -1189,13 +1189,7 @@ void kconfig_read_controls(const d_event &event, int automap_flag)
else if (axis == PlayerCfg.KeySettings.Joystick[dxx_kconfig_ui_kc_joystick_throttle]) // Throttle - default deadzone
joy_null_value = PlayerCfg.JoystickDead[5]*3;

if (value > joy_null_value)
value = ((value - joy_null_value) * 128) / (128 - joy_null_value);
else if (value < -joy_null_value)
value = ((value + joy_null_value) * 128) / (128 - joy_null_value);
else
value = 0;
Controls.raw_joy_axis[axis] = value;
Controls.raw_joy_axis[axis] = apply_deadzone(value, joy_null_value);
break;
}
#endif

0 comments on commit d6b2ab5

Please sign in to comment.
You can’t perform that action at this time.