diff --git a/include/akgl/SDL_GameControllerDB.h b/include/akgl/SDL_GameControllerDB.h index 41ea51d..91d0e04 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 Tue May 26 10:27:58 AM EDT 2026 +// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Tue May 26 11:21:36 AM EDT 2026 #define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228 diff --git a/include/akgl/physics.h b/include/akgl/physics.h index ccaf33b..19659ae 100644 --- a/include/akgl/physics.h +++ b/include/akgl/physics.h @@ -8,9 +8,9 @@ typedef struct akgl_PhysicsBackend { akerr_ErrorContext AKERR_NOIGNORE *(*simulate)(struct akgl_PhysicsBackend *self, akgl_Iterator *opflags); - akerr_ErrorContext AKERR_NOIGNORE *(*gravity)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); + akerr_ErrorContext AKERR_NOIGNORE *(*gravity)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); akerr_ErrorContext AKERR_NOIGNORE *(*collide)(struct akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2); - akerr_ErrorContext AKERR_NOIGNORE *(*move)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); + akerr_ErrorContext AKERR_NOIGNORE *(*move)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); double drag_x; double drag_y; @@ -23,15 +23,15 @@ typedef struct akgl_PhysicsBackend { } akgl_PhysicsBackend; -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2); -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_null(akgl_PhysicsBackend *self); -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2); -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_move(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime); +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_move(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt); akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_sidescroller(akgl_PhysicsBackend *self); diff --git a/src/actor.c b/src/actor.c index 2c587c1..c4f1283 100644 --- a/src/actor.c +++ b/src/actor.c @@ -119,12 +119,6 @@ akerr_ErrorContext *akgl_actor_logic_movement(akgl_Actor *obj, SDL_Time curtime) PREPARE_ERROR(errctx); FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "obj"); FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "obj->basechar"); - if ( obj->vx > obj->basechar->sx ) { - obj->vx = obj->basechar->sx; - } - if ( obj->vy > obj->basechar->sy ) { - obj->vy = obj->basechar->sy; - } // Effectively a NOOP, this is handled by the physics engine now // These functions are still present in case the library user wants per-actor behavior SUCCEED_RETURN(errctx); diff --git a/src/physics.c b/src/physics.c index 61a45ec..4f19855 100644 --- a/src/physics.c +++ b/src/physics.c @@ -6,7 +6,7 @@ #include #include -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime) +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt) { PREPARE_ERROR(e); FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self"); @@ -20,7 +20,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_collide(akgl_PhysicsBackend SUCCEED_RETURN(e); } -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime) +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt) { PREPARE_ERROR(e); FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self"); @@ -41,7 +41,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_null(akgl_PhysicsBackend *s } -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime) +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt) { PREPARE_ERROR(e); FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self"); @@ -51,14 +51,14 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_gravity(akgl_PhysicsBackend * //Gravity is applied in units per second. So we apply // (unit / milliseconds per second) * (milliseconds since last update) - actor->vx += ((self->gravity_x / AKGL_TIME_ONESEC_NS) * (curtime - self->gravity_time)); - actor->vy += ((self->gravity_y / AKGL_TIME_ONESEC_NS) * (curtime - self->gravity_time)); - actor->vz += ((self->gravity_z / AKGL_TIME_ONESEC_NS) * (curtime - self->gravity_time)); + actor->vx += self->gravity_x * dt; + actor->vy += self->gravity_y * dt; + actor->vz += self->gravity_z * dt; // Apply atmospheric drag - actor->vx -= actor->vx * self->drag_x * (curtime - self->gravity_time); - actor->vy -= actor->vy * self->drag_x * (curtime - self->gravity_time); - actor->vz -= actor->vz * self->drag_x * (curtime - self->gravity_time); + actor->vx -= actor->vx * self->drag_x * dt; + actor->vy -= actor->vy * self->drag_y * dt; + actor->vz -= actor->vz * self->drag_z * dt; // Need a euler function SUCCEED_RETURN(e); } @@ -71,42 +71,24 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_collide(akgl_PhysicsBackend * SUCCEED_RETURN(e); } -akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, SDL_Time curtime) +akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_ss_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt) { PREPARE_ERROR(e); FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self"); FAIL_ZERO_RETURN(e, actor, AKERR_NULLPOINTER, "actor"); - - if ( actor->parent != NULL ) { - // Children don't move independently of their parents, they just have an offset - SUCCEED_RETURN(e); - } else if ( actor->basechar == NULL ) { - SUCCEED_RETURN(e); - } else { - if ( (curtime - actor->movetimer) >= actor->basechar->speedtime ) { - actor->movetimer = curtime; - ATTEMPT { - CATCH(e, actor->movementlogicfunc(actor,curtime)); - } CLEANUP { - } PROCESS(e) { - } HANDLE(e, AKGL_ERR_LOGICINTERRUPT) { - // The actor told us NOT to process them, they handled their own update - SUCCEED_RETURN(e); - } FINISH(e, true); - if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_LEFT) ) { - actor->x += -actor->vx; - } - if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) { - actor->x += actor->vx; - } - if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_UP) ) { - actor->y += -actor->vy; - } - if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) { - actor->y += actor->vy; - } - } + if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_LEFT) ) { + actor->x += -actor->vx; } + if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) { + actor->x += actor->vx; + } + if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_UP) ) { + actor->y += -actor->vy; + } + if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) { + actor->y += actor->vy; + } + SUCCEED_RETURN(e); } @@ -151,6 +133,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_simulate(akgl_PhysicsBackend *se .layerid = 0 }; SDL_Time curtime = SDL_GetTicksNS(); + float32_t dt = (curtime - self->gravity_time) / AKGL_TIME_ONESEC_NS; akgl_Actor *actor = NULL; FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self"); @@ -160,11 +143,18 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_simulate(akgl_PhysicsBackend *se opflags = &defflags; } + for ( int i = 0; i < AKGL_MAX_HEAP_ACTOR; i++ ) { actor = &HEAP_ACTOR[i]; if ( actor->refcount == 0 ) { continue; } + if ( actor->parent != NULL ) { + // Children don't move independently of their parents, they just have an offset + continue; + } else if ( actor->basechar == NULL ) { + continue; + } if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_LAYERMASK) ) { if ( actor->layer != opflags->layerid ) { continue; @@ -172,15 +162,21 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_simulate(akgl_PhysicsBackend *se } if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_LEFT) || AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) { - actor->vx += actor->basechar->ax; + actor->vx += actor->basechar->ax * dt; } if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_UP) || AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) { - actor->vy += actor->basechar->ay; + actor->vy += actor->basechar->ay * dt; } - PASS(e, self->gravity(self, actor, curtime)); - PASS(e, self->move(self, actor, curtime)); - self->gravity_time = curtime; + if ( actor->vx > actor->basechar->sx ) { + actor->vx = actor->basechar->sx; + } + if ( actor->vy > actor->basechar->sy ) { + actor->vy = actor->basechar->sy; + } + //PASS(e, self->gravity(self, actor, dt)); + PASS(e, self->move(self, actor, dt)); } + self->gravity_time = curtime; SUCCEED_RETURN(e); }