From 87a5b1da2192da777cda0c7b2da6edc33473aee2 Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Wed, 6 May 2026 12:02:36 -0400 Subject: [PATCH] Add ability to push controls to a control map without having to manually track controlmap index IDs --- include/sdl3game/SDL_GameControllerDB.h | 2 +- include/sdl3game/controller.h | 3 + src/controller.c | 114 +++++++++++++++--------- 3 files changed, 76 insertions(+), 43 deletions(-) diff --git a/include/sdl3game/SDL_GameControllerDB.h b/include/sdl3game/SDL_GameControllerDB.h index 4d87bb9..390be1d 100644 --- a/include/sdl3game/SDL_GameControllerDB.h +++ b/include/sdl3game/SDL_GameControllerDB.h @@ -1,7 +1,7 @@ #ifndef _SDL_GAMECONTROLLERDB_H_ #define _SDL_GAMECONTROLLERDB_H_ -// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Wed May 6 11:06:20 AM EDT 2026 +// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Wed May 6 11:52:34 AM EDT 2026 #define SDL_GAMECONTROLLER_DB_LEN 2225 diff --git a/include/sdl3game/controller.h b/include/sdl3game/controller.h index 1e2f662..091af78 100644 --- a/include/sdl3game/controller.h +++ b/include/sdl3game/controller.h @@ -21,6 +21,7 @@ typedef struct { typedef struct { actor *target; + int nextMap; SDL3GControl controls[MAX_CONTROLS]; SDL_KeyboardID kbid; SDL_JoystickID jsid; @@ -37,5 +38,7 @@ akerr_ErrorContext AKERR_NOIGNORE *controller_handle_button_up(void *appstate, S akerr_ErrorContext AKERR_NOIGNORE *controller_handle_added(void *appstate, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *controller_handle_removed(void *appstate, SDL_Event *event); +akerr_ErrorContext AKERR_NOIGNORE *SDL3G_controller_pushmap(int controlmapid, SDL3GControl *control); + akerr_ErrorContext AKERR_NOIGNORE *SDL3G_controller_default(int controlmapid, char *actorname, int kbid, int jsid); #endif // _CONTROLLER_H_ diff --git a/src/controller.c b/src/controller.c index 811c7ed..2224990 100644 --- a/src/controller.c +++ b/src/controller.c @@ -194,13 +194,34 @@ akerr_ErrorContext *gamepad_handle_removed(void *appstate, SDL_Event *event) SUCCEED_RETURN(errctx); } +akerr_ErrorContext AKERR_NOIGNORE *SDL3G_controller_pushmap(int controlmapid, SDL3GControl *control) +{ + int newmapid = 0; + PREPARE_ERROR(errctx); + ATTEMPT { + FAIL_ZERO_RETURN(errctx, control, AKERR_NULLPOINTER, "NULL Control"); + FAIL_NONZERO_RETURN(errctx, (controlmapid >= MAX_CONTROL_MAPS), AKERR_OUTOFBOUNDS, "ID %d exceeds maximum %d", controlmapid, MAX_CONTROL_MAPS); + newmapid = GAME_ControlMaps[controlmapid].nextMap; + FAIL_ZERO_RETURN(errctx, (MAX_CONTROLS - newmapid), AKERR_OUTOFBOUNDS, "Control map ID %d is full", controlmapid); + memcpy((void *)&GAME_ControlMaps[controlmapid].controls[newmapid], control, sizeof(SDL3GControl)); + GAME_ControlMaps[controlmapid].nextMap = newmapid + 1; + } CLEANUP { + } PROCESS(errctx) { + } FINISH(errctx, true); + SUCCEED_RETURN(errctx); +} + akerr_ErrorContext AKERR_NOIGNORE *SDL3G_controller_default(int controlmapid, char *actorname, int kbid, int jsid) { SDL3GControlMap *controlmap; + SDL3GControl control; + PREPARE_ERROR(errctx); ATTEMPT { // set up the control map - controlmap = &GAME_ControlMaps[0]; + FAIL_NONZERO_RETURN(errctx, (controlmapid >= MAX_CONTROL_MAPS), AKERR_OUTOFBOUNDS, "ID %d exceeds maximum %d", controlmapid, MAX_CONTROL_MAPS); + memset((void *)control, 0x00, sizeof(SDL3GControl)); + controlmap = &GAME_ControlMaps[controlmapid]; controlmap->kbid = kbid; controlmap->jsid = jsid; @@ -210,62 +231,71 @@ akerr_ErrorContext AKERR_NOIGNORE *SDL3G_controller_default(int controlmapid, ch // ---- KEYBOARD CONTROLS ---- // Move down - controlmap->controls[0].key = SDLK_DOWN; - controlmap->controls[0].event_on = SDL_EVENT_KEY_DOWN; - controlmap->controls[0].event_off = SDL_EVENT_KEY_UP; - controlmap->controls[0].handler_on = &SDL3GActor_cmhf_down_on; - controlmap->controls[0].handler_off = &SDL3GActor_cmhf_down_off; + control.key = SDLK_DOWN; + control.event_on = SDL_EVENT_KEY_DOWN; + control.event_off = SDL_EVENT_KEY_UP; + control.handler_on = &SDL3GActor_cmhf_down_on; + control.handler_off = &SDL3GActor_cmhf_down_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move up - controlmap->controls[1].key = SDLK_UP; - controlmap->controls[1].event_on = SDL_EVENT_KEY_DOWN; - controlmap->controls[1].event_off = SDL_EVENT_KEY_UP; - controlmap->controls[1].handler_on = &SDL3GActor_cmhf_up_on; - controlmap->controls[1].handler_off = &SDL3GActor_cmhf_up_off; + control.key = SDLK_UP; + control.event_on = SDL_EVENT_KEY_DOWN; + control.event_off = SDL_EVENT_KEY_UP; + control.handler_on = &SDL3GActor_cmhf_up_on; + control.handler_off = &SDL3GActor_cmhf_up_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move left - controlmap->controls[2].key = SDLK_LEFT; - controlmap->controls[2].event_on = SDL_EVENT_KEY_DOWN; - controlmap->controls[2].event_off = SDL_EVENT_KEY_UP; - controlmap->controls[2].handler_on = &SDL3GActor_cmhf_left_on; - controlmap->controls[2].handler_off = &SDL3GActor_cmhf_left_off; + control.key = SDLK_LEFT; + control.event_on = SDL_EVENT_KEY_DOWN; + control.event_off = SDL_EVENT_KEY_UP; + control.handler_on = &SDL3GActor_cmhf_left_on; + control.handler_off = &SDL3GActor_cmhf_left_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move right - controlmap->controls[3].key = SDLK_RIGHT; - controlmap->controls[3].event_on = SDL_EVENT_KEY_DOWN; - controlmap->controls[3].event_off = SDL_EVENT_KEY_UP; - controlmap->controls[3].handler_on = &SDL3GActor_cmhf_right_on; - controlmap->controls[3].handler_off = &SDL3GActor_cmhf_right_off; + control.key = SDLK_RIGHT; + control.event_on = SDL_EVENT_KEY_DOWN; + control.event_off = SDL_EVENT_KEY_UP; + control.handler_on = &SDL3GActor_cmhf_right_on; + control.handler_off = &SDL3GActor_cmhf_right_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); + control.key = 0; // ----- GAMEPAD CONTROLS // Move down - controlmap->controls[17].button = SDL_GAMEPAD_BUTTON_DPAD_DOWN; - controlmap->controls[17].event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; - controlmap->controls[17].event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; - controlmap->controls[17].handler_on = &SDL3GActor_cmhf_down_on; - controlmap->controls[17].handler_off = &SDL3GActor_cmhf_down_off; + control.button = SDL_GAMEPAD_BUTTON_DPAD_DOWN; + control.event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; + control.event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; + control.handler_on = &SDL3GActor_cmhf_down_on; + control.handler_off = &SDL3GActor_cmhf_down_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move up - controlmap->controls[18].button = SDL_GAMEPAD_BUTTON_DPAD_UP; - controlmap->controls[18].event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; - controlmap->controls[18].event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; - controlmap->controls[18].handler_on = &SDL3GActor_cmhf_up_on; - controlmap->controls[18].handler_off = &SDL3GActor_cmhf_up_off; + control.button = SDL_GAMEPAD_BUTTON_DPAD_UP; + control.event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; + control.event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; + control.handler_on = &SDL3GActor_cmhf_up_on; + control.handler_off = &SDL3GActor_cmhf_up_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move left - controlmap->controls[19].button = SDL_GAMEPAD_BUTTON_DPAD_LEFT; - controlmap->controls[19].event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; - controlmap->controls[19].event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; - controlmap->controls[19].handler_on = &SDL3GActor_cmhf_left_on; - controlmap->controls[19].handler_off = &SDL3GActor_cmhf_left_off; + control.button = SDL_GAMEPAD_BUTTON_DPAD_LEFT; + control.event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; + control.event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; + control.handler_on = &SDL3GActor_cmhf_left_on; + control.handler_off = &SDL3GActor_cmhf_left_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); // Move right - controlmap->controls[20].button = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; - controlmap->controls[20].event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; - controlmap->controls[20].event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; - controlmap->controls[20].handler_on = &SDL3GActor_cmhf_right_on; - controlmap->controls[20].handler_off = &SDL3GActor_cmhf_right_off; - + control.button = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; + control.event_on = SDL_EVENT_GAMEPAD_BUTTON_DOWN; + control.event_off = SDL_EVENT_GAMEPAD_BUTTON_UP; + control.handler_on = &SDL3GActor_cmhf_right_on; + control.handler_off = &SDL3GActor_cmhf_right_off; + CATCH(errctx, SDL3G_controller_pushmap(controlmapid, &control)); + SUCCEED_RETURN(errctx); } CLEANUP {