Skip to content

Commit 9940d41

Browse files
Nintorchbruvzg
andcommitted
Add support for new SDL joypad features (WIP)
This commit adds support for new SDL joypad features that weren't previously possible due to older custom joypad implementations. These features include accelerometer, gyroscope, LED lights, touchpads and more. Co-Authored-By: bruvzg <[email protected]>
1 parent 0564019 commit 9940d41

File tree

11 files changed

+924
-10
lines changed

11 files changed

+924
-10
lines changed

core/core_constants.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,16 @@ void register_global_constants() {
527527
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON1);
528528
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON2);
529529

530+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, INVALID);
531+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_X);
532+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_Y);
533+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_X);
534+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_Y);
535+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_LEFT);
536+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_RIGHT);
537+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, SDL_MAX);
538+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, MAX);
539+
530540
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, INVALID);
531541
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, A);
532542
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, B);
@@ -552,15 +562,22 @@ void register_global_constants() {
552562
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, SDL_MAX);
553563
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, MAX);
554564

555-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, INVALID);
556-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_X);
557-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_Y);
558-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_X);
559-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_Y);
560-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_LEFT);
561-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_RIGHT);
562-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, SDL_MAX);
563-
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, MAX);
565+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, UNKNOWN);
566+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, STANDARD);
567+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, XBOX360);
568+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, XBOXONE);
569+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS3);
570+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS4);
571+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS5);
572+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, NSPRO);
573+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_LEFT);
574+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_RIGHT);
575+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_PAIR);
576+
577+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, UNKNOWN);
578+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, XBOX);
579+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, PLAYSTATION);
580+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, NINTENDO);
564581

565582
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NONE);
566583
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_OFF);

core/input/input.cpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include "core/os/thread.h"
4141
#endif
4242

