1515typedef struct {
1616 SDL_MouseID mouse ;
1717 SDL_KeyboardID keyboard ;
18+ SDL_Gamepad * gamepad ;
1819 double pos [3 ];
1920 double vel [3 ];
2021 unsigned int yaw ;
@@ -60,6 +61,15 @@ static int whoseKeyboard(SDL_KeyboardID keyboard, const Player players[], int pl
6061 return -1 ;
6162}
6263
64+ static int whoseGamepad (SDL_JoystickID gamepad , const Player players [], int players_len )
65+ {
66+ int i ;
67+ for (i = 0 ; i < players_len ; i ++ ) {
68+ if (SDL_GetGamepadID (players [i ].gamepad ) == gamepad ) return i ;
69+ }
70+ return -1 ;
71+ }
72+
6373static void shoot (int shooter , Player players [], int players_len )
6474{
6575 int i , j ;
@@ -288,6 +298,7 @@ static void initPlayers(Player *players, int len)
288298 players [i ].wasd = 0 ;
289299 players [i ].mouse = 0 ;
290300 players [i ].keyboard = 0 ;
301+ players [i ].gamepad = NULL ;
291302 players [i ].color [0 ] = (1 << (i / 2 )) & 2 ? 0 : 0xff ;
292303 players [i ].color [1 ] = (1 << (i / 2 )) & 1 ? 0 : 0xff ;
293304 players [i ].color [2 ] = (1 << (i / 2 )) & 4 ? 0 : 0xff ;
@@ -344,7 +355,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
344355 * appstate = as ;
345356 }
346357
347- if (!SDL_Init (SDL_INIT_VIDEO )) {
358+ if (!SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMEPAD )) {
348359 return SDL_APP_FAILURE ;
349360 }
350361 if (!SDL_CreateWindowAndRenderer ("examples/demo/woodeneye-008" , 640 , 480 , 0 , & as -> window , & as -> renderer )) {
@@ -386,6 +397,25 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
386397 }
387398 }
388399 break ;
400+ case SDL_EVENT_GAMEPAD_REMOVED :
401+ for (i = 0 ; i < player_count ; i ++ ) {
402+ if (players [i ].gamepad && (SDL_GetGamepadID (players [i ].gamepad ) == event -> gdevice .which )) {
403+ SDL_CloseGamepad (players [i ].gamepad );
404+ players [i ].gamepad = NULL ;
405+ }
406+ }
407+ break ;
408+ case SDL_EVENT_GAMEPAD_ADDED :
409+ for (i = 0 ; i < player_count ; i ++ ) {
410+ if (players [i ].gamepad == NULL ) {
411+ players [i ].gamepad = SDL_OpenGamepad (event -> gdevice .which );
412+ if (!players [i ].gamepad )
413+ SDL_Log ("Failed to open gamepad ID %u: %s" , (unsigned int ) event -> gdevice .which , SDL_GetError ());
414+ else
415+ as -> player_count = SDL_max (as -> player_count , i + 1 );
416+ }
417+ }
418+ break ;
389419 case SDL_EVENT_MOUSE_MOTION : {
390420 SDL_MouseID id = event -> motion .which ;
391421 int index = whoseMouse (id , players , player_count );
@@ -446,6 +476,44 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
446476 }
447477 break ;
448478 }
479+ case SDL_EVENT_GAMEPAD_AXIS_MOTION : {
480+ SDL_JoystickID id = event -> gaxis .which ;
481+ int index = whoseGamepad (id , players , player_count );
482+ if (index >= 0 ) {
483+ if (event -> gaxis .axis == SDL_GAMEPAD_AXIS_LEFTX )
484+ players [index ].yaw -= ((int )event -> gaxis .value ) * 0x00000800 ;
485+ if (event -> gaxis .axis == SDL_GAMEPAD_AXIS_LEFTY )
486+ players [index ].pitch = SDL_max (-0x40000000 , SDL_min (0x40000000 , players [index ].pitch - ((int )event -> gaxis .value ) * 0x00000800 ));
487+ }
488+ break ;
489+ }
490+ case SDL_EVENT_GAMEPAD_BUTTON_DOWN : {
491+ Uint8 button = event -> gbutton .button ;
492+ SDL_JoystickID id = event -> gbutton .which ;
493+ int index = whoseGamepad (id , players , player_count );
494+ if (index >= 0 ) {
495+ if (button == SDL_GAMEPAD_BUTTON_DPAD_UP ) players [index ].wasd |= 1 ;
496+ if (button == SDL_GAMEPAD_BUTTON_DPAD_LEFT ) players [index ].wasd |= 2 ;
497+ if (button == SDL_GAMEPAD_BUTTON_DPAD_DOWN ) players [index ].wasd |= 4 ;
498+ if (button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT ) players [index ].wasd |= 8 ;
499+ if (button == SDL_GAMEPAD_BUTTON_SOUTH ) players [index ].wasd |= 16 ;
500+ if (button == SDL_GAMEPAD_BUTTON_EAST ) shoot (index , players , player_count );
501+ }
502+ break ;
503+ }
504+ case SDL_EVENT_GAMEPAD_BUTTON_UP : {
505+ Uint8 button = event -> gbutton .button ;
506+ SDL_JoystickID id = event -> gbutton .which ;
507+ int index = whoseGamepad (id , players , player_count );
508+ if (index >= 0 ) {
509+ if (button == SDL_GAMEPAD_BUTTON_DPAD_UP ) players [index ].wasd &= 30 ;
510+ if (button == SDL_GAMEPAD_BUTTON_DPAD_LEFT ) players [index ].wasd &= 29 ;
511+ if (button == SDL_GAMEPAD_BUTTON_DPAD_DOWN ) players [index ].wasd &= 27 ;
512+ if (button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT ) players [index ].wasd &= 23 ;
513+ if (button == SDL_GAMEPAD_BUTTON_SOUTH ) players [index ].wasd &= 15 ;
514+ }
515+ break ;
516+ }
449517 }
450518 return SDL_APP_CONTINUE ;
451519}
@@ -476,5 +544,13 @@ SDL_AppResult SDL_AppIterate(void *appstate)
476544
477545void SDL_AppQuit (void * appstate , SDL_AppResult result )
478546{
547+ AppState * as = appstate ;
548+ Player * players = as -> players ;
549+ int player_count = as -> player_count ;
550+ int i ;
551+ for (i = 0 ; i < player_count ; i ++ ) {
552+ if (players [i ].gamepad )
553+ SDL_CloseGamepad (players [i ].gamepad );
554+ }
479555 SDL_free (appstate ); // just free the memory, SDL will clean up the window/renderer for us.
480- }
556+ }
0 commit comments