From a2fd58fda777a17c55abd0cdc8ffb5c5cff0db23 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 8 Jun 2025 18:32:36 -0500 Subject: [PATCH] input --- src/input.c | 17 ++++++++++++++ src/input.h | 34 +++++++++++++++++++++++++++- src/main.c | 10 +++++++-- src/rpg/entity/entity.c | 49 +++++++++++++++++++++++++++++++++++++++++ src/rpg/entity/entity.h | 25 +++++++++++++++++++++ src/rpg/entity/player.c | 23 +++++++++++++++++++ 6 files changed, 155 insertions(+), 3 deletions(-) diff --git a/src/input.c b/src/input.c index 8907c3e..8fef90f 100644 --- a/src/input.c +++ b/src/input.c @@ -91,6 +91,7 @@ void inputUpdate() { // Button was pressed val |= map->value; i += len - 1; + break; } while(map->key); } @@ -98,6 +99,22 @@ void inputUpdate() { INPUT.current = val; } +bool_t inputIsDown(const uint8_t key) { + return (INPUT.current & key) != 0; +} + +bool_t inputWasDown(const uint8_t key) { + return (INPUT.previous & key) != 0; +} + +bool_t inputWasPressed(const uint8_t key) { + return inputIsDown(key) && !inputWasDown(key); +} + +bool_t inputWasReleased(const uint8_t key) { + return !inputIsDown(key) && inputWasDown(key); +} + void inputDispose() { inputDisableRawMode(); } \ No newline at end of file diff --git a/src/input.h b/src/input.h index d66b54a..96591c2 100644 --- a/src/input.h +++ b/src/input.h @@ -42,4 +42,36 @@ void inputInit(); /** * Updates the input system. */ -void inputUpdate(); \ No newline at end of file +void inputUpdate(); + +/** + * Returns true if the specified key is currently pressed down. + * + * @param key The key to check. + * @return True if the key is down, false otherwise. + */ +bool_t inputIsDown(const uint8_t key); + +/** + * Returns true if the specified key was pressed down in the previous frame. + * + * @param key The key to check. + * @return True if the key was down in the previous frame, false otherwise. + */ +bool_t inputWasDown(const uint8_t key); + +/** + * Returns true if the specified key was pressed in the current frame. + * + * @param key The key to check. + * @return True if the key was pressed, false otherwise. + */ +bool_t inputWasPressed(const uint8_t key); + +/** + * Returns true if the specified key was released in the current frame. + * + * @param key The key to check. + * @return True if the key was released, false otherwise. + */ +bool_t inputWasReleased(const uint8_t key); \ No newline at end of file diff --git a/src/main.c b/src/main.c index f02bb6c..905744a 100644 --- a/src/main.c +++ b/src/main.c @@ -33,8 +33,14 @@ int32_t main(const int32_t argc, const char **argv) { entityUpdate(ent++); } while(ent < (ENTITIES + ENTITY_COUNT)); - renderUpdate(); - usleep(100 * 1000); // Sleep for 16 milliseconds (60 FPS) + if(inputIsDown(INPUT_DOWN)) { + printf("Input down pressed\n"); + } else { + printf("Input down not pressed\n"); + } + + // renderUpdate(); + usleep(16 * 1000); // Sleep for 16 milliseconds (60 FPS) } return EXIT_SUCCESS; diff --git a/src/rpg/entity/entity.c b/src/rpg/entity/entity.c index 2557782..5b035a0 100644 --- a/src/rpg/entity/entity.c +++ b/src/rpg/entity/entity.c @@ -39,9 +39,58 @@ void entityUpdate(entity_t *entity) { "Entity type has no update" ); + // Handle subpixel movement + if(entity->subX < 0) { + entity->subX++; + } else if(entity->subY < 0) { + entity->subY++; + } else if(entity->subX > 0) { + entity->subX--; + } else if(entity->subY > 0) { + entity->subY--; + } + + // Entity-Type handling ENTITY_CALLBACKS[entity->type].update(entity); } +void entityTurn(entity_t *entity, const entitydir_t dir) { + assertNotNull(entity, "Entity cannot be NULL"); + assertFalse(entityIsWalking(entity), "Entity is currently walking"); + entity->dir = dir; +} + +void entityWalk(entity_t *entity) { + assertNotNull(entity, "Entity cannot be NULL"); + assertFalse(entityIsWalking(entity), "Entity is already walking"); + + switch(entity->dir) { + case ENTITY_DIR_UP: + entity->y--; + entity->subY = ENTITY_MOVE_SUBPIXEL; + break; + case ENTITY_DIR_DOWN: + entity->y++; + entity->subY = -ENTITY_MOVE_SUBPIXEL; + break; + case ENTITY_DIR_LEFT: + entity->x--; + entity->subX = ENTITY_MOVE_SUBPIXEL; + break; + case ENTITY_DIR_RIGHT: + entity->x++; + entity->subX = -ENTITY_MOVE_SUBPIXEL; + break; + default: + assertUnreachable("Invalid entity direction"); + } +} + +bool_t entityIsWalking(const entity_t *entity) { + assertNotNull(entity, "Entity cannot be NULL"); + return (entity->subX != 0 || entity->subY != 0); +} + entity_t * entityGetAt(const uint8_t x, const uint8_t y) { entity_t *e = ENTITIES; do { diff --git a/src/rpg/entity/entity.h b/src/rpg/entity/entity.h index 31b5316..a56e927 100644 --- a/src/rpg/entity/entity.h +++ b/src/rpg/entity/entity.h @@ -8,6 +8,8 @@ #pragma once #include "player.h" +#define ENTITY_MOVE_SUBPIXEL 4 + typedef enum { ENTITY_DIR_UP = 0, ENTITY_DIR_DOWN = 1, @@ -62,6 +64,29 @@ void entityInit(entity_t *entity, const entitytype_t type); */ void entityUpdate(entity_t *entity); +/** + * Turns the entity to face a specific direction. + * + * @param entity Pointer to the entity to turn. + * @param dir The direction to turn the entity towards. + */ +void entityTurn(entity_t *entity, const entitydir_t dir); + +/** + * Makes the entity walk in the current direction. + * + * @param entity Pointer to the entity to make walk. + */ +void entityWalk(entity_t *entity); + +/** + * Checks if the entity is currently mid-walking. + * + * @param entity Pointer to the entity to check. + * @return true if the entity is walking, false otherwise. + */ +bool_t entityIsWalking(const entity_t *entity); + /** * Resets the entity at a given position. * diff --git a/src/rpg/entity/player.c b/src/rpg/entity/player.c index d92b8e3..6a89760 100644 --- a/src/rpg/entity/player.c +++ b/src/rpg/entity/player.c @@ -7,6 +7,7 @@ #include "entity.h" #include "assert/assert.h" +#include "input.h" void playerInit(entity_t *player) { assertNotNull(player, "Player entity is NULL"); @@ -16,4 +17,26 @@ void playerInit(entity_t *player) { void playerUpdate(entity_t *entity) { assertNotNull(entity, "Entity is NULL"); assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity is not a player"); + + if(!entityIsWalking(entity)) { + entitydir_t dir = 0xFF; + if(inputIsDown(INPUT_UP)) { + dir = ENTITY_DIR_UP; + } else if(inputIsDown(INPUT_DOWN)) { + dir = ENTITY_DIR_DOWN; + } else if(inputIsDown(INPUT_LEFT)) { + dir = ENTITY_DIR_LEFT; + } else if(inputIsDown(INPUT_RIGHT)) { + dir = ENTITY_DIR_RIGHT; + } + + if(dir != 0xFF) { + if(dir != entity->dir) { + entityTurn(entity, dir); + } else { + entityWalk(entity); + } + } + } + } \ No newline at end of file