diff --git a/src/dusk/assert/assert.c b/src/dusk/assert/assert.c index 15bb8b5..31cbba0 100644 --- a/src/dusk/assert/assert.c +++ b/src/dusk/assert/assert.c @@ -80,4 +80,45 @@ void assertDeprecatedImpl( const char *message ) { assertUnreachableImpl(file, line, message); +} + +void assertMemoryRangeMatchesImpl( + const char *file, + const int32_t line, + const void *start, + const void *end, + const size_t size, + const char *message +) { + assertTrueImpl( + file, + line, + start != NULL, + "Start pointer is NULL" + ); + assertTrueImpl( + file, + line, + end != NULL, + "End pointer is NULL" + ); + assertTrueImpl( + file, + line, + size > 0, + "Size is 0" + ); + assertTrueImpl( + file, + line, + start < end, + "Start pointer is not before end pointer" + ); + + assertTrueImpl( + file, + line, + ((uintptr_t)end - (uintptr_t)start) == size, + message + ); } \ No newline at end of file diff --git a/src/dusk/assert/assert.h b/src/dusk/assert/assert.h index 228eb96..88b2e25 100644 --- a/src/dusk/assert/assert.h +++ b/src/dusk/assert/assert.h @@ -95,6 +95,15 @@ void assertDeprecatedImpl( const char *message ); +void assertMemoryRangeMatchesImpl( + const char *file, + const int32_t line, + const void *start, + const void *end, + const size_t size, + const char *message +); + #define assertTrue(x, message) \ assertTrueImpl(__FILE__, __LINE__, x, message) @@ -119,4 +128,5 @@ void assertDeprecatedImpl( #define assertStrLenMin(str, len, message) \ assertTrue(strlen(str) >= len, message) -// EOF \ No newline at end of file +#define assertMemoryRangeMatches(start, end, size, message) \ + assertMemoryRangeMatchesImpl(__FILE__, __LINE__, start, end, size, message) diff --git a/src/dusk/overworld/entity.c b/src/dusk/overworld/entity.c index a3bd148..fc337f2 100644 --- a/src/dusk/overworld/entity.c +++ b/src/dusk/overworld/entity.c @@ -7,6 +7,7 @@ #include "entity.h" #include "assert/assert.h" +#include "overworlddefs.h" entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = { { NULL, NULL }, @@ -37,4 +38,59 @@ void entityUpdate(entity_t *ent) { assertNotNull(ENTITY_CALLBACKS[ent->type].update, "Entity type update err."); ENTITY_CALLBACKS[ent->type].update(ent); + + // Handle moving + if(ent->subX > 0) { + ent->subX -= ENTITY_MOVE_SPEED; + if(ent->subX < 0) ent->subX = 0; + } else if(ent->subX < 0) { + ent->subX += ENTITY_MOVE_SPEED; + if(ent->subX > 0) ent->subX = 0; + } else if(ent->subY > 0) { + ent->subY -= ENTITY_MOVE_SPEED; + if(ent->subY < 0) ent->subY = 0; + } else if(ent->subY < 0) { + ent->subY += ENTITY_MOVE_SPEED; + if(ent->subY > 0) ent->subY = 0; + } +} + +void entityTurn(entity_t *ent, const facingdir_t dir) { + assertNotNull(ent, "Entity cannot be NULL"); + assertTrue(dir < FACING_DIRECTION_COUNT, "Invalid facing direction"); + + ent->direction = dir; +} + +void entityMove(entity_t *ent, const facingdir_t dir) { + assertNotNull(ent, "Entity cannot be NULL"); + + entityTurn(ent, dir); + + // Move + switch(dir) { + case FACING_DIRECTION_EAST: + ent->x++; + ent->subX = -OVERWORLD_ENTITY_WIDTH; + break; + case FACING_DIRECTION_WEST: + ent->x--; + ent->subX = OVERWORLD_ENTITY_WIDTH; + break; + case FACING_DIRECTION_NORTH: + ent->y++; + ent->subY = -OVERWORLD_ENTITY_HEIGHT; + break; + case FACING_DIRECTION_SOUTH: + ent->y--; + ent->subY = OVERWORLD_ENTITY_HEIGHT; + break; + default: + assertUnreachable("Invalid facing direction"); + } +} + +bool entityIsMoving(const entity_t *ent) { + assertNotNull(ent, "Entity cannot be NULL"); + return ent->subX != 0 || ent->subY != 0; } \ No newline at end of file diff --git a/src/dusk/overworld/entity.h b/src/dusk/overworld/entity.h index 5c55a66..bcd421b 100644 --- a/src/dusk/overworld/entity.h +++ b/src/dusk/overworld/entity.h @@ -26,10 +26,11 @@ typedef enum { FACING_DIRECTION_NORTH, FACING_DIRECTION_WEST } facingdir_t; +#define FACING_DIRECTION_COUNT 4 typedef struct _entity_t { uint8_t x, y; - uint8_t subX, subY; + int8_t subX, subY; facingdir_t direction; entitytype_t type; @@ -38,6 +39,8 @@ typedef struct _entity_t { }; } entity_t; +#define ENTITY_MOVE_SPEED 4 + /** * Initializes an entity. * @@ -54,4 +57,28 @@ void entityInit( * * @param entity The entity to update. */ -void entityUpdate(entity_t *entity); \ No newline at end of file +void entityUpdate(entity_t *entity); + +/** + * Turns an entity in a given direction. + * + * @param entity The entity to turn. + * @param dir The direction to turn the entity. + */ +void entityTurn(entity_t *entity, const facingdir_t dir); + +/** + * Moves an entity in a given direction. + * + * @param entity The entity to move. + * @param dir The direction to move the entity. + */ +void entityMove(entity_t *entity, const facingdir_t dir); + +/** + * Checks if an entity is moving. + * + * @param entity The entity to check. + * @return TRUE if the entity is moving, FALSE otherwise. + */ +bool_t entityIsMoving(const entity_t *entity); \ No newline at end of file diff --git a/src/dusk/overworld/player.c b/src/dusk/overworld/player.c index 2ff8905..72b02d7 100644 --- a/src/dusk/overworld/player.c +++ b/src/dusk/overworld/player.c @@ -19,12 +19,12 @@ void playerUpdate(entity_t *ent) { assertNotNull(ent, "Entity cannot be NULL"); if(inputWasPressed(INPUT_RIGHT)) { - ent->x++; + entityMove(ent, FACING_DIRECTION_EAST); } else if(inputWasPressed(INPUT_LEFT)) { - ent->x--; + entityMove(ent, FACING_DIRECTION_WEST); } else if(inputWasPressed(INPUT_UP)) { - ent->y--; + entityMove(ent, FACING_DIRECTION_NORTH); } else if(inputWasPressed(INPUT_DOWN)) { - ent->y++; + entityMove(ent, FACING_DIRECTION_SOUTH); } } \ No newline at end of file diff --git a/src/duskgl/display/shader/data/entities.c b/src/duskgl/display/shader/data/entities.c index 1a2f7ec..cf42929 100644 --- a/src/duskgl/display/shader/data/entities.c +++ b/src/duskgl/display/shader/data/entities.c @@ -27,8 +27,10 @@ void entitiesUpdate() { entitiesdataent_t *dst = &ENTITIES_DATA.entities[i]; // Copy position data. - assertTrue( - (&src->subY - &src->x) + sizeof(uint8_t) == sizeof(uint_t), + assertMemoryRangeMatches( + &src->x, + &src->direction, + sizeof(uint_t), "Entity data is not packed correctly any more." ); memcpy(&dst->position, &src->x, sizeof(uint_t)); diff --git a/src/duskgl/display/shader/data/entities.glsl b/src/duskgl/display/shader/data/entities.glsl index 91c731b..04124d3 100644 --- a/src/duskgl/display/shader/data/entities.glsl +++ b/src/duskgl/display/shader/data/entities.glsl @@ -26,8 +26,8 @@ vec2 entityGetVertice(uint instanceIndex, uint indiceIndex) { uint x = packedGetU8(0u, entities[instanceIndex].position); uint y = packedGetU8(1u, entities[instanceIndex].position); - uint subX = packedGetU8(2u, entities[instanceIndex].position); - uint subY = packedGetU8(3u, entities[instanceIndex].position); + int subX = packedGetI8(2u, entities[instanceIndex].position); + int subY = packedGetI8(3u, entities[instanceIndex].position); vert.x += float(x); vert.y += float(y); diff --git a/src/duskgl/display/shader/fragments/packed.glsl b/src/duskgl/display/shader/fragments/packed.glsl index ff71d4a..7496c2d 100644 --- a/src/duskgl/display/shader/fragments/packed.glsl +++ b/src/duskgl/display/shader/fragments/packed.glsl @@ -5,4 +5,9 @@ uint packedGetU8(uint position, uint data) { return (data >> (position * 8u)) & 0xFFu; +} + +int packedGetI8(uint position, uint data) { + int shift = int(position * 8u); + return int(data << (24 - shift)) >> 24; } \ No newline at end of file