@@ -89,15 +89,16 @@ public void initialize() {
8989 initialized = true ;
9090 }
9191
92- private void onDeviceConnected (int deviceIndex , boolean isGamepad ) {
92+ private void onDeviceConnected (InputManager inputManager , int deviceIndex , boolean isGamepad ) {
9393 if (loadGamepads && !isGamepad && SDL_IsGamepad (deviceIndex )) {
9494 // SDL will fire both GAMEPAD and JOYSTICK events for recognized
9595 // gamepads, so here we check if the joystick is expected to be
9696 // a gamepad, and skip it if so to avoid duplicates.
9797 return ;
9898 }
99-
100- InputManager inputManager = (InputManager ) listener ;
99+ if (joysticks .containsKey (deviceIndex )) {
100+ return ;
101+ }
101102
102103 SdlJoystick joystick ;
103104 if (isGamepad ) {
@@ -164,6 +165,7 @@ private void onDeviceConnected(int deviceIndex, boolean isGamepad) {
164165 JoystickButton button = new DefaultJoystickButton (inputManager , joystick , buttonIndex ,
165166 buttonName , logicalId );
166167 joystick .addButton (button );
168+ joyButtonPressed .put (button , false );
167169 }
168170 }
169171
@@ -176,7 +178,7 @@ private void onDeviceConnected(int deviceIndex, boolean isGamepad) {
176178 JoystickAxis .POV_Y , true , false , 0.0f );
177179 joystick .addAxis (POV_Y_AXIS_ID , povY );
178180
179- (( InputManager ) listener ) .fireJoystickConnectedEvent (joystick );
181+ inputManager .fireJoystickConnectedEvent (joystick );
180182
181183 }
182184
@@ -204,7 +206,9 @@ private void onDeviceDisconnected(int deviceIndex) {
204206 // free resources
205207 destroyJoystick (joystick );
206208
207- ((InputManager ) listener ).fireJoystickDisconnectedEvent (joystick );
209+ if (listener instanceof InputManager ) {
210+ ((InputManager ) listener ).fireJoystickDisconnectedEvent (joystick );
211+ }
208212 }
209213
210214 @ Override
@@ -220,9 +224,13 @@ public Joystick[] loadJoysticks(InputManager inputManager) {
220224 // load managed gamepads
221225 IntBuffer gamepads = SDL_GetGamepads ();
222226 if (gamepads != null ) {
223- while (gamepads .hasRemaining ()) {
224- int deviceId = gamepads .get ();
225- onDeviceConnected (deviceId , true );
227+ try {
228+ while (gamepads .hasRemaining ()) {
229+ int deviceId = gamepads .get ();
230+ onDeviceConnected (inputManager , deviceId , true );
231+ }
232+ } finally {
233+ SDLStdinc .SDL_free (gamepads );
226234 }
227235 }
228236 }
@@ -231,9 +239,13 @@ public Joystick[] loadJoysticks(InputManager inputManager) {
231239 // load raw gamepads
232240 IntBuffer joys = SDL_GetJoysticks ();
233241 if (joys != null ) {
234- while (joys .hasRemaining ()) {
235- int deviceId = joys .get ();
236- onDeviceConnected (deviceId , false );
242+ try {
243+ while (joys .hasRemaining ()) {
244+ int deviceId = joys .get ();
245+ onDeviceConnected (inputManager , deviceId , false );
246+ }
247+ } finally {
248+ SDLStdinc .SDL_free (joys );
237249 }
238250 }
239251 }
@@ -248,18 +260,23 @@ public void update() {
248260
249261 public void onSDLEvent (SDL_Event evt ) {
250262 int type = evt .type ();
263+ if (!(listener instanceof InputManager )) {
264+ return ;
265+ }
266+
267+ InputManager inputManager = (InputManager ) listener ;
251268 if (type == SDL_EVENT_GAMEPAD_ADDED ) {
252269 if (loadGamepads ) {
253270 int which = evt .gdevice ().which ();
254- onDeviceConnected (which , true );
271+ onDeviceConnected (inputManager , which , true );
255272 }
256273 } else if (type == SDL_EVENT_GAMEPAD_REMOVED ) {
257274 int which = evt .gdevice ().which ();
258275 onDeviceDisconnected (which );
259276 } else if (type == SDL_EVENT_JOYSTICK_ADDED ) {
260277 if (loadRaw ) {
261278 int which = evt .jdevice ().which ();
262- onDeviceConnected (which , false );
279+ onDeviceConnected (inputManager , which , false );
263280 }
264281 } else if (type == SDL_EVENT_JOYSTICK_REMOVED ) {
265282 int which = evt .jdevice ().which ();
@@ -268,14 +285,21 @@ public void onSDLEvent(SDL_Event evt) {
268285 }
269286
270287 private void handleInputEvents () {
288+ if (listener == null ) {
289+ return ;
290+ }
291+
271292 float rawValue , value ;
272293 for (SdlJoystick js : joysticks .values ()) {
273294 if (js .isGamepad ()) {
274295 long gp = js .gamepad ;
275296
276- // for(int axisIndex=0; axisIndex<SDL_GAMEPAD_AXIS_COUNT; axisIndex++){
277297 for (JoystickAxis axis : js .getAxes ()) {
278298 int axisIndex = axis .getAxisId ();
299+ if (isVirtualPovAxis (axisIndex )) {
300+ continue ;
301+ }
302+
279303 String jmeAxisId = axis .getLogicalId ();
280304
281305 short v = SDL_GetGamepadAxis (gp , axisIndex );
@@ -286,57 +310,57 @@ private void handleInputEvents() {
286310
287311 // Virtual trigger buttons.
288312 if (virtualTriggerThreshold > 0f ) {
289- if (jmeAxisId == JoystickAxis .AXIS_XBOX_LEFT_TRIGGER ) {
313+ if (JoystickAxis .AXIS_XBOX_LEFT_TRIGGER . equals ( jmeAxisId ) ) {
290314 updateButton (js .getButton (JoystickButton .BUTTON_XBOX_LT ),
291315 value > virtualTriggerThreshold );
292- } else if (jmeAxisId == JoystickAxis .AXIS_XBOX_RIGHT_TRIGGER ) {
316+ } else if (JoystickAxis .AXIS_XBOX_RIGHT_TRIGGER . equals ( jmeAxisId ) ) {
293317 updateButton (js .getButton (JoystickButton .BUTTON_XBOX_RT ),
294318 value > virtualTriggerThreshold );
295319 }
296320 }
321+ }
297322
298- // Dpad -> virtual POV axes
299- float povXValue = 0f ;
300- float povYValue = 0f ;
301-
302- // button handling
303- // for (int b = 0; b <= SDL_GAMEPAD_BUTTON_COUNT; b++) {
304- for (JoystickButton button : js .getButtons ()) {
305- int b = button .getButtonId ();
306- String jmeButtonId = button .getLogicalId ();
307-
308- boolean pressed = SDL_GetGamepadButton (gp , b );
309- updateButton (button , pressed );
310-
311- // Dpad -> virtual POV axes
312- if (jmeButtonId == JoystickButton .BUTTON_XBOX_DPAD_UP ) {
313- povYValue += pressed ? 1f : 0f ;
314- } else if (jmeButtonId == JoystickButton .BUTTON_XBOX_DPAD_DOWN ) {
315- povYValue += pressed ? -1f : 0f ;
316- } else if (jmeButtonId == JoystickButton .BUTTON_XBOX_DPAD_LEFT ) {
317- povXValue += pressed ? -1f : 0f ;
318- } else if (jmeButtonId == JoystickButton .BUTTON_XBOX_DPAD_RIGHT ) {
319- povXValue += pressed ? 1f : 0f ;
320- }
321- }
323+ float povXValue = 0f ;
324+ float povYValue = 0f ;
322325
323- JoystickAxis povXAxis = js .getPovXAxis ();
324- if (povXAxis != null ) {
325- updateAxis (povXAxis , povXValue , povXValue );
326- }
326+ for (JoystickButton button : js .getButtons ()) {
327+ int buttonId = button .getButtonId ();
328+ String jmeButtonId = button .getLogicalId ();
327329
328- JoystickAxis povYAxis = js .getPovYAxis ();
329- if (povYAxis != null ) {
330- updateAxis (povYAxis , povYValue , povYValue );
330+ boolean pressed = SDL_GetGamepadButton (gp , buttonId );
331+ updateButton (button , pressed );
332+
333+ if (JoystickButton .BUTTON_XBOX_DPAD_UP .equals (jmeButtonId )) {
334+ povYValue += pressed ? 1f : 0f ;
335+ } else if (JoystickButton .BUTTON_XBOX_DPAD_DOWN .equals (jmeButtonId )) {
336+ povYValue += pressed ? -1f : 0f ;
337+ } else if (JoystickButton .BUTTON_XBOX_DPAD_LEFT .equals (jmeButtonId )) {
338+ povXValue += pressed ? -1f : 0f ;
339+ } else if (JoystickButton .BUTTON_XBOX_DPAD_RIGHT .equals (jmeButtonId )) {
340+ povXValue += pressed ? 1f : 0f ;
331341 }
332342 }
343+
344+ JoystickAxis povXAxis = js .getPovXAxis ();
345+ if (povXAxis != null ) {
346+ updateAxis (povXAxis , povXValue , povXValue );
347+ }
348+
349+ JoystickAxis povYAxis = js .getPovYAxis ();
350+ if (povYAxis != null ) {
351+ updateAxis (povYAxis , povYValue , povYValue );
352+ }
333353 } else {
334354 long joy = js .joystick ;
335355
336356 for (JoystickAxis axis : js .getAxes ()) {
357+ if (isVirtualPovAxis (axis .getAxisId ())) {
358+ continue ;
359+ }
360+
337361 short v = SDL_GetJoystickAxis (joy , axis .getAxisId ());
338- rawValue = v ;
339- value = v ;
362+ rawValue = remapJoystickAxisValue ( v ) ;
363+ value = rawValue ;
340364 updateAxis (axis , value , rawValue );
341365 }
342366
@@ -348,6 +372,10 @@ private void handleInputEvents() {
348372 }
349373 }
350374
375+ private boolean isVirtualPovAxis (int axisId ) {
376+ return axisId == POV_X_AXIS_ID || axisId == POV_Y_AXIS_ID ;
377+ }
378+
351379 @ Override
352380 public void setJoyRumble (int joyId , float amount ) {
353381 setJoyRumble (joyId , amount , amount , 100f / 1000f );
@@ -480,6 +508,13 @@ private float remapAxisValueToJme(int axisId, short v) {
480508 }
481509 }
482510
511+ private float remapJoystickAxisValue (short value ) {
512+ if (value == Short .MIN_VALUE ) {
513+ return -1f ;
514+ }
515+ return value / 32767f ;
516+ }
517+
483518 private void updateButton (JoystickButton button , boolean pressed ) {
484519 if (button == null ) return ;
485520 Boolean old = joyButtonPressed .get (button );
@@ -491,6 +526,7 @@ private void updateButton(JoystickButton button, boolean pressed) {
491526
492527 private void updateAxis (JoystickAxis axis , float value , float rawValue ) {
493528 if (axis == null ) return ;
529+ value = JoystickCompatibilityMappings .remapAxisRange (axis , value );
494530 Float old = joyAxisValues .get (axis );
495531 float jitter = FastMath .clamp (Math .max (axis .getJitterThreshold (), globalJitterThreshold ), 0f , 1f );
496532 if (old == null || FastMath .abs (old - value ) > jitter ) {
0 commit comments