Skip to content

Commit 10920b3

Browse files
committed
Add gamepad support to woodeneye-008
1 parent 8d81ee3 commit 10920b3

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

examples/demo/02-woodeneye-008/woodeneye-008.c

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
typedef 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+
6373
static 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

477545
void 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

Comments
 (0)