Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add and improve methods to get the name of gamepad inputs #89193

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 232 additions & 8 deletions core/input/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,138 @@ static const char *_joy_axes[(size_t)JoyAxis::SDL_MAX] = {
"righttrigger",
};

static const char *_joy_button_names_unknown[(size_t)JoyButton::SDL_MAX] = {
"Bottom Action",
"Right Action",
"Left Action",
"Top Action",
"Select",
"Guide",
"Start",
"Left Stick",
"Right Stick",
"Left Shoulder",
"Right Shoulder",
"D-pad Up",
"D-pad Down",
"D-pad Left",
"D-pad Right",
"Misc",
"Paddle 1",
"Paddle 2",
"Paddle 3",
"Paddle 4",
"Touchpad",
};

static const char *_joy_button_names_nintendo_generic[(size_t)JoyButton::SDL_MAX] = {
"B",
"A",
"Y",
"X",
"-",
"",
"+",
"",
"",
"L",
"R",
"",
"",
"",
"",
"Capture",
"",
"",
"",
"",
"",
};

static const char *_joy_button_names_playstation_generic[(size_t)JoyButton::SDL_MAX] = {
"Cross",
"Circle",
"Square",
"Triangle",
"Select",
"PS",
"",
"L3",
"R3",
"L1",
"R1",
"",
"",
"",
"",
"Microphone",
"",
"",
"",
"",
"",
};

static const char *_joy_button_names_xbox_generic[(size_t)JoyButton::SDL_MAX] = {
"A",
"B",
"X",
"Y",
"Back",
"Home",
"Menu",
"L/LS",
"R/RS",
"LB",
"RB",
"",
"",
"",
"",
"Share",
"",
"",
"",
"",
"",
};

static const char *_joy_axis_names_unknown[(size_t)JoyAxis::SDL_MAX] = {
"Left Stick X-Axis",
"Left Stick Y-Axis",
"Right Stick X-Axis",
"Right Stick Y-Axis",
"Left Trigger",
"Right Trigger",
YeldhamDev marked this conversation as resolved.
Show resolved Hide resolved
};

static const char *_joy_axis_names_nintendo_generic[(size_t)JoyAxis::SDL_MAX] = {
"",
"",
"",
"",
"ZL",
"ZR",
};

static const char *_joy_axis_names_playstation_generic[(size_t)JoyAxis::SDL_MAX] = {
"",
"",
"",
"",
"L2",
"R2",
};

static const char *_joy_axis_names_xbox_generic[(size_t)JoyAxis::SDL_MAX] = {
"",
"",
"",
"",
"LT",
"RT",
};

Input *Input::singleton = nullptr;

void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
Expand Down Expand Up @@ -112,12 +244,15 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
ClassDB::bind_method(D_METHOD("get_joy_scheme", "device"), &Input::get_joy_scheme);
ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid);
ClassDB::bind_method(D_METHOD("get_joy_info", "device"), &Input::get_joy_info);
ClassDB::bind_method(D_METHOD("should_ignore_device", "vendor_id", "product_id"), &Input::should_ignore_device);
ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
ClassDB::bind_method(D_METHOD("get_joy_button_string", "button", "scheme"), &Input::get_joy_button_string, DEFVAL(JoyScheme::JOY_SCHEME_UNKNOWN));
ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis", "value", "scheme"), &Input::get_joy_axis_string, DEFVAL(0), DEFVAL(JoyScheme::JOY_SCHEME_UNKNOWN));
ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
Expand Down Expand Up @@ -178,6 +313,11 @@ void Input::_bind_methods() {
BIND_ENUM_CONSTANT(CURSOR_HSPLIT);
BIND_ENUM_CONSTANT(CURSOR_HELP);

BIND_ENUM_CONSTANT(JOY_SCHEME_UNKNOWN);
BIND_ENUM_CONSTANT(JOY_SCHEME_NINTENDO_GENERIC);
BIND_ENUM_CONSTANT(JOY_SCHEME_PLAYSTATION_GENERIC);
BIND_ENUM_CONSTANT(JOY_SCHEME_XBOX_GENERIC);

ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected")));
}

