4848#include <stdlib.h>
4949#include <unistd.h>
5050
51- #ifdef USE_SDL2
51+ #ifdef USE_SDL3
52+ #include <SDL3/SDL.h>
53+ #elif defined(USE_SDL2 )
5254#include <SDL2/SDL.h>
5355#else
5456#include <SDL/SDL.h>
@@ -258,6 +260,32 @@ int ndof_init_first(NDOF_Device *in_out_dev, void *param)
258260 return 0 ;
259261
260262 } else {
263+ #ifdef USE_SDL3
264+ // SpaceNavigator not found, use SDL Joystick
265+ SDL_Joystick * j = SDL_OpenJoystick (0 );
266+ if (j )
267+ {
268+ in_out_dev -> axes_count = SDL_GetNumJoystickAxes (j ) + SDL_GetNumJoystickHats (j ) * 2 ; // each hat has 2 axes
269+ in_out_dev -> btn_count = SDL_GetNumJoystickButtons (j );
270+ in_out_dev -> absolute = 0 ; // always relative on Linux
271+ in_out_dev -> valid = 1 ;
272+ in_out_dev -> axes_max = 32767 ;
273+ in_out_dev -> axes_min = -32767 ;
274+
275+ strncpy (in_out_dev -> product , SDL_GetJoystickName (j ), 255 );
276+
277+ // private data
278+ LinJoystickPrivate * priv = (LinJoystickPrivate * ) malloc (sizeof (LinJoystickPrivate ));
279+ priv -> j = j ;
280+ priv -> fd = -1 ;
281+ priv -> USE_SDL = 1 ;
282+ // remember number of hats for later axis mapping in ndof_update()
283+ priv -> num_hats = SDL_GetNumJoystickHats (j );
284+ in_out_dev -> private_data = priv ;
285+
286+ return 0 ;
287+ }
288+ #else
261289 // SpaceNavigator not found, use SDL Joystick
262290 SDL_Joystick * j = SDL_JoystickOpen (0 );
263291 if (j )
@@ -268,7 +296,7 @@ int ndof_init_first(NDOF_Device *in_out_dev, void *param)
268296 in_out_dev -> valid = 1 ;
269297 in_out_dev -> axes_max = 32767 ;
270298 in_out_dev -> axes_min = -32767 ;
271- #ifdef USE_SDL2
299+ #if defined( USE_SDL2 )
272300 strncpy (in_out_dev -> product , SDL_JoystickName (j ), 255 );
273301#else
274302 strncpy (in_out_dev -> product , SDL_JoystickName (0 ), 255 );
@@ -283,7 +311,9 @@ int ndof_init_first(NDOF_Device *in_out_dev, void *param)
283311 in_out_dev -> private_data = priv ;
284312
285313 return 0 ;
286- } else {
314+ }
315+ #endif
316+ else {
287317
288318 // no joysticks found
289319 return -1 ;
@@ -348,6 +378,50 @@ void ndof_update(NDOF_Device *in_dev)
348378
349379 if (priv -> USE_SDL )
350380 {
381+ #ifdef USE_SDL3
382+ SDL_UpdateJoysticks ();
383+ SDL_Joystick * j = priv -> j ;
384+
385+ for (i = 0 ; i < in_dev -> axes_count - priv -> num_hats * 2 ; i ++ ) // hats will get mapped to uppermost axes
386+ {
387+ in_dev -> axes [i ] = (int ) (SDL_GetJoystickAxis (j , i ));
388+ }
389+
390+ for (i = 0 ; i < priv -> num_hats ; i ++ )
391+ {
392+ int x = 0 ;
393+ int y = 0 ;
394+
395+ int value = SDL_GetJoystickHat (j , i );
396+
397+ // map hat values (1, 2, 4, 8) to axis data (-32768, 32768)
398+ if (value & 1 )
399+ {
400+ y = -32767 ;
401+ }
402+ else if (value & 4 )
403+ {
404+ y = 32768 ;
405+ }
406+ if (value & 2 )
407+ {
408+ x = 32767 ;
409+ }
410+ else if (value & 8 )
411+ {
412+ x = -32768 ;
413+ }
414+
415+ // add the hat data to the uppermost axes data
416+ in_dev -> axes [in_dev -> axes_count - priv -> num_hats * 2 + i * 2 ] = x ;
417+ in_dev -> axes [in_dev -> axes_count - priv -> num_hats * 2 + i * 2 + 1 ] = y ;
418+ }
419+
420+ for (i = 0 ; i < in_dev -> btn_count ; i ++ )
421+ {
422+ in_dev -> buttons [i ] = SDL_GetJoystickButton (j , i );
423+ }
424+ #else
351425 SDL_JoystickUpdate ();
352426 SDL_Joystick * j = priv -> j ;
353427
@@ -390,18 +464,18 @@ void ndof_update(NDOF_Device *in_dev)
390464 {
391465 in_dev -> buttons [i ] = SDL_JoystickGetButton (j , i );
392466 }
467+ #endif
393468 } else {
394469 // update SpaceNavigator
395470
396471 struct input_event ev ;
397- int mapped_code ;
398472
399473 while (read (priv -> fd , & ev , sizeof (struct input_event )) > 0 )
400474 {
401475 switch (ev .type )
402476 {
403477 case EV_KEY :
404- mapped_code = SPACE_MOUSE_BUTTON_MAPPING [ev .code & 0xff ];
478+ int mapped_code = SPACE_MOUSE_BUTTON_MAPPING [ev .code & 0xff ];
405479 // printf("Key %d (mapped to %d) pressed %d .\n", ev.code, mapped_code, ev.value);
406480 priv -> buttons [mapped_code ] = ev .value ;
407481 break ;
0 commit comments