Change entity to use fixed_t

This commit is contained in:
2025-06-18 14:06:03 -05:00
parent c9f795e55c
commit 9a306df7e5
12 changed files with 329 additions and 32 deletions

View File

@ -8,6 +8,7 @@
#pragma once
#include "player.h"
#include "npc.h"
#include "util/fixed.h"
#define ENTITY_COUNT_MAX 32
@ -32,7 +33,8 @@ typedef enum {
typedef struct _entity_t {
uint32_t id;// Completely unique ID for this entity.
float_t x, y;
fixed248_t x, y;
fixed248_t vx, vy;
entitytype_t type;
entitydir_t dir;

View File

@ -17,8 +17,8 @@ void playerInit() {
entityInit(ent, ENTITY_TYPE_PLAYER);
ent->id = PLAYER_ENTITY_ID;
ent->x = WORLD_PLAYER_SPAWN_X;
ent->y = WORLD_PLAYER_SPAWN_Y;
ent->x = fx248Fromui32(WORLD_PLAYER_SPAWN_X);
ent->y = fx248Fromui32(WORLD_PLAYER_SPAWN_Y);
}
void playerNPCInit(entity_t *entity) {
@ -32,47 +32,47 @@ void playerNPCUpdate(entity_t *entity) {
if(inputIsDown(INPUT_BIND_UP)) {
if(inputIsDown(INPUT_BIND_LEFT)) {
entity->x -= PLAYER_MOVE_SPEED_XY;
entity->y -= PLAYER_MOVE_SPEED_XY;
fx248Subfx248(&entity->x, PLAYER_MOVE_SPEED_XY);
fx248Subfx248(&entity->y, PLAYER_MOVE_SPEED_XY);
if(entity->dir != ENTITY_DIR_NORTH && entity->dir != ENTITY_DIR_WEST) {
entity->dir = ENTITY_DIR_NORTH;
}
} else if(inputIsDown(INPUT_BIND_RIGHT)) {
entity->x += PLAYER_MOVE_SPEED_XY;
entity->y -= PLAYER_MOVE_SPEED_XY;
fx248Addfx248(&entity->x, PLAYER_MOVE_SPEED_XY);
fx248Subfx248(&entity->y, PLAYER_MOVE_SPEED_XY);
if(entity->dir != ENTITY_DIR_NORTH && entity->dir != ENTITY_DIR_EAST) {
entity->dir = ENTITY_DIR_NORTH;
}
} else {
entity->y -= PLAYER_MOVE_SPEED;
fx248Subfx248(&entity->y, PLAYER_MOVE_SPEED);
entity->dir = ENTITY_DIR_NORTH;
}
} else if(inputIsDown(INPUT_BIND_DOWN)) {
if(inputIsDown(INPUT_BIND_LEFT)) {
entity->x -= PLAYER_MOVE_SPEED_XY;
entity->y += PLAYER_MOVE_SPEED_XY;
fx248Subfx248(&entity->x, PLAYER_MOVE_SPEED_XY);
fx248Addfx248(&entity->y, PLAYER_MOVE_SPEED_XY);
if(entity->dir != ENTITY_DIR_SOUTH && entity->dir != ENTITY_DIR_WEST) {
entity->dir = ENTITY_DIR_SOUTH;
}
} else if(inputIsDown(INPUT_BIND_RIGHT)) {
entity->x += PLAYER_MOVE_SPEED_XY;
entity->y += PLAYER_MOVE_SPEED_XY;
fx248Addfx248(&entity->x, PLAYER_MOVE_SPEED_XY);
fx248Addfx248(&entity->y, PLAYER_MOVE_SPEED_XY);
if(entity->dir != ENTITY_DIR_SOUTH && entity->dir != ENTITY_DIR_EAST) {
entity->dir = ENTITY_DIR_SOUTH;
}
} else {
entity->y += PLAYER_MOVE_SPEED;
fx248Addfx248(&entity->y, PLAYER_MOVE_SPEED);
entity->dir = ENTITY_DIR_SOUTH;
}
} else if(inputIsDown(INPUT_BIND_LEFT)) {
entity->x -= PLAYER_MOVE_SPEED;
fx248Subfx248(&entity->x, PLAYER_MOVE_SPEED);
entity->dir = ENTITY_DIR_WEST;
} else if(inputIsDown(INPUT_BIND_RIGHT)) {
entity->x += PLAYER_MOVE_SPEED;
fx248Addfx248(&entity->x, PLAYER_MOVE_SPEED);
entity->dir = ENTITY_DIR_EAST;
}
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "dusk.h"
#include "util/fixed.h"
typedef struct _entity_t entity_t;
@ -15,8 +16,8 @@ typedef struct {
} playerentity_t;
#define PLAYER_ENTITY_ID (UINT32_MAX-1)
#define PLAYER_MOVE_SPEED 1.0f
#define PLAYER_MOVE_SPEED_XY (PLAYER_MOVE_SPEED * 0.70710678118f)
#define PLAYER_MOVE_SPEED FIXED248(1, 0)
#define PLAYER_MOVE_SPEED_XY FIXED248(0, 70)
/**
* Initializes the player and all player-related entities.

View File

@ -6,5 +6,6 @@
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
fixed.c
memory.c
)

92
src/dusk/util/fixed.c Normal file
View File

@ -0,0 +1,92 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "fixed.h"
fixed248_t fx248Fromi32(const int32_t b) {
return (fixed248_t)b << FIXED248_FRACTION_BITS;
}
fixed248_t fx248Fromui32(const uint32_t b) {
return (fixed248_t)b << FIXED248_FRACTION_BITS;
}
fixed248_t fx248Fromf32(const float_t b) {
return (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS));
}
int32_t fx248Toi32(const fixed248_t a) {
return (int32_t)(a >> FIXED248_FRACTION_BITS);
}
uint32_t fx248Tou32(const fixed248_t a) {
return (uint32_t)(a >> FIXED248_FRACTION_BITS);
}
float_t fx248Tof32(const fixed248_t a) {
return (float_t)(a / (1 << FIXED248_FRACTION_BITS));
}
void fx248Addfx248(fixed248_t *a, const fixed248_t b) {
*a += b;
}
void fx248Addi32(fixed248_t *a, const int32_t b) {
*a += (fixed248_t)b << FIXED248_FRACTION_BITS;
}
void fx248Addui32(fixed248_t *a, const uint32_t b) {
*a += (fixed248_t)b << FIXED248_FRACTION_BITS;
}
void fx248Subfx248(fixed248_t *a, const fixed248_t b) {
*a -= b;
}
void fx248Subi32(fixed248_t *a, const int32_t b) {
*a -= (fixed248_t)b << FIXED248_FRACTION_BITS;
}
void fx248Subui32(fixed248_t *a, const uint32_t b) {
*a -= (fixed248_t)b << FIXED248_FRACTION_BITS;
}
void fx248Subf32(fixed248_t *a, const float_t b) {
*a -= (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS));
}
int32_t fx248Floor(const fixed248_t a) {
return (int32_t)(a >> FIXED248_FRACTION_BITS);
}
int32_t fx248Ceil(const fixed248_t a) {
return (int32_t)((
a + ((1 << FIXED248_FRACTION_BITS) - 1)
) >> FIXED248_FRACTION_BITS);
}
int32_t fx248Round(const fixed248_t a) {
return (int32_t)(
(a + (1 << (FIXED248_FRACTION_BITS - 1))
) >> FIXED248_FRACTION_BITS);
}
uint32_t fx248Flooru32(const fixed248_t a) {
return (uint32_t)(a >> FIXED248_FRACTION_BITS);
}
uint32_t fx248Ceilu32(const fixed248_t a) {
return (uint32_t)((
a + ((1 << FIXED248_FRACTION_BITS) - 1)
) >> FIXED248_FRACTION_BITS);
}
uint32_t fx248Roundu32(const fixed248_t a) {
return (uint32_t)(
(a + (1 << (FIXED248_FRACTION_BITS - 1))
) >> FIXED248_FRACTION_BITS);
}

182
src/dusk/util/fixed.h Normal file
View File

@ -0,0 +1,182 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef uint32_t fixed248_t;
#define FIXED248_FRACTION_BITS 8
#define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS)
#define FIXED248(i, f) ((fixed248_t)( \
((i) << FIXED248_FRACTION_BITS) + \
(((f) * FIXED248_HIGH_MULTIPLIER) / 100) \
))
/**
* Convert an int32_t value to a fixed248_t value.
*
* @param b The int32_t value to convert.
* @return The converted fixed248_t value.
*/
fixed248_t fx248Fromi32(const int32_t b);
/**
* Convert a uint32_t value to a fixed248_t value.
*
* @param b The uint32_t value to convert.
* @return The converted fixed248_t value.
*/
fixed248_t fx248Fromui32(const uint32_t b);
/**
* Convert a float_t value to a fixed248_t value.
*
* @param b The float_t value to convert.
* @return The converted fixed248_t value.
*/
fixed248_t fx248Fromf32(const float_t b);
/**
* Convert a fixed248_t value to an int32_t value.
*
* @param a The fixed248_t value to convert.
* @return The converted int32_t value.
*/
int32_t fx248Toi32(const fixed248_t a);
/**
* Convert a fixed248_t value to a uint32_t value.
*
* @param a The fixed248_t value to convert.
* @return The converted uint32_t value.
*/
uint32_t fx248Tou32(const fixed248_t a);
/**
* Convert a fixed248_t value to a float_t value.
*
* @param a The fixed248_t value to convert.
* @return The converted float_t value.
*/
float_t fx248Tof32(const fixed248_t a);
/**
* Add a fixed248_t value to another fixed248_t value.
*
* @param a Pointer to the first fixed248_t value (will be modified).
* @param b The fixed248_t value to add to the first value.
*/
void fx248Addfx248(fixed248_t *a, const fixed248_t b);
/**
* Add an int32_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The int32_t value to add to the fixed248_t value.
*/
void fx248Addi32(fixed248_t *a, const int32_t b);
/**
* Add a uint32_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The uint32_t value to add to the fixed248_t value.
*/
void fx248Addui32(fixed248_t *a, const uint32_t b);
/**
* Add a float_t value to a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The float_t value to add to the fixed248_t value.
*/
void fx248Addf32(fixed248_t *a, const float_t b);
/**
* Subtract a fixed248_t value from another fixed248_t value.
*
* @param a Pointer to the first fixed248_t value (will be modified).
* @param b The fixed248_t value to subtract from the first value.
*/
void fx248Subfx248(fixed248_t *a, const fixed248_t b);
/**
* Subtract an int32_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The int32_t value to subtract from the fixed248_t value.
*/
void fx248Subi32(fixed248_t *a, const int32_t b);
/**
* Subtract a uint32_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The uint32_t value to subtract from the fixed248_t value.
*/
void fx248Subui32(fixed248_t *a, const uint32_t b);
/**
* Subtract a float_t value from a fixed248_t value.
*
* @param a Pointer to the fixed248_t value (will be modified).
* @param b The float_t value to subtract from the fixed248_t value.
*/
void fx248Subf32(fixed248_t *a, const float_t b);
/**
* Convert a fixed248_t value to an int32_t value, rounding towards zero.
*
* @param a The fixed248_t value to convert.
* @return The converted int32_t value.
*/
int32_t fx248Floor(const fixed248_t a);
/**
* Convert a fixed248_t value to an int32_t value, rounding towards positive
* infinity.
*
* @param a The fixed248_t value to convert.
* @return The converted int32_t value.
*/
int32_t fx248Ceil(const fixed248_t a);
/**
* Convert a fixed248_t value to an int32_t value, rounding to the nearest
* integer.
*
* @param a The fixed248_t value to convert.
* @return The converted int32_t value.
*/
int32_t fx248Round(const fixed248_t a);
/**
* Convert a fixed248_t value to a uint32_t value, rounding towards zero.
*
* @param a The fixed248_t value to convert.
* @return The converted uint32_t value.
*/
uint32_t fx248Flooru32(const fixed248_t a);
/**
* Convert a fixed248_t value to a uint32_t value, rounding towards positive
* infinity.
*
* @param a The fixed248_t value to convert.
* @return The converted uint32_t value.
*/
uint32_t fx248Ceilu32(const fixed248_t a);
/**
* Convert a fixed248_t value to a uint32_t value, rounding to the nearest
* integer.
*
* @param a The fixed248_t value to convert.
* @return The converted uint32_t value.
*/
uint32_t fx248Roundu32(const fixed248_t a);

View File

@ -195,7 +195,7 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) {
}
// Load tile data into chunk
printf("Loading chunk at (%u, %u)\n", x, y);
// printf("Loading chunk at (%u, %u)\n", x, y);
memoryCopy(
chunk->tilesBase,
chunkData->layerBase,
@ -248,8 +248,8 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) {
entity->id = data->id;
// Positions are chunk-relative.
entity->x = (chunk->x * CHUNK_WIDTH * TILE_WIDTH) + data->x;
entity->y = (chunk->y * CHUNK_HEIGHT * TILE_HEIGHT) + data->y;
entity->x = fx248Fromui32((chunk->x * CHUNK_WIDTH * TILE_WIDTH) + data->x);
entity->y = fx248Fromui32((chunk->y * CHUNK_HEIGHT * TILE_HEIGHT)+data->y);
// Next entity
data++;

View File

@ -47,8 +47,8 @@ void overworldUpdate() {
entity->type == ENTITY_TYPE_PLAYER,
"First entity must be player"
);
OVERWORLD_CAMERA_X = (uint32_t)floorf(entity->x);
OVERWORLD_CAMERA_Y = (uint32_t)floorf(entity->y);
OVERWORLD_CAMERA_X = fx248Flooru32(entity->x);
OVERWORLD_CAMERA_Y = fx248Flooru32(entity->y);
uint16_t x, y;
if(OVERWORLD_CAMERA_X < RENDER_WIDTH / 2) {

View File

@ -114,8 +114,8 @@ void drawOverworldDraw(void) {
void drawOverworldDrawEntity(const entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
uint32_t x = (uint32_t)floorf(entity->x);
uint32_t y = (uint32_t)floorf(entity->y);
uint32_t x = fx248Tou32(entity->x);
uint32_t y = fx248Tou32(entity->y);
uint32_t row = 0;
uint32_t col = entity->dir;