Back to floats.

This commit is contained in:
2025-10-10 09:16:08 -05:00
parent c4c43b23ad
commit 349e6e7c94
16 changed files with 164 additions and 220 deletions

View File

@@ -51,27 +51,16 @@ void entityUpdate(entity_t *entity) {
playerMovement(entity);
}
// Velocity
for(uint8_t i = 0; i < WORLD_DIMENSIONS; i++) {
if(entity->velocity[i] == 0) continue;
// Add velcoity
glm_vec3_muladds(entity->velocity, TIME.delta, entity->position);
worldPosAddSubtile(&entity->position[i], entity->velocity[i]);
// Apply friction
glm_vec3_muladds(
entity->velocity, -ENTITY_FRICTION * TIME.delta, entity->velocity
);
// Friction
worldsubtile_t v = entity->velocity[i];
if (v > 0) {
v -= ENTITY_FRICTION;
if (v < ENTITY_MIN_VELOCITY) v = 0;
} else if (v < 0) {
v += ENTITY_FRICTION;
if (v > -ENTITY_MIN_VELOCITY) v = 0;
}
if ((v > 0 && v < ENTITY_FRICTION) || (v < 0 && v > -ENTITY_FRICTION)) {
v = 0;
}
entity->velocity[i] = v;
// Clamp small velocities to zero
if(glm_vec3_norm(entity->velocity) < ENTITY_MIN_VELOCITY) {
glm_vec3_zero(entity->velocity);
}
}

View File

