Skip to content

Commit b39eef9

Browse files
Nintorchbruvzg
andcommitted
Introduce new joypad features provided by SDL3
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 b39eef9

File tree

11 files changed

+1196
-12
lines changed

11 files changed

+1196
-12
lines changed

core/core_constants.cpp

Lines changed: 51 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,47 @@ 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, INVALID);
566+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, UNKNOWN);
567+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, STANDARD);
568+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, XBOX360);
569+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, XBOXONE);
570+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS3);
571+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS4);
572+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, PS5);
573+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, NSPRO);
574+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_LEFT);
575+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_RIGHT);
576+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyModel, JOY_MODEL, JOYCON_PAIR);
577+
578+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, INVALID);
579+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, UNKNOWN);
580+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, XBOX);
581+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, PLAYSTATION);
582+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyScheme, JOY_SCHEME, NINTENDO);
583+
584+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, INVALID);
585+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, UNKNOWN);
586+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, GAMEPAD);
587+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, WHEEL);
588+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, ARCADE_STICK);
589+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, FLIGHT_STICK);
590+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, DANCE_PAD);
591+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, GUITAR);
592+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, DRUM_KIT);
593+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, ARCADE_PAD);
594+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyDeviceType, JOY_DEVICE, THROTTLE);
595+
596+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyPowerState, JOY_POWER, INVALID);
597+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyPowerState, JOY_POWER, UNKNOWN);
598+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyPowerState, JOY_POWER, ON_BATTERY);
599+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyPowerState, JOY_POWER, NO_BATTERY);
600+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyPowerState, JOY_POWER, CHARGING);
601+
602+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyConnectionState, JOY_CONNECTION, INVALID);
603+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyConnectionState, JOY_CONNECTION, UNKNOWN);
604+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyConnectionState, JOY_CONNECTION, WIRED);
605+
BIND_CORE_ENUM_CLASS_CONSTANT(JoyConnectionState, JOY_CONNECTION, WIRELESS);
564606

565607
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NONE);
566608
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_OFF);

core/input/input.cpp

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