Expand Down Expand Up @@ -417,9 +557,26 @@ float Input::get_joy_axis(int p_device, JoyAxis p_axis) const {
}
}

String Input::get_joy_name(int p_idx) {
String Input::get_joy_name(int p_device) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx].name;
return joy_names[p_device].name;
}

Input::JoyScheme Input::get_joy_scheme(int p_device) {
String joy_name = get_joy_name(p_device).to_lower();

if (joy_name.contains("nintendo") || joy_name.contains("joy-con") || joy_name.contains("gamecube")) {
return JOY_SCHEME_NINTENDO_GENERIC;
}
if (joy_name.contains("sony") || joy_name.contains("playstation") || joy_name.contains("dualshock") ||
joy_name.contains("ps1") || joy_name.contains("ps2") || joy_name.contains("ps3") || joy_name.contains("ps4") || joy_name.contains("ps5")) {
YeldhamDev marked this conversation as resolved.
Show resolved Hide resolved
return JOY_SCHEME_PLAYSTATION_GENERIC;
}
if (joy_name.contains("microsoft") || joy_name.contains("xbox")) {
return JOY_SCHEME_XBOX_GENERIC;
}

return JOY_SCHEME_UNKNOWN;
}

Vector2 Input::get_joy_vibration_strength(int p_device) {
Expand All @@ -446,6 +603,73 @@ float Input::get_joy_vibration_duration(int p_device) {
}
}

String Input::get_joy_button_string(JoyButton p_button, JoyScheme p_scheme) {
String button_name;
switch (p_scheme) {
case JOY_SCHEME_NINTENDO_GENERIC: {
button_name = _joy_button_names_nintendo_generic[(int)p_button];
} break;
case JOY_SCHEME_PLAYSTATION_GENERIC: {
button_name = _joy_button_names_playstation_generic[(int)p_button];
} break;
case JOY_SCHEME_XBOX_GENERIC: {
button_name = _joy_button_names_xbox_generic[(int)p_button];
} break;
default: {
}
}

if (button_name.is_empty()) {
button_name = _joy_button_names_unknown[(int)p_button];
}

return button_name;
}

String Input::get_joy_axis_string(JoyAxis p_axis, float p_value, JoyScheme p_scheme) {
if (p_axis == JoyAxis::TRIGGER_LEFT || p_axis == JoyAxis::TRIGGER_RIGHT) {
String axis_name;
switch (p_scheme) {
case JOY_SCHEME_NINTENDO_GENERIC: {
axis_name = _joy_axis_names_nintendo_generic[(int)p_axis];
} break;
case JOY_SCHEME_PLAYSTATION_GENERIC: {
axis_name = _joy_axis_names_playstation_generic[(int)p_axis];
} break;
case JOY_SCHEME_XBOX_GENERIC: {
axis_name = _joy_axis_names_xbox_generic[(int)p_axis];
} break;
default: {
}
}

if (axis_name.is_empty()) {
axis_name = _joy_axis_names_unknown[(int)p_axis];
}

return axis_name;
}

if (p_value != 0.0) {
String stick;
if (p_axis == JoyAxis::LEFT_X || p_axis == JoyAxis::LEFT_Y) {
stick = "Left Stick ";
} else if (p_axis == JoyAxis::RIGHT_X || p_axis == JoyAxis::RIGHT_Y) {
stick = "Right Stick ";
}

if (p_axis == JoyAxis::LEFT_X || p_axis == JoyAxis::RIGHT_X) {
stick += p_value < 0 ? "Left" : "Right";
} else if (p_axis == JoyAxis::LEFT_Y || p_axis == JoyAxis::RIGHT_Y) {
stick += p_value < 0 ? "Up" : "Down";
}

return stick;
}

return _joy_axis_names_unknown[(int)p_axis];
}