43+
#include "drivers/sdl/joypad_sdl.h"
44+
4345
static const char *_joy_buttons[(size_t)JoyButton::SDL_MAX] = {
4446
"a",
4547
"b",
@@ -145,10 +147,24 @@ void Input::_bind_methods() {
145147
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
146148
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
147149
ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
150+
ClassDB::bind_method(D_METHOD("get_joy_accelerometer_enabled", "device"), &Input::get_joy_accelerometer_enabled);
151+
ClassDB::bind_method(D_METHOD("get_joy_gyroscope_enabled", "device"), &Input::get_joy_gyroscope_enabled);
152+
ClassDB::bind_method(D_METHOD("get_joy_accelerometer", "device"), &Input::get_joy_accelerometer);
153+
ClassDB::bind_method(D_METHOD("get_joy_gyroscope", "device"), &Input::get_joy_gyroscope);
154+
ClassDB::bind_method(D_METHOD("get_joy_model", "device"), &Input::get_joy_model);
155+
ClassDB::bind_method(D_METHOD("get_joy_scheme", "device"), &Input::get_joy_scheme);
156+
ClassDB::bind_method(D_METHOD("get_joy_axis_string", "device", "axis"), &Input::get_joy_axis_string);
157+
ClassDB::bind_method(D_METHOD("get_joy_button_string", "device", "button"), &Input::get_joy_button_string);
148158
ClassDB::bind_method(D_METHOD("set_gravity", "value"), &Input::set_gravity);
149159
ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
150160
ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
151161
ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
162+
ClassDB::bind_method(D_METHOD("set_joy_light", "device", "color"), &Input::set_joy_light);
163+
ClassDB::bind_method(D_METHOD("set_joy_accelerometer_enabled", "device", "enable"), &Input::set_joy_accelerometer_enabled);
164+
ClassDB::bind_method(D_METHOD("set_joy_gyroscope_enabled", "device", "enable"), &Input::set_joy_gyroscope_enabled);
165+
ClassDB::bind_method(D_METHOD("has_joy_light", "device"), &Input::has_joy_light);
166+
ClassDB::bind_method(D_METHOD("has_joy_accelerometer", "device"), &Input::has_joy_accelerometer);
167+
ClassDB::bind_method(D_METHOD("has_joy_gyroscope", "device"), &Input::has_joy_gyroscope);
152168
ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
153169
ClassDB::bind_method(D_METHOD("get_last_mouse_screen_velocity"), &Input::get_last_mouse_screen_velocity);
154170
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
@@ -661,6 +677,48 @@ Vector3 Input::get_gyroscope() const {
661677
return gyroscope;
662678
}
663679

680+
bool Input::get_joy_accelerometer_enabled(int p_device) const {
681+
return JoypadSDL::get_singleton()->is_accelerometer_enabled(p_device);
682+
}
683+
684+
bool Input::get_joy_gyroscope_enabled(int p_device) const {
685+
return JoypadSDL::get_singleton()->is_gyroscope_enabled(p_device);
686+
}
687+
688+
Vector3 Input::get_joy_accelerometer(int p_device) const {
689+
_THREAD_SAFE_METHOD_
690+
if (joy_motion.has(p_device)) {
691+
return joy_motion[p_device].accelerometer;
692+
} else {
693+
return Vector3();
694+
}
695+
}
696+
697+
Vector3 Input::get_joy_gyroscope(int p_device) const {
698+
_THREAD_SAFE_METHOD_
699+
if (joy_motion.has(p_device)) {
700+
return joy_motion[p_device].gyroscope;
701+
} else {
702+
return Vector3();
703+
}
704+
}
705+
706+
JoyModel Input::get_joy_model(int p_device) const {
707+
return JoypadSDL::get_singleton()->get_model(p_device);
708+
}
709+
710+
JoyScheme Input::get_joy_scheme(int p_device) const {
711+
return JoypadSDL::get_singleton()->get_scheme(p_device);
712+
}
713+
714+
String Input::get_joy_axis_string(int p_device, JoyAxis p_axis) const {
715+
return JoypadSDL::get_singleton()->get_axis_string(p_device, p_axis);
716+
}
717+
718+
String Input::get_joy_button_string(int p_device, JoyButton p_button) const {
719+
return JoypadSDL::get_singleton()->get_button_string(p_device, p_button);
720+
}
721+
664722
void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
665723
// This function does the final delivery of the input event to user land.
666724
// Regardless where the event came from originally, this has to happen on the main thread.
@@ -914,6 +972,62 @@ void Input::set_joy_axis(int p_device, JoyAxis p_axis, float p_value) {
914972
_joy_axis[c] = p_value;
915973
}
916974

975+
bool Input::set_joy_light(int p_device, Color p_color) {
976+
return JoypadSDL::get_singleton()->set_light(p_device, p_color);
977+
}
978+
979+
bool Input::set_joy_accelerometer_enabled(int p_device, bool p_enable) {
980+
bool enabled = JoypadSDL::get_singleton()->enable_accelerometer(p_device, p_enable);
981+
if (enabled) {
982+
if (!joy_motion.has(p_device)) {
983+
joy_motion.insert(p_device, {});
984+
}
985+
joy_motion[p_device].accelerometer = Vector3();
986+
}
987+
return enabled;
988+
}
989+
990+
bool Input::set_joy_gyroscope_enabled(int p_device, bool p_enable) {
991+
bool enabled = JoypadSDL::get_singleton()->enable_gyroscope(p_device, p_enable);
992+
if (enabled) {
993+
if (!joy_motion.has(p_device)) {
994+
joy_motion.insert(p_device, {});
995+
}
996+
joy_motion[p_device].gyroscope = Vector3();
997+
}
998+
return enabled;
999+
}
1000+
1001+
void Input::set_joy_accelerometer(int p_device, const Vector3 &p_value) {
1002+
_THREAD_SAFE_METHOD_
1003+
if (!get_joy_accelerometer_enabled(p_device)) {
1004+
return;
1005+
}
1006+
1007+
joy_motion[p_device].accelerometer = p_value;
1008+
}
1009+
1010+
void Input::set_joy_gyroscope(int p_device, const Vector3 &p_value) {
1011+
_THREAD_SAFE_METHOD_
1012+
if (!get_joy_gyroscope_enabled(p_device)) {
1013+
return;
1014+
}
1015+
1016+
joy_motion[p_device].gyroscope = p_value;
1017+
}
1018+
1019+
bool Input::has_joy_light(int p_device) const {
1020+
return JoypadSDL::get_singleton()->has_light(p_device);
1021+
}
1022+
1023+
bool Input::has_joy_accelerometer(int p_device) const {
1024+
return JoypadSDL::get_singleton()->has_accelerometer(p_device);
1025+
}
1026+
1027+
bool Input::has_joy_gyroscope(int p_device) const {
1028+
return JoypadSDL::get_singleton()->has_gyroscope(p_device);
1029+
}
1030+
9171031
void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
9181032
_THREAD_SAFE_METHOD_
9191033
if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {

core/input/input.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ class Input : public Object {
146146

147147
HashMap<int, VibrationInfo> joy_vibration;
148148

149+
struct MotionInfo {
150+
Vector3 accelerometer;
151+
Vector3 gyroscope;
152+
};
153+
HashMap<int, MotionInfo> joy_motion;
154+
149155
struct VelocityTrack {
150156
uint64_t last_tick = 0;
151157
Vector2 velocity;
@@ -325,6 +331,18 @@ class Input : public Object {
325331
Vector3 get_magnetometer() const;
326332
Vector3 get_gyroscope() const;
327333

334+
bool get_joy_accelerometer_enabled(int p_device) const;
335+
bool get_joy_gyroscope_enabled(int p_device) const;
336+
337+
Vector3 get_joy_accelerometer(int p_device) const;
338+
Vector3 get_joy_gyroscope(int p_device) const;
339+
340+
JoyModel get_joy_model(int p_device) const;
341+
JoyScheme get_joy_scheme(int p_device) const;
342+
343+
String get_joy_axis_string(int p_device, JoyAxis p_axis) const;
344+
String get_joy_button_string(int p_device, JoyButton p_button) const;
345+
328346
Point2 get_mouse_position() const;
329347
Vector2 get_last_mouse_velocity();
330348
Vector2 get_last_mouse_screen_velocity();
@@ -341,6 +359,18 @@ class Input : public Object {
341359
void set_gyroscope(const Vector3 &p_gyroscope);
342360
void set_joy_axis(int p_device, JoyAxis p_axis, float p_value);
343361

362+
bool set_joy_light(int p_device, Color p_color);
363+
364+
bool set_joy_accelerometer_enabled(int p_device, bool p_enable);
365+
bool set_joy_gyroscope_enabled(int p_device, bool p_enable);
366+
367+
void set_joy_accelerometer(int p_device, const Vector3 &p_value);
368+
void set_joy_gyroscope(int p_device, const Vector3 &p_value);
369+
370+
bool has_joy_light(int p_device) const;
371+
bool has_joy_accelerometer(int p_device) const;
372+
bool has_joy_gyroscope(int p_device) const;
373+
344374
void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
345375
void stop_joy_vibration(int p_device);
346376
void vibrate_handheld(int p_duration_ms = 500, float p_amplitude = -1.0);

core/input/input_enums.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ enum class JoyButton {
104104
MAX = 128, // Android supports up to 36 buttons. DirectInput supports up to 128 buttons.
105105
};
106106

107+
// See SDL_GamepadType
108+
enum class JoyModel {
109+
UNKNOWN,
110+
STANDARD,
111+
XBOX360,
112+
XBOXONE,
113+
PS3,
114+
PS4,
115+
PS5,
116+
NSPRO,
117+
JOYCON_LEFT,
118+
JOYCON_RIGHT,
119+
JOYCON_PAIR,
120+
};
121+
122+
enum class JoyScheme {
123+
UNKNOWN,
124+
XBOX,
125+
PLAYSTATION,
126+
NINTENDO,
127+
};
128+
107129
enum class MIDIMessage {
108130
NONE = 0,
109131
NOTE_OFF = 0x8,

core/variant/binder_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ VARIANT_ENUM_CAST(HatDir);
104104
VARIANT_BITFIELD_CAST(HatMask);
105105
VARIANT_ENUM_CAST(JoyAxis);
106106
VARIANT_ENUM_CAST(JoyButton);
107+
VARIANT_ENUM_CAST(JoyModel);
108+
VARIANT_ENUM_CAST(JoyScheme);
107109

108110
VARIANT_ENUM_CAST(MIDIMessage);
109111
VARIANT_ENUM_CAST(MouseButton);

drivers/sdl/SCsub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ if env["builtin_sdl"]:
182182
"joystick/windows/SDL_windows_gaming_input.c",
183183
"joystick/windows/SDL_windowsjoystick.c",
184184
"joystick/windows/SDL_xinputjoystick.c",
185+
"sensor/windows/SDL_windowssensor.c",
185186
"thread/windows/SDL_syscond_cv.c",
186187
"thread/windows/SDL_sysmutex.c",
187188
"thread/windows/SDL_sysrwlock_srw.c",

drivers/sdl/SDL_build_config_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#define SDL_DIALOG_DISABLED 1
4848
#define SDL_FILESYSTEM_DUMMY 1
4949
#define SDL_FSOPS_DUMMY 1
50-
#define SDL_SENSOR_DISABLED 1
5150
#define SDL_GPU_DISABLED 1
5251
#define SDL_RENDER_DISABLED 1
5352
#define SDL_POWER_DISABLED 1
@@ -73,6 +72,7 @@
7372
#define SDL_THREAD_GENERIC_RWLOCK_SUFFIX 1
7473
#define SDL_THREAD_WINDOWS 1
7574
#define SDL_TIMER_WINDOWS 1
75+
#define SDL_SENSOR_WINDOWS 1
7676

7777
// Linux defines
7878
#elif defined(SDL_PLATFORM_LINUX)

0 commit comments

Comments
 (0)