43+
#include "drivers/sdl/joypad_sdl.h"
44+
45+
#define JOY_CHECK_RETURN(m_value, m_default_value) \
46+
if (!joy_names.has(p_device)) { \
47+
return m_default_value; \
48+
} \
49+
return m_value;
50+
4351
static const char *_joy_buttons[(size_t)JoyButton::SDL_MAX] = {
4452
"a",
4553
"b",
@@ -145,10 +153,34 @@ void Input::_bind_methods() {
145153
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
146154
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
147155
ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
156+
ClassDB::bind_method(D_METHOD("get_joy_accelerometer_enabled", "device"), &Input::get_joy_accelerometer_enabled);
157+
ClassDB::bind_method(D_METHOD("get_joy_gyroscope_enabled", "device"), &Input::get_joy_gyroscope_enabled);
158+
ClassDB::bind_method(D_METHOD("get_joy_accelerometer", "device"), &Input::get_joy_accelerometer);
159+
ClassDB::bind_method(D_METHOD("get_joy_gyroscope", "device"), &Input::get_joy_gyroscope);
160+
ClassDB::bind_method(D_METHOD("get_joy_sensor_rate", "device"), &Input::get_joy_sensor_rate);
161+
ClassDB::bind_method(D_METHOD("get_joy_model", "device"), &Input::get_joy_model);
162+
ClassDB::bind_method(D_METHOD("get_joy_scheme", "device"), &Input::get_joy_scheme);
163+
ClassDB::bind_method(D_METHOD("get_joy_device_type", "device"), &Input::get_joy_device_type);
164+
ClassDB::bind_method(D_METHOD("get_joy_power_state", "device"), &Input::get_joy_power_state);
165+
ClassDB::bind_method(D_METHOD("get_joy_power_percent", "device"), &Input::get_joy_power_percent);
166+
ClassDB::bind_method(D_METHOD("get_joy_connection_state", "device"), &Input::get_joy_connection_state);
167+
ClassDB::bind_method(D_METHOD("get_joy_axis_string", "device", "axis"), &Input::get_joy_axis_string);
168+
ClassDB::bind_method(D_METHOD("get_joy_button_string", "device", "button"), &Input::get_joy_button_string);
169+
ClassDB::bind_method(D_METHOD("get_joy_touchpad_finger", "device", "touchpad", "finger"), &Input::get_joy_touchpad_finger);
170+
ClassDB::bind_method(D_METHOD("get_joy_touchpad_fingers", "device", "touchpad"), &Input::get_joy_touchpad_fingers);
171+
ClassDB::bind_method(D_METHOD("get_joy_num_buttons", "device"), &Input::get_joy_num_buttons);
172+
ClassDB::bind_method(D_METHOD("get_joy_num_axes", "device"), &Input::get_joy_num_axes);
173+
ClassDB::bind_method(D_METHOD("get_joy_num_touchpads", "device"), &Input::get_joy_num_touchpads);
148174
ClassDB::bind_method(D_METHOD("set_gravity", "value"), &Input::set_gravity);
149175
ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
150176
ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
151177
ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
178+
ClassDB::bind_method(D_METHOD("set_joy_light", "device", "color"), &Input::set_joy_light);
179+
ClassDB::bind_method(D_METHOD("set_joy_accelerometer_enabled", "device", "enable"), &Input::set_joy_accelerometer_enabled);
180+
ClassDB::bind_method(D_METHOD("set_joy_gyroscope_enabled", "device", "enable"), &Input::set_joy_gyroscope_enabled);
181+
ClassDB::bind_method(D_METHOD("has_joy_light", "device"), &Input::has_joy_light);
182+
ClassDB::bind_method(D_METHOD("has_joy_accelerometer", "device"), &Input::has_joy_accelerometer);
183+
ClassDB::bind_method(D_METHOD("has_joy_gyroscope", "device"), &Input::has_joy_gyroscope);
152184
ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
153185
ClassDB::bind_method(D_METHOD("get_last_mouse_screen_velocity"), &Input::get_last_mouse_screen_velocity);
154186
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
@@ -596,7 +628,12 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
596628
}
597629
}
598630
}
631+
// We don't want this to be exposed to the user, because this setting
632+
// is not very useful outside of this method
633+
js.info.erase("mapping_handled");
634+
599635
_set_joypad_mapping(js, mapping);
636+
JoypadSDL::get_singleton()->get_joypad_features(p_idx, js);
600637
} else {
601638
js.connected = false;
602639
for (int i = 0; i < (int)JoyButton::MAX; i++) {
@@ -606,6 +643,9 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_
606643
for (int i = 0; i < (int)JoyAxis::MAX; i++) {
607644
set_joy_axis(p_idx, (JoyAxis)i, 0.0f);
608645
}
646+
joy_vibration.erase(p_idx);
647+
joy_motion.erase(p_idx);
648+
joy_touch.erase(p_idx);
609649
}
610650
joy_names[p_idx] = js;
611651

@@ -661,6 +701,144 @@ Vector3 Input::get_gyroscope() const {
661701
return gyroscope;
662702
}
663703

704+
bool Input::get_joy_accelerometer_enabled(int p_device) const {
705+
return joy_motion.has(p_device) && joy_motion[p_device].accelerometer_enabled;
706+
}
707+
708+
bool Input::get_joy_gyroscope_enabled(int p_device) const {
709+
return joy_motion.has(p_device) && joy_motion[p_device].gyroscope_enabled;
710+
}
711+
712+
Vector3 Input::get_joy_accelerometer(int p_device) const {
713+
_THREAD_SAFE_METHOD_
714+
if (joy_motion.has(p_device)) {
715+
return joy_motion[p_device].accelerometer;
716+
} else {
717+
return Vector3();
718+
}
719+
}
720+
721+
float Input::get_joy_sensor_rate(int p_device) const {
722+
_THREAD_SAFE_METHOD_
723+
JOY_CHECK_RETURN(joy_names[p_device].sensor_data_rate, 0.0f);
724+
}
725+
726+
Vector3 Input::get_joy_gyroscope(int p_device) const {
727+
_THREAD_SAFE_METHOD_
728+
if (joy_motion.has(p_device)) {
729+
return joy_motion[p_device].gyroscope;
730+
} else {
731+
return Vector3();
732+
}
733+
}
734+
735+
JoyModel Input::get_joy_model(int p_device) const {
736+
_THREAD_SAFE_METHOD_
737+
JOY_CHECK_RETURN(joy_names[p_device].model, JoyModel::INVALID);
738+
}
739+
740+
JoyScheme Input::get_joy_scheme(int p_device) const {
741+
_THREAD_SAFE_METHOD_
742+
if (!joy_names.has(p_device)) {
743+
return JoyScheme::INVALID;
744+
}
745+
746+
switch (joy_names[p_device].model) {
747+
default:
748+
case JoyModel::INVALID: // Shouldn't happen, but I'll leave it here just in case
749+
return JoyScheme::INVALID;
750+
751+
case JoyModel::UNKNOWN:
752+
return JoyScheme::UNKNOWN;
753+
754+
case JoyModel::STANDARD:
755+
case JoyModel::XBOX360:
756+
case JoyModel::XBOXONE:
757+
return JoyScheme::XBOX;
758+
759+
case JoyModel::PS3:
760+
case JoyModel::PS4:
761+
case JoyModel::PS5:
762+
return JoyScheme::PLAYSTATION;
763+
764+
case JoyModel::NSPRO:
765+
case JoyModel::JOYCON_LEFT:
766+
case JoyModel::JOYCON_RIGHT:
767+
case JoyModel::JOYCON_PAIR:
768+
return JoyScheme::NINTENDO;
769+
}
770+
}
771+
772+
JoyDeviceType Input::get_joy_device_type(int p_device) const {
773+
_THREAD_SAFE_METHOD_
774+
JOY_CHECK_RETURN(joy_names[p_device].device_type, JoyDeviceType::INVALID);
775+
}
776+
777+
JoyPowerState Input::get_joy_power_state(int p_device) const {
778+
_THREAD_SAFE_METHOD_
779+
JOY_CHECK_RETURN(joy_names[p_device].power_state, JoyPowerState::INVALID);
780+
}
781+
782+
int Input::get_joy_power_percent(int p_device) const {
783+
_THREAD_SAFE_METHOD_
784+
JOY_CHECK_RETURN(joy_names[p_device].power_percent, -1);
785+
}
786+
787+
JoyConnectionState Input::get_joy_connection_state(int p_device) const {
788+
_THREAD_SAFE_METHOD_
789+
JOY_CHECK_RETURN(joy_names[p_device].connection_state, JoyConnectionState::INVALID);
790+
}
791+
792+
String Input::get_joy_axis_string(int p_device, JoyAxis p_axis) const {
793+
return JoypadSDL::get_singleton()->get_axis_string(p_device, p_axis);
794+
}
795+
796+
String Input::get_joy_button_string(int p_device, JoyButton p_button) const {
797+
return JoypadSDL::get_singleton()->get_button_string(p_device, p_button);
798+
}
799+
800+
Vector2 Input::get_joy_touchpad_finger(int p_device, int p_touchpad, int p_finger) const {
801+
_THREAD_SAFE_METHOD_
802+
if (!joy_touch.has(p_device) || !joy_touch[p_device].touchpad_fingers.has(p_touchpad) || !joy_touch[p_device].touchpad_fingers[p_touchpad].has(p_finger)) {
803+
return Vector2(-1.0, -1.0);
804+
}
805+
return joy_touch[p_device].touchpad_fingers[p_touchpad][p_finger];
806+
}
807+
808+
TypedArray<int> Input::get_joy_touchpad_fingers(int p_device, int p_touchpad) const {
809+
_THREAD_SAFE_METHOD_
810+
if (!joy_touch.has(p_device) || !joy_touch[p_device].touchpad_fingers.has(p_touchpad)) {
811+
return TypedArray<int>();
812+
}
813+
814+
TypedArray<int> result;
815+
for (KeyValue<int, Vector2> i : joy_touch[p_device].touchpad_fingers[p_touchpad]) {
816+
result.append(i.key);
817+
}
818+
return result;
819+
}
820+
821+
int Input::get_joy_num_buttons(int p_device) const {
822+
_THREAD_SAFE_METHOD_
823+
JOY_CHECK_RETURN(joy_names[p_device].num_buttons, -1);
824+
}
825+
826+
int Input::get_joy_num_axes(int p_device) const {
827+
_THREAD_SAFE_METHOD_
828+
JOY_CHECK_RETURN(joy_names[p_device].num_axes, -1);
829+
}
830+
831+
int Input::get_joy_num_touchpads(int p_device) const {
832+
_THREAD_SAFE_METHOD_
833+
if (!joy_names.has(p_device)) {
834+
return -1;
835+
}
836+
if (!joy_touch.has(p_device)) {
837+
return 0;
838+
}
839+
return joy_touch[p_device].num_touchpads;
840+
}
841+
664842
void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
665843
// This function does the final delivery of the input event to user land.
666844
// Regardless where the event came from originally, this has to happen on the main thread.
@@ -914,6 +1092,73 @@ void Input::set_joy_axis(int p_device, JoyAxis p_axis, float p_value) {
9141092
_joy_axis[c] = p_value;
9151093
}
9161094

1095+
bool Input::set_joy_light(int p_device, Color p_color) {
1096+
_THREAD_SAFE_METHOD_
1097+
return JoypadSDL::get_singleton()->set_light(p_device, p_color);
1098+
}
1099+
1100+
bool Input::set_joy_accelerometer_enabled(int p_device, bool p_enable) {
1101+
_THREAD_SAFE_METHOD_
1102+
bool enabled = JoypadSDL::get_singleton()->enable_accelerometer(p_device, p_enable);
1103+
joy_motion[p_device].accelerometer = Vector3();
1104+
joy_motion[p_device].accelerometer_enabled = enabled;
1105+
return enabled;
1106+
}
1107+
1108+
bool Input::set_joy_gyroscope_enabled(int p_device, bool p_enable) {
1109+
_THREAD_SAFE_METHOD_
1110+
bool enabled = JoypadSDL::get_singleton()->enable_gyroscope(p_device, p_enable);
1111+
joy_motion[p_device].gyroscope = Vector3();
1112+
joy_motion[p_device].gyroscope_enabled = enabled;
1113+
return enabled;
1114+
}
1115+
1116+
void Input::set_joy_accelerometer(int p_device, const Vector3 &p_value) {
1117+
_THREAD_SAFE_METHOD_
1118+
joy_motion[p_device].accelerometer = p_value;
1119+
// TODO: event
1120+
}
1121+
1122+
void Input::set_joy_gyroscope(int p_device, const Vector3 &p_value) {
1123+
_THREAD_SAFE_METHOD_
1124+
joy_motion[p_device].gyroscope = p_value;
1125+
// TODO: event
1126+
}
1127+
1128+
void Input::set_joy_sensor_rate(int p_device, float p_rate) {
1129+
_THREAD_SAFE_METHOD_
1130+
joy_names[p_device].sensor_data_rate = p_rate;
1131+
}
1132+
1133+
void Input::set_joy_power_info(int p_device, JoyPowerState p_power_state, int p_power_percent) {
1134+
_THREAD_SAFE_METHOD_
1135+
joy_names[p_device].power_state = p_power_state;
1136+
joy_names[p_device].power_percent = p_power_percent;
1137+
// TODO: event
1138+
}
1139+
1140+
void Input::set_joy_touchpad_finger(int p_device, int p_touchpad, int p_finger, bool p_down, Vector2 p_value) {
1141+
_THREAD_SAFE_METHOD_
1142+
if (p_down) {
1143+
joy_touch[p_device].touchpad_fingers[p_touchpad][p_finger] = p_value;
1144+
} else {
1145+
joy_touch[p_device].touchpad_fingers[p_touchpad].erase(p_finger);
1146+
}
1147+
// TODO: event
1148+
}
1149+
1150+
bool Input::has_joy_light(int p_device) const {
1151+
return joy_names.has(p_device) && joy_names[p_device].has_light;
1152+
}
1153+
1154+
bool Input::has_joy_accelerometer(int p_device) const {
1155+
return joy_motion.has(p_device) && joy_motion[p_device].has_accelerometer;
1156+
}
1157+
1158+
bool Input::has_joy_gyroscope(int p_device) const {
1159+
return joy_motion.has(p_device) && joy_motion[p_device].has_gyroscope;
1160+
}
1161+
9171162
void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
9181163
_THREAD_SAFE_METHOD_
9191164
if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {

0 commit comments

Comments
 (0)