Skip to content

Commit bad86bd

Browse files
committed
Add support for joypad LED lights
1 parent 36b9212 commit bad86bd

File tree

10 files changed

+906
-3
lines changed

10 files changed

+906
-3
lines changed

core/input/input.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,21 @@ void Input::_bind_methods() {
147147
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
148148
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
149149
ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
150+
ClassDB::bind_method(D_METHOD("is_joy_accelerometer_enabled", "device"), &Input::is_joy_accelerometer_enabled);
151+
ClassDB::bind_method(D_METHOD("is_joy_gyroscope_enabled", "device"), &Input::is_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_gravity", "device"), &Input::get_joy_gravity);
154+
ClassDB::bind_method(D_METHOD("get_joy_gyroscope", "device"), &Input::get_joy_gyroscope);
150155
ClassDB::bind_method(D_METHOD("set_gravity", "value"), &Input::set_gravity);
151156
ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
152157
ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
153158
ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
159+
ClassDB::bind_method(D_METHOD("set_joy_light", "device", "color"), &Input::set_joy_light);
160+
ClassDB::bind_method(D_METHOD("set_joy_accelerometer_enabled", "device", "enable"), &Input::set_joy_accelerometer_enabled);
161+
ClassDB::bind_method(D_METHOD("set_joy_gyroscope_enabled", "device", "enable"), &Input::set_joy_gyroscope_enabled);
162+
ClassDB::bind_method(D_METHOD("has_joy_light", "device"), &Input::has_joy_light);
163+
ClassDB::bind_method(D_METHOD("has_joy_accelerometer", "device"), &Input::has_joy_accelerometer);
164+
ClassDB::bind_method(D_METHOD("has_joy_gyroscope", "device"), &Input::has_joy_gyroscope);
154165
ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
155166
ClassDB::bind_method(D_METHOD("get_last_mouse_screen_velocity"), &Input::get_last_mouse_screen_velocity);
156167
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
@@ -731,6 +742,40 @@ Vector3 Input::get_gyroscope() const {
731742
return gyroscope;
732743
}
733744

745+
bool Input::is_joy_accelerometer_enabled(int p_device) const {
746+
_THREAD_SAFE_METHOD_
747+
return joy_motion.has(p_device) && joy_motion[p_device].accelerometer_enabled;
748+
}
749+
750+
bool Input::is_joy_gyroscope_enabled(int p_device) const {
751+
_THREAD_SAFE_METHOD_
752+
return joy_motion.has(p_device) && joy_motion[p_device].gyroscope_enabled;
753+
}
754+
755+
Vector3 Input::get_joy_accelerometer(int p_device) const {
756+
_THREAD_SAFE_METHOD_
757+
if (!joy_motion.has(p_device)) {
758+
return Vector3();
759+
}
760+
return joy_motion[p_device].accelerometer;
761+
}
762+
763+
Vector3 Input::get_joy_gravity(int p_device) const {
764+
_THREAD_SAFE_METHOD_
765+
if (!joy_motion.has(p_device)) {
766+
return Vector3();
767+
}
768+
return joy_motion[p_device].gravity;
769+
}
770+
771+
Vector3 Input::get_joy_gyroscope(int p_device) const {
772+
_THREAD_SAFE_METHOD_
773+
if (!joy_motion.has(p_device)) {
774+
return Vector3();
775+
}
776+
return joy_motion[p_device].gyroscope;
777+
}
778+
734779
void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
735780
// This function does the final delivery of the input event to user land.
736781
// Regardless where the event came from originally, this has to happen on the main thread.
@@ -986,6 +1031,81 @@ void Input::set_joy_axis(int p_device, JoyAxis p_axis, float p_value) {
9861031
_joy_axis[c] = p_value;
9871032
}
9881033

1034+
bool Input::set_joy_light(int p_device, Color p_color) {
1035+
if (!joy_names.has(p_device) || joy_names[p_device].features == nullptr) {
1036+
return false;
1037+
}
1038+
return joy_names[p_device].features->set_joy_light(p_color);
1039+
}
1040+
1041+
void Input::set_joy_features(int p_device, JoypadFeatures *p_features) {
1042+
if (!joy_names.has(p_device)) {
1043+
return;
1044+
}
1045+
joy_names[p_device].features = p_features;
1046+
_update_joypad_features(p_device);
1047+
}
1048+
1049+
bool Input::set_joy_accelerometer_enabled(int p_device, bool p_enable) {
1050+
_THREAD_SAFE_METHOD_
1051+
if (!joy_names.has(p_device) || joy_names[p_device].features == nullptr) {
1052+
return false;
1053+
}
1054+
bool enabled = joy_names[p_device].features->set_joy_accelerometer_enabled(p_enable);
1055+
joy_motion[p_device].accelerometer = Vector3();
1056+
joy_motion[p_device].accelerometer_enabled = enabled;
1057+
return enabled;
1058+
}
1059+
1060+
bool Input::set_joy_gyroscope_enabled(int p_device, bool p_enable) {
1061+
_THREAD_SAFE_METHOD_
1062+
if (!joy_names.has(p_device) || joy_names[p_device].features == nullptr) {
1063+
return false;
1064+
}
1065+
bool enabled = joy_names[p_device].features->set_joy_gyroscope_enabled(p_enable);
1066+
joy_motion[p_device].gyroscope = Vector3();
1067+
joy_motion[p_device].gyroscope_enabled = enabled;
1068+
return enabled;
1069+
}
1070+
1071+
void Input::set_joy_accelerometer(int p_device, const Vector3 &p_value) {
1072+
_THREAD_SAFE_METHOD_
1073+
if (!joy_motion.has(p_device)) {
1074+
return;
1075+
}
1076+
joy_motion[p_device].accelerometer = p_value;
1077+
}
1078+
1079+
void Input::set_joy_gravity(int p_device, const Vector3 &p_value) {
1080+
_THREAD_SAFE_METHOD_
1081+
if (!joy_motion.has(p_device)) {
1082+
return;
1083+
}
1084+
joy_motion[p_device].gravity = p_value;
1085+
}
1086+
1087+
void Input::set_joy_gyroscope(int p_device, const Vector3 &p_value) {
1088+
_THREAD_SAFE_METHOD_
1089+
if (!joy_motion.has(p_device)) {
1090+
return;
1091+
}
1092+
joy_motion[p_device].gyroscope = p_value;
1093+
}
1094+
1095+
bool Input::has_joy_light(int p_device) const {
1096+
return joy_names.has(p_device) && joy_names[p_device].has_light;
1097+
}
1098+
1099+
bool Input::has_joy_accelerometer(int p_device) const {
1100+
_THREAD_SAFE_METHOD_
1101+
return joy_motion.has(p_device) && joy_motion[p_device].has_accelerometer;
1102+
}
1103+
1104+
bool Input::has_joy_gyroscope(int p_device) const {
1105+
_THREAD_SAFE_METHOD_
1106+
return joy_motion.has(p_device) && joy_motion[p_device].has_gyroscope;
1107+
}
1108+
9891109
void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
9901110
_THREAD_SAFE_METHOD_
9911111
if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {
@@ -1478,6 +1598,21 @@ void Input::_update_action_cache(const StringName &p_action_name, ActionState &r
14781598
}
14791599
}
14801600

1601+
void Input::_update_joypad_features(int p_device) {
1602+
if (!joy_names.has(p_device) || joy_names[p_device].features == nullptr) {
1603+
return;
1604+
}
1605+
if (joy_names[p_device].features->has_joy_accelerometer()) {
1606+
joy_motion[p_device].has_accelerometer = true;
1607+
}
1608+
if (joy_names[p_device].features->has_joy_gyroscope()) {
1609+
joy_motion[p_device].has_gyroscope = true;
1610+
}
1611+
if (joy_names[p_device].features->has_joy_light()) {
1612+
joy_names[p_device].has_light = true;
1613+
}
1614+
}
1615+
14811616
Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button) {
14821617
JoyEvent event;
14831618

core/input/input.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ class Input : public Object {
7979
CURSOR_MAX
8080
};
8181

82+
class JoypadFeatures {
83+
public:
84+
virtual ~JoypadFeatures() {}
85+
86+
virtual bool has_joy_accelerometer() const { return false; }
87+
virtual bool has_joy_gyroscope() const { return false; }
88+
virtual bool has_joy_light() const { return false; }
89+
90+
virtual bool set_joy_accelerometer_enabled(bool p_enable) { return false; }
91+
virtual bool set_joy_gyroscope_enabled(bool p_enable) { return false; }
92+
virtual bool set_joy_light(Color p_color) { return false; }
93+
};
94+
8295
static constexpr int32_t JOYPADS_MAX = 16;
8396

8497
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
@@ -149,6 +162,18 @@ class Input : public Object {
149162

150163
HashMap<int, VibrationInfo> joy_vibration;
151164

165+
struct MotionInfo {
166+
bool has_accelerometer = false;
167+
bool has_gyroscope = false;
168+
bool accelerometer_enabled = false;
169+
bool gyroscope_enabled = false;
170+
Vector3 accelerometer;
171+
Vector3 gravity;
172+
Vector3 gyroscope;
173+
};
174+
175+
HashMap<int, MotionInfo> joy_motion;
176+
152177
struct VelocityTrack {
153178
uint64_t last_tick = 0;
154179
Vector2 velocity;
@@ -174,6 +199,8 @@ class Input : public Object {
174199
int mapping = -1;
175200
int hat_current = 0;
176201
Dictionary info;
202+
bool has_light = false;
203+
Input::JoypadFeatures *features;
177204
};
178205

179206
VelocityTrack mouse_velocity_track;
@@ -253,6 +280,7 @@ class Input : public Object {
253280
void _button_event(int p_device, JoyButton p_index, bool p_pressed);
254281
void _axis_event(int p_device, JoyAxis p_axis, float p_value);
255282
void _update_action_cache(const StringName &p_action_name, ActionState &r_action_state);
283+
void _update_joypad_features(int p_device);
256284

257285
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
258286

@@ -330,6 +358,13 @@ class Input : public Object {
330358
Vector3 get_magnetometer() const;
331359
Vector3 get_gyroscope() const;
332360

361+
bool is_joy_accelerometer_enabled(int p_device) const;
362+
bool is_joy_gyroscope_enabled(int p_device) const;
363+
364+
Vector3 get_joy_accelerometer(int p_device) const;
365+
Vector3 get_joy_gravity(int p_device) const;
366+
Vector3 get_joy_gyroscope(int p_device) const;
367+
333368
Point2 get_mouse_position() const;
334369
Vector2 get_last_mouse_velocity();
335370
Vector2 get_last_mouse_screen_velocity();
@@ -346,6 +381,21 @@ class Input : public Object {
346381
void set_gyroscope(const Vector3 &p_gyroscope);
347382
void set_joy_axis(int p_device, JoyAxis p_axis, float p_value);
348383

384+
bool set_joy_light(int p_device, Color p_color);
385+
386+
void set_joy_features(int p_device, JoypadFeatures *p_features);
387+
388+
bool set_joy_accelerometer_enabled(int p_device, bool p_enable);
389+
bool set_joy_gyroscope_enabled(int p_device, bool p_enable);
390+
391+
void set_joy_accelerometer(int p_device, const Vector3 &p_value);
392+
void set_joy_gravity(int p_device, const Vector3 &p_value);
393+
void set_joy_gyroscope(int p_device, const Vector3 &p_value);
394+
395+
bool has_joy_light(int p_device) const;
396+
bool has_joy_accelerometer(int p_device) const;
397+
bool has_joy_gyroscope(int p_device) const;
398+
349399
void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
350400
void stop_joy_vibration(int p_device);
351401
void vibrate_handheld(int p_duration_ms = 500, float p_amplitude = -1.0);

0 commit comments

Comments
 (0)