static String _hex_str(uint8_t p_byte) {
static const char *dict = "0123456789abcdef";
char ret[3];
Expand All @@ -457,13 +681,13 @@ static String _hex_str(uint8_t p_byte) {
return ret;
}

void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_name, const String &p_guid, const Dictionary &p_joypad_info) {
void Input::joy_connection_changed(int p_device, bool p_connected, const String &p_name, const String &p_guid, const Dictionary &p_joypad_info) {
_THREAD_SAFE_METHOD_

// Clear the pressed status if a Joypad gets disconnected.
if (!p_connected) {
for (KeyValue<StringName, ActionState> &E : action_states) {
HashMap<int, ActionState::DeviceState>::Iterator it = E.value.device_states.find(p_idx);
HashMap<int, ActionState::DeviceState>::Iterator it = E.value.device_states.find(p_device);
if (it) {
E.value.device_states.remove(it);
_update_action_cache(E.key, E.value);
Expand Down Expand Up @@ -497,17 +721,17 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
} else {
js.connected = false;
for (int i = 0; i < (int)JoyButton::MAX; i++) {
JoyButton c = _combine_device((JoyButton)i, p_idx);
JoyButton c = _combine_device((JoyButton)i, p_device);
joy_buttons_pressed.erase(c);
}
for (int i = 0; i < (int)JoyAxis::MAX; i++) {
set_joy_axis(p_idx, (JoyAxis)i, 0.0f);
set_joy_axis(p_device, (JoyAxis)i, 0.0f);
}
}
joy_names[p_idx] = js;
joy_names[p_device] = js;

// Ensure this signal is emitted on the main thread, as some platforms (e.g. Linux) call this from a different thread.
call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected);
call_deferred("emit_signal", SNAME("joy_connection_changed"), p_device, p_connected);
}

Vector3 Input::get_gravity() const {
Expand Down
18 changes: 15 additions & 3 deletions core/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#ifndef INPUT_H
#define INPUT_H

#include "core/input/input_enums.h"
#include "core/input/input_event.h"
#include "core/object/object.h"
#include "core/os/keyboard.h"
Expand Down Expand Up @@ -74,7 +75,14 @@ class Input : public Object {
CURSOR_VSPLIT,
CURSOR_HSPLIT,
CURSOR_HELP,
CURSOR_MAX
CURSOR_MAX,
};

enum JoyScheme {
JOY_SCHEME_UNKNOWN,
JOY_SCHEME_NINTENDO_GENERIC,
JOY_SCHEME_PLAYSTATION_GENERIC,
JOY_SCHEME_XBOX_GENERIC,
};

enum {
Expand Down Expand Up @@ -293,12 +301,15 @@ class Input : public Object {
Vector2 get_vector(const StringName &p_negative_x, const StringName &p_positive_x, const StringName &p_negative_y, const StringName &p_positive_y, float p_deadzone = -1.0f) const;

float get_joy_axis(int p_device, JoyAxis p_axis) const;
String get_joy_name(int p_idx);
String get_joy_name(int p_device);
JoyScheme get_joy_scheme(int p_device);
TypedArray<int> get_connected_joypads();
Vector2 get_joy_vibration_strength(int p_device);
float get_joy_vibration_duration(int p_device);
uint64_t get_joy_vibration_timestamp(int p_device);
void joy_connection_changed(int p_idx, bool p_connected, const String &p_name, const String &p_guid = "", const Dictionary &p_joypad_info = Dictionary());
String get_joy_button_string(JoyButton p_button, JoyScheme p_scheme = JoyScheme::JOY_SCHEME_UNKNOWN);
String get_joy_axis_string(JoyAxis p_axis, float p_value = 0, JoyScheme p_scheme = JoyScheme::JOY_SCHEME_UNKNOWN);
void joy_connection_changed(int p_device, bool p_connected, const String &p_name, const String &p_guid = "", const Dictionary &p_joypad_info = Dictionary());

Vector3 get_gravity() const;
Vector3 get_accelerometer() const;
Expand Down Expand Up @@ -374,5 +385,6 @@ class Input : public Object {

VARIANT_ENUM_CAST(Input::MouseMode);
VARIANT_ENUM_CAST(Input::CursorShape);
VARIANT_ENUM_CAST(Input::JoyScheme);

#endif // INPUT_H
Loading
Loading