@@ -10,10 +10,9 @@
#include "rpg/entity/player.h"
#include "npc.h"
#include "physics/physics.h"
#include "rpg/world/worldunit.h"
#define ENTITY_FRICTION 2
#define ENTITY_MIN_VELOCITY 1
#define ENTITY_FRICTION 16.0f
#define ENTITY_MIN_VELOCITY 0.1f
#define ENTITY_COUNT 256
typedef struct map_s map_t;
@@ -30,8 +29,8 @@ typedef struct entity_s {
uint8_t id;
entitytype_t type;
direction_t direction;
worldpos_t position[WORLD_DIMENSIONS];
worldsubtile_t velocity[WORLD_DIMENSIONS];
vec3 position;
vec3 velocity;
union {
player_t player;

View File

@@ -11,6 +11,7 @@
#include "display/tileset/tileset_entities.h"
#include "rpg/rpgcamera.h"
#include "util/memory.h"
#include "time/time.h"
void playerInit(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
@@ -27,8 +28,8 @@ void playerMovement(entity_t *entity) {
if(dir[0] == 0 && dir[1] == 0) return;
glm_vec2_normalize(dir);
entity->velocity[0] += (worldsubtile_t)((float_t)PLAYER_SPEED * dir[0]);
entity->velocity[1] += (worldsubtile_t)((float_t)PLAYER_SPEED * dir[1]);
entity->velocity[0] += PLAYER_SPEED * dir[0] * TIME.fixedDelta;
entity->velocity[1] += PLAYER_SPEED * dir[1] * TIME.fixedDelta;
// Update direction.
if(dir[0] > 0) {

View File

@@ -8,7 +8,8 @@
#pragma once
#include "dusk.h"
#define PLAYER_SPEED 4
#define PLAYER_SPEED 32.0f
#define PLAYER_SPEED_RUNNING 64.0f
#define PLAYER_INTERACTION_RANGE 1.0f
#define PLAYER_INTERACTION_SIZE 0.5f

View File

@@ -21,11 +21,11 @@ errorret_t rpgInit(void) {
entityInit(ent, ENTITY_TYPE_PLAYER);
RPG_CAMERA.mode = RPG_CAMERA_MODE_FOLLOW_ENTITY;
RPG_CAMERA.followEntity.followEntityId = ent->id;
ent->position[0].tile = 32, ent->position[1].tile = 32;
ent->position[0] = 4, ent->position[1] = 4;
ent = &ENTITIES[1];
entityInit(ent, ENTITY_TYPE_NPC);
ent->position[0].tile = 40, ent->position[1].tile = 32;
ent->position[0] = 6, ent->position[1] = 6;
errorOk();
}

View File

@@ -9,9 +9,7 @@
#include "util/memory.h"
#include "rpg/entity/entity.h"
rpgcamera_t RPG_CAMERA = {
.position = { 0 }
};
rpgcamera_t RPG_CAMERA;
void rpgCameraInit(void) {
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));

View File

@@ -6,7 +6,7 @@
*/
#pragma once
#include "world/worldunit.h"
#include "dusk.h"
typedef enum {
RPG_CAMERA_MODE_FREE,
@@ -14,7 +14,7 @@ typedef enum {
} rpgcameramode_t;
typedef struct {
worldpos_t position[WORLD_DIMENSIONS];
vec3 position;
rpgcameramode_t mode;
union {

View File

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

View File

@@ -1,62 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "worldunit.h"
#include "assert/assert.h"
void worldChunkPosAdd(worldchunkpos_t *pos, const worldsubtile_t amt) {
assertNotNull(pos, "Position pointer cannot be NULL");
/*
int32_t sum = (int32_t)pos->subtile + (int32_t)amt;
int32_t shifted = sum + 128; // may be negative or large
int32_t carry = div_floor(shifted, 256); // tiles to add (can be neg)
int32_t rem = mod_floor(shifted, 256); // 0..255
int32_t new_sub = rem - 128; // back to [-128,127]
pos->subtile = (int8_t)new_sub;
pos->tile = (uint8_t)((int32_t)pos->tile + carry); // wrap mod 256
*/
int32_t shiftedTotal = (int32_t)pos->subtile + (int32_t)amt + 128;
int32_t tileCarry = shiftedTotal >> 8; // divide by 256
int32_t wrappedSubtile = shiftedTotal - (tileCarry << 8);
pos->subtile = (int8_t)(wrappedSubtile - 128);
pos->tile = (uint8_t)(pos->tile + (uint8_t)tileCarry);
}
void worldPosAddSubtile(worldpos_t *pos, const worldsubtile_t amt) {
assertNotNull(pos, "Position pointer cannot be NULL");
// Same as worldChunkPosAdd but with chunk handling.
int32_t shiftedTotal = (int32_t)pos->subtile + (int32_t)amt + 128;
int32_t tileCarry = shiftedTotal >> 8; // divide by 256
int32_t wrappedSubtile = shiftedTotal - (tileCarry << 8);
pos->subtile = (int8_t)(wrappedSubtile - 128);
int32_t newTile = (int32_t)pos->tile + (int32_t)tileCarry;
int32_t chunkCarry = newTile / WORLD_CHUNK_SIZE;
pos->tile = (uint8_t)(newTile % WORLD_CHUNK_SIZE);
pos->chunk = (uint8_t)(pos->chunk + (uint8_t)chunkCarry);
}
float_t worldChunkPosToF32(const worldchunkpos_t pos, const uint8_t tileSize) {
const float_t scaleFactor = (float_t)tileSize * (1.0f / 256.0f);
return (
(float_t)pos.tile * (float_t)tileSize + ((float_t)pos.subtile + 128.0f) *
scaleFactor
);
}
float_t worldPosToF32(const worldpos_t pos, const uint8_t tileSize) {
const float_t scaleFactor = (float_t)tileSize * (1.0f / 256.0f);
const float_t chunkFactor = WORLD_CHUNK_SIZE * (float_t)tileSize;
return (
(float_t)pos.chunk * chunkFactor +
(float_t)pos.tile * (float_t)tileSize +
((float_t)pos.subtile + 128.0f) * scaleFactor
);
}

View File

@@ -1,100 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#define WORLD_DIMENSIONS 3
#define WORLD_SUBTITLE_MIN -128
#define WORLD_SUBTITLE_MAX 127
#define WORLD_CHUNK_SIZE 256 // Tiles per axis per chunk.
/**
* Position in SUBTILE space in a world, each unit represents a single subtile.
* This is divided by the size of the tile, e.g. if a tile is 16x16 then there
* are 128 / tile size = units per pixel of a tile. This means there are always
* between WORLD_SUBTITLE_MIN and WORLD_SUBTITLE_MAX subtiles in a tile.
*
* The extra benefit of this is that different tile sizes don't require any game
* logic updates!
*/
typedef int8_t worldsubtile_t;
/**
* Position in TILE space in a world, each unit represents a single tile. This
* is within CHUNK space. This is not different depending on chunk size, if the
* chunks are 32 tiles wide then the max tile value is 31.
*/
typedef uint8_t worldtile_t;
/**
* Represents a position in a world in SUBTILE and TILE space. This is basically
* just a convenience struct so you don't have to pass two variables around.
*
* For example, an entity may be at tile (2, 3) and subtile (8, 12).
* meaning that the entity is at pixel (2 * TILE_SIZE + 8, 3 * TILE_SIZE + 12)
* in world space.
*
* This is still within CHUNK space.
*/
typedef struct worldchunkpos_s {
worldsubtile_t subtile;
worldtile_t tile;
} worldchunkpos_t;
/**
* Position in CHUNK space in a world, each unit represents a single chunk.
*/
typedef uint8_t worldchunk_t;
/**
* Represents a position in a world in SUBTILE, TILE and CHUNK space. This is in
* WORLD space, so this is the full position of an entity in the world.
*/
typedef struct worldpos_s {
worldsubtile_t subtile;
worldtile_t tile;
worldchunk_t chunk;
} worldpos_t;
/**
* Adds a number of subtiles to a world chunk position, rolling over into tiles
* and chunks as necessary.
*
* @param pos Pointer to the world chunk position to modify.
* @param amt The amount of subtiles to add (can be negative).
*/
void worldChunkPosAdd(worldchunkpos_t *pos, const worldsubtile_t amt);
/**
* Adds a number of subtiles to a world position, rolling over into tiles and
* chunks as necessary.
*
* @param pos Pointer to the world position to modify.
* @param amt The amount of subtiles to add (can be negative).
*/
void worldPosAddSubtile(worldpos_t *pos, const worldsubtile_t amt);
/**
* Converts a world chunk position to a floating point number, given the tile
* size in pixels.
*
* @param pos Pointer to the world chunk position to convert.
* @param tileSize The size of a tile in pixels.
* @return The position as a floating point number.
*/
float_t worldChunkPosToF32(const worldchunkpos_t pos, const uint8_t tileSize);
/**
* Converts a world position to a floating point number, given the tile size
* in pixels.
*
* @param pos Pointer to the world position to convert.
* @param tileSize The size of a tile in pixels.
* @return The position as a floating point number.
*/
float_t worldPosToF32(const worldpos_t pos, const uint8_t tileSize);