From 284ffd7b4a2a4449a96bc6b5e016c5ce89f6f8a2 Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Tue, 5 May 2026 20:39:58 -0400 Subject: [PATCH] Fix missing sdl3game.pc for pkg-config, change sprite speed and character movement values to long int expressed in nanoseconds for better compatibility with SDL_Time and locking against game clock, still expressed as milliseconds in json --- CMakeLists.txt | 7 +++++++ include/sdl3game/SDL_GameControllerDB.h | 2 +- include/sdl3game/actor.h | 2 +- include/sdl3game/character.h | 2 +- include/sdl3game/sprite.h | 2 +- src/actor.c | 18 ++++++++---------- src/character.c | 2 ++ src/sprite.c | 3 ++- tests/sprite.c | 2 +- 9 files changed, 24 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2946fe8..93775ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,11 @@ find_package(box2d REQUIRED) #pkg_check_modules(akerror REQUIRED akerror) set(GAMECONTROLLERDB_H "include/sdl3game/SDL_GameControllerDB.h") +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/lib") +set(includedir "\${prefix}/include") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sdl3game.pc.in ${CMAKE_CURRENT_BINARY_DIR}/sdl3game.pc @ONLY) add_custom_command( OUTPUT ${GAMECONTROLLERDB_H} @@ -90,10 +95,12 @@ target_link_libraries(test_util PRIVATE akerror::akerror sdl3game SDL3::SDL3 SDL target_link_libraries(charviewer PRIVATE akerror::akerror sdl3game SDL3::SDL3 SDL3_image::SDL3_image SDL3_mixer::SDL3_mixer box2d::box2d jansson::jansson -lm) set(main_lib_dest "lib/sdl3game-${MY_LIBRARY_VERSION}") +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl3game.pc DESTINATION "lib/pkgconfig/") install(TARGETS sdl3game DESTINATION "lib/") install(FILES "include/sdl3game/actor.h" DESTINATION "include/sdl3game/") install(FILES "include/sdl3game/assets.h" DESTINATION "include/sdl3game/") install(FILES "include/sdl3game/character.h" DESTINATION "include/sdl3game/") +install(FILES "include/sdl3game/error.h" DESTINATION "include/sdl3game/") install(FILES "include/sdl3game/draw.h" DESTINATION "include/sdl3game/") install(FILES "include/sdl3game/game.h" DESTINATION "include/sdl3game/") install(FILES "include/sdl3game/controller.h" DESTINATION "include/sdl3game/") diff --git a/include/sdl3game/SDL_GameControllerDB.h b/include/sdl3game/SDL_GameControllerDB.h index 5b4d2e0..368f07a 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 Sun May 3 11:38:30 PM EDT 2026 +// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Tue May 5 08:39:19 PM EDT 2026 #define SDL_GAMECONTROLLER_DB_LEN 2225 diff --git a/include/sdl3game/actor.h b/include/sdl3game/actor.h index e1f9045..5bdaa9d 100644 --- a/include/sdl3game/actor.h +++ b/include/sdl3game/actor.h @@ -68,7 +68,7 @@ typedef struct actor { bool movement_controls_face; void *actorData; bool visible; - int logictimer; + SDL_Time logictimer; float x; float y; struct actor *children[ACTOR_MAX_CHILDREN]; diff --git a/include/sdl3game/character.h b/include/sdl3game/character.h index 7a4ccbf..db1efe0 100644 --- a/include/sdl3game/character.h +++ b/include/sdl3game/character.h @@ -13,7 +13,7 @@ typedef struct character { SDL_PropertiesID state_sprites; akerr_ErrorContext AKERR_NOIGNORE *(*sprite_add)(struct character *, sprite *, int); akerr_ErrorContext AKERR_NOIGNORE *(*sprite_get)(struct character *, int, sprite **); - int movementspeed; + long int movementspeed; float vx; float vy; } character; diff --git a/include/sdl3game/sprite.h b/include/sdl3game/sprite.h index f5b797f..0e3d19e 100644 --- a/include/sdl3game/sprite.h +++ b/include/sdl3game/sprite.h @@ -29,7 +29,7 @@ typedef struct { int frames; // how many frames are in this animation int width; int height; - int speed; // how many milliseconds a given sprite frame should be visible before cycling + long int speed; // how many milliseconds a given sprite frame should be visible before cycling bool loop; // when this sprite is done playing, it should immediately start again bool loopReverse; // when this sprite is done playing, it should go in reverse order through its frames char name[SPRITE_MAX_NAME_LENGTH]; diff --git a/src/actor.c b/src/actor.c index 6351274..3e5b2f4 100644 --- a/src/actor.c +++ b/src/actor.c @@ -76,7 +76,7 @@ akerr_ErrorContext *actor_automatic_face(actor *obj) SUCCEED_RETURN(errctx); } -akerr_ErrorContext *actor_logic_changeframe(actor *obj, sprite *curSprite, SDL_Time curtimems) +akerr_ErrorContext *actor_logic_changeframe(actor *obj, sprite *curSprite, SDL_Time curtime) { PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "Null actor reference"); @@ -111,7 +111,7 @@ akerr_ErrorContext *actor_logic_changeframe(actor *obj, sprite *curSprite, SDL_T SUCCEED_RETURN(errctx); } -akerr_ErrorContext *actor_logic_movement(actor *obj, SDL_Time curtimems) +akerr_ErrorContext *actor_logic_movement(actor *obj, SDL_Time curtime) { PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "Null actor reference"); @@ -139,7 +139,6 @@ akerr_ErrorContext *actor_update(actor *obj) { PREPARE_ERROR(errctx); SDL_Time curtime = 0; - SDL_Time curtimems = 0; sprite *curSprite = NULL; FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor reference"); @@ -147,12 +146,11 @@ akerr_ErrorContext *actor_update(actor *obj) ATTEMPT { SDL_GetCurrentTime(&curtime); - curtimems = curtime / 1000000; CATCH(errctx, obj->facefunc(obj)); // is it time to apply movement logic? - if ( (curtimems - obj->logictimer) >= obj->basechar->movementspeed ) { - CATCH(errctx, obj->movementlogicfunc(obj, curtimems)); - obj->logictimer = curtimems; + if ( (curtime - obj->logictimer) >= obj->basechar->movementspeed ) { + CATCH(errctx, obj->movementlogicfunc(obj, curtime)); + obj->logictimer = curtime; } } CLEANUP { } PROCESS(errctx) { @@ -161,9 +159,9 @@ akerr_ErrorContext *actor_update(actor *obj) ATTEMPT { CATCH(errctx, character_sprite_get(obj->basechar, obj->state, &curSprite)); // is it time to change frames? - if ( (curtimems - obj->curSpriteFrameTimer) >= curSprite->speed ) { - CATCH(errctx, obj->changeframefunc(obj, curSprite, curtimems)); - obj->curSpriteFrameTimer = curtimems; + if ( ((curtime) - obj->curSpriteFrameTimer) >= curSprite->speed) { + CATCH(errctx, obj->changeframefunc(obj, curSprite, curtime)); + obj->curSpriteFrameTimer = curtime; } } CLEANUP { } PROCESS(errctx) { diff --git a/src/character.c b/src/character.c index 60db76a..e8d0f99 100644 --- a/src/character.c +++ b/src/character.c @@ -185,6 +185,8 @@ akerr_ErrorContext *character_load_json(char *filename) "Error while loading character from %s on line %d: %s", filename, error.line, error.text ); CATCH(errctx, character_load_json_inner(json, obj)); + CATCH(errctx, get_json_integer_value(json, "movementspeed", (int *)&obj->movementspeed)); + obj->movementspeed = obj->movementspeed * 1000000; CATCH(errctx, get_json_number_value(json, "velocity_x", &obj->vx)); CATCH(errctx, get_json_number_value(json, "velocity_y", &obj->vy)); } CLEANUP { diff --git a/src/sprite.c b/src/sprite.c index 1178cc4..1173119 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -98,7 +98,8 @@ akerr_ErrorContext *sprite_load_json(char *filename) CATCH(errctx, get_json_integer_value((json_t *)json, "width", &obj->width)); CATCH(errctx, get_json_integer_value((json_t *)json, "height", &obj->height)); - CATCH(errctx, get_json_integer_value((json_t *)json, "speed", &obj->speed)); + CATCH(errctx, get_json_integer_value((json_t *)json, "speed", (int *)&obj->speed)); + obj->speed = obj->speed * 1000000; CATCH(errctx, get_json_boolean_value((json_t *)json, "loop", &obj->loop)); CATCH(errctx, get_json_boolean_value((json_t *)json, "loopReverse", &obj->loopReverse)); diff --git a/tests/sprite.c b/tests/sprite.c index b54b611..43bbaef 100644 --- a/tests/sprite.c +++ b/tests/sprite.c @@ -126,7 +126,7 @@ akerr_ErrorContext *test_sprite_load_json(void) FAIL_ZERO_BREAK(errctx, (testsprite->width == 48), AKERR_VALUE, "width incorrect (48 : %d)", testsprite->width); FAIL_ZERO_BREAK(errctx, (testsprite->height == 48), AKERR_VALUE, "height incorrect (48 : %d)", testsprite->height); - FAIL_ZERO_BREAK(errctx, (testsprite->speed == 100), AKERR_VALUE, "speed incorrect (100 : %d)", testsprite->speed); + FAIL_ZERO_BREAK(errctx, (testsprite->speed == 100000000), AKERR_VALUE, "speed incorrect (100 : %ld)", testsprite->speed); FAIL_ZERO_BREAK(errctx, (testsprite->loop == true), AKERR_VALUE, "loop incorrect (1 : %d)", testsprite->loop); FAIL_ZERO_BREAK(errctx, (testsprite->loopReverse == true), AKERR_VALUE, "loopReverse incorrect (1 : %d)", testsprite->loopReverse); FAIL_ZERO_BREAK(errctx, (testsprite->frames == 3), AKERR_VALUE, "frame count incorrect (3 : %d)", testsprite->frames);