diff --git a/include/akgl/SDL_GameControllerDB.h b/include/akgl/SDL_GameControllerDB.h index d15e4fe..97e2d21 100644 --- a/include/akgl/SDL_GameControllerDB.h +++ b/include/akgl/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 13 04:53:27 AM EDT 2026 +// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Wed May 13 08:00:23 AM EDT 2026 #define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228 diff --git a/include/akgl/controller.h b/include/akgl/controller.h index c04f11a..a4236e3 100644 --- a/include/akgl/controller.h +++ b/include/akgl/controller.h @@ -32,6 +32,8 @@ typedef struct { extern akgl_ControlMap GAME_ControlMaps[AKGL_MAX_CONTROL_MAPS]; +akerr_ErrorContext AKERR_NOIGNORE *akgl_controller_list_keyboards(void); + akerr_ErrorContext AKERR_NOIGNORE *akgl_controller_handle_event(void *appstate, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *akgl_controller_handle_button_down(void *appstate, SDL_Event *event); diff --git a/include/akgl/tilemap.h b/include/akgl/tilemap.h index 17ec4d3..f6feda0 100644 --- a/include/akgl/tilemap.h +++ b/include/akgl/tilemap.h @@ -19,6 +19,7 @@ #define AKGL_TILEMAP_LAYER_TYPE_TILES 1 #define AKGL_TILEMAP_LAYER_TYPE_OBJECTS 2 +#define AKGL_TILEMAP_LAYER_TYPE_IMAGE 3 typedef struct { float x; @@ -43,6 +44,7 @@ typedef struct { int x; int y; int id; + SDL_Texture *texture; int data[AKGL_TILEMAP_MAX_WIDTH * AKGL_TILEMAP_MAX_HEIGHT]; akgl_TilemapObject objects[AKGL_TILEMAP_MAX_OBJECTS_PER_LAYER]; } akgl_TilemapLayer; diff --git a/src/controller.c b/src/controller.c index 733f010..9ae8b98 100644 --- a/src/controller.c +++ b/src/controller.c @@ -7,6 +7,21 @@ akgl_ControlMap GAME_ControlMaps[AKGL_MAX_CONTROL_MAPS]; +akerr_ErrorContext AKERR_NOIGNORE *akgl_controller_list_keyboards(void) +{ + int count; + SDL_KeyboardID *keyboards = SDL_GetKeyboards(&count); + PREPARE_ERROR(e); + + FAIL_ZERO_RETURN(e, keyboards, AKERR_NULLPOINTER, "%s", SDL_GetError()); + + for (int i = 0; i < count; i++) { + const char *name = SDL_GetKeyboardNameForID(keyboards[i]); + SDL_Log("Keyboard %d: ID %u, Name: %s\n", i, keyboards[i], name); + } + SUCCEED_RETURN(e); +} + akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *event) { int i = 0; @@ -15,7 +30,9 @@ akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *even akgl_ControlMap *curmap = NULL; akgl_Control *curcontrol = NULL; PREPARE_ERROR(errctx); - + FAIL_ZERO_RETURN(errctx, appstate, AKERR_NULLPOINTER, "NULL appstate"); + FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event"); + ATTEMPT { for ( i = 0 ; i < AKGL_MAX_CONTROL_MAPS; i++ ) { curmap = &GAME_ControlMaps[i]; diff --git a/src/tilemap.c b/src/tilemap.c index 842be1a..c4a8b6b 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -113,7 +113,7 @@ akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilema ); dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[tsidx].imagefilename); - FAIL_ZERO_BREAK(errctx, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image"); + FAIL_ZERO_BREAK(errctx, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError()); } CLEANUP { } PROCESS(errctx) { } FINISH(errctx, true); @@ -315,6 +315,40 @@ akerr_ErrorContext *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *roo SUCCEED_RETURN(errctx); } +akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *root, int layerid) +{ + PREPARE_ERROR(errctx); + akgl_String *tmpstr; + akgl_String *fpath; + + FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference"); + FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference"); + + ATTEMPT { + CATCH(errctx, akgl_heap_next_string(&tmpstr)); + CATCH(errctx, akgl_heap_next_string(&fpath)); + CATCH(errctx, akgl_get_json_string_value(root, "image", &tmpstr)); + + snprintf((char *)&fpath->data, + AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE, + "%s%s", + SDL_GetBasePath(), + tmpstr->data + ); + + dest->layers[layerid].texture = IMG_LoadTexture(renderer, (char *)fpath->data); + FAIL_ZERO_BREAK(errctx, dest->layers[layerid].texture, AKGL_ERR_SDL, "%s", SDL_GetError()); + dest->layers[layerid].width = dest->layers[layerid].texture->w; + dest->layers[layerid].height = dest->layers[layerid].texture->h; + } CLEANUP { + IGNORE(akgl_heap_release_string(tmpstr)); + IGNORE(akgl_heap_release_string(fpath)); + } PROCESS(errctx) { + } FINISH(errctx, true); + + SUCCEED_RETURN(errctx); +} + akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root) { PREPARE_ERROR(errctx); @@ -324,7 +358,8 @@ akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root) json_t *layer = NULL; akgl_String *tmpstr = NULL; int i; - int tmpint; + int layerid = 0; + int tmpint = 0; ATTEMPT { CATCH(errctx, akgl_get_json_array_value(root, "layers", &layers)); @@ -335,27 +370,26 @@ akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root) } CATCH(errctx, akgl_get_json_array_index_object((json_t *)layers, i, &layer)); CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "id", &tmpint)); - if ( (tmpint - 1) != i ) { - // TileD's map layer IDs start at 1, not 0, and are sequential but not necessarily contiguous. We may have a gap in IDs. - layer = NULL; - continue; - } - - CATCH(errctx, akgl_get_json_number_value((json_t *)layer, "opacity", &dest->layers[i].opacity)); - CATCH(errctx, akgl_get_json_boolean_value((json_t *)layer, "visible", &dest->layers[i].visible)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "id", &dest->layers[i].id)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "x", &dest->layers[i].x)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "y", &dest->layers[i].y)); + CATCH(errctx, akgl_get_json_number_value((json_t *)layer, "opacity", &dest->layers[layerid].opacity)); + CATCH(errctx, akgl_get_json_boolean_value((json_t *)layer, "visible", &dest->layers[layerid].visible)); + CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "id", &dest->layers[layerid].id)); + CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "x", &dest->layers[layerid].x)); + CATCH(errctx, akgl_get_json_integer_value((json_t *)layer, "y", &dest->layers[layerid].y)); CATCH(errctx, akgl_get_json_string_value((json_t *)layer, "type", &tmpstr)); + SDL_Log("Layer %d has type %s", layerid, tmpstr->data); if ( strncmp((char *)tmpstr->data, "objectgroup", strlen((char *)tmpstr->data)) == 0 ) { - dest->layers[i].type = AKGL_TILEMAP_LAYER_TYPE_OBJECTS; - CATCH(errctx, akgl_tilemap_load_layer_objects((akgl_Tilemap *)dest, (json_t *)layer, i)); + dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_OBJECTS; + CATCH(errctx, akgl_tilemap_load_layer_objects((akgl_Tilemap *)dest, (json_t *)layer, layerid)); } else if ( strncmp((char *)tmpstr->data, "tilelayer", strlen((char *)tmpstr->data)) == 0 ) { - dest->layers[i].type = AKGL_TILEMAP_LAYER_TYPE_TILES; - CATCH(errctx, akgl_tilemap_load_layer_tile((akgl_Tilemap *)dest, (json_t *)layer, i)); + dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_TILES; + CATCH(errctx, akgl_tilemap_load_layer_tile((akgl_Tilemap *)dest, (json_t *)layer, layerid)); + } else if ( strncmp((char *)tmpstr->data, "imagelayer", strlen((char *)tmpstr->data)) == 0 ) { + dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_IMAGE; + CATCH(errctx, akgl_tilemap_load_layer_image((akgl_Tilemap *)dest, (json_t *)layer, layerid)); } layer = NULL; + layerid += 1; } } CLEANUP { } PROCESS(errctx) { @@ -458,6 +492,17 @@ akerr_ErrorContext *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *map, /*SDL_Log("Rendering map into viewport from (%d, %d) to (%d, %d)", start_x, start_y, end_x, end_y);*/ + if ( map->layers[layeridx].type == AKGL_TILEMAP_LAYER_TYPE_IMAGE ) { + dest.x = 0; + dest.y = 0; + src.w = map->layers[layeridx].width; + src.h = map->layers[layeridx].height; + dest.w = map->layers[layeridx].width; + dest.h = map->layers[layeridx].height; + SDL_RenderTexture(renderer, map->layers[layeridx].texture, &src, &dest); + SUCCEED_RETURN(errctx); + } + dest.x = 0; dest.y = 0; dest.w = map->tilewidth;