From 26ecf67472a2b6648ffe879c81fc420714e8db7e Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 10 Aug 2025 09:00:00 -0500 Subject: [PATCH] Suspiciously everything worked when changing to floats --- .gitignore | 2 +- archive/fixed.c | 257 +++++++++++++ archive/fixed.h | 379 ++++++++++++++++++++ src/dusk/dusk.h | 1 + src/dusk/entity/entity.c | 57 ++- src/dusk/entity/entity.h | 9 +- src/dusk/entity/player.c | 35 +- src/dusk/entity/player.h | 11 +- src/dusk/physics/physics.c | 224 ++++++------ src/dusk/physics/physics.h | 43 ++- src/dusk/util/CMakeLists.txt | 1 - src/dusk/util/fixed.c | 257 ------------- src/dusk/util/fixed.h | 379 -------------------- src/dusk/world/chunk.c | 8 +- src/dusk/world/overworld.c | 4 +- src/duskraylib/display/draw/drawoverworld.c | 4 +- tools/mapcompile/helper.py | 5 +- tools/mapcompile/mapcompile.py | 4 +- 18 files changed, 817 insertions(+), 863 deletions(-) create mode 100644 archive/fixed.c create mode 100644 archive/fixed.h delete mode 100644 src/dusk/util/fixed.c delete mode 100644 src/dusk/util/fixed.h diff --git a/.gitignore b/.gitignore index 7d4fe5a..a3753f7 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,6 @@ assets/borrowed /archive0 /archive1 -/archive +# /archive __pycache__ \ No newline at end of file diff --git a/archive/fixed.c b/archive/fixed.c new file mode 100644 index 0000000..4b5fd75 --- /dev/null +++ b/archive/fixed.c @@ -0,0 +1,257 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "fixed.h" +#include "assert/assert.h" + +float_t fx248Fromi32(const int32_t b) { + return (float_t)b << FIXED248_FRACTION_BITS; +} + +float_t fx248Fromu32(const uint32_t b) { + return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); +} + +float_t fx248Fromf32(const float_t b) { + return (float_t)(b * (1 << FIXED248_FRACTION_BITS)); +} + +float_t fx248Fromu16(const uint16_t b) { + return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); +} + +float_t fx248Fromu8(const uint8_t b) { + return (float_t)((int32_t)b << FIXED248_FRACTION_BITS); +} + + + +int32_t fx248Toi32(const float_t a) { + return a >> FIXED248_FRACTION_BITS; +} + +uint32_t fx248Tou32(const float_t a) { + return (uint32_t)(a >> FIXED248_FRACTION_BITS); +} + +float_t fx248Tof32(const float_t a) { + return (float_t)a / (1 << FIXED248_FRACTION_BITS); +} + +uint16_t fx248Tou16(const float_t a) { + return (uint16_t)(a >> FIXED248_FRACTION_BITS); +} + +uint8_t fx248Tou8(const float_t a) { + return (uint8_t)(a >> FIXED248_FRACTION_BITS); +} + + + +float_t fx248Addfx248(const float_t a, const float_t b) { + return a + b; +} + +float_t fx248Addi32(const float_t a, const int32_t b) { + return fx248Addfx248(a, fx248Fromi32(b)); +} + +float_t fx248Addu32(const float_t a, const uint32_t b) { + return fx248Addfx248(a, fx248Fromu32(b)); +} + +float_t fx248Addf32(const float_t a, const float_t b) { + return fx248Addfx248(a, fx248Fromf32(b)); +} + + + +float_t fx248Subfx248(const float_t a, const float_t b) { + return a - b; +} + +float_t fx248Subi32(const float_t a, const int32_t b) { + return fx248Subfx248(a, fx248Fromi32(b)); +} + +float_t fx248Subu32(const float_t a, const uint32_t b) { + return fx248Subfx248(a, fx248Fromu32(b)); +} + +float_t fx248Subf32(const float_t a, const float_t b) { + return fx248Subfx248(a, fx248Fromf32(b)); +} + + + +float_t fx248Mulfx248(const float_t a, const float_t b) { + return (float_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); +} + +float_t fx248Muli32(const float_t a, const int32_t b) { + return (float_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); +} + +float_t fx248Mulu32(const float_t a, const uint32_t b) { + return (float_t)( + ((int64_t)a * (int64_t)(int32_t)b + ) >> FIXED248_FRACTION_BITS); +} + +float_t fx248Mulf32(const float_t a, const float_t b) { + return (float_t)(( + (int64_t)a * (int64_t)(b * (1 << FIXED248_FRACTION_BITS)) + ) >> FIXED248_FRACTION_BITS); +} + + + +float_t fx248Divfx248(const float_t a, const float_t b) { + assertFalse(b == 0, "Division by zero in fx248Divfx248"); + return (float_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); +} + +float_t fx248Divi32(const float_t a, const int32_t b) { + assertFalse(b == 0, "Division by zero in fx248Divi32"); + return (float_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); +} + +float_t fx248Divu32(const float_t a, const uint32_t b) { + assertFalse(b == 0, "Division by zero in fx248Divu32"); + return (float_t)( + ((int64_t)a << FIXED248_FRACTION_BITS + ) / (int64_t)(int32_t)b); +} + +float_t fx248Divf32(const float_t a, const float_t b) { + assertFalse(b == 0, "Division by zero in fx248Divf32"); + return (float_t)(( + (int64_t)a << FIXED248_FRACTION_BITS + ) / (int64_t)(b * (1 << FIXED248_FRACTION_BITS))); +} + + + +float_t fx248Floor(const float_t a) { + return a & ~((1 << FIXED248_FRACTION_BITS) - 1); +} + +float_t fx248Ceil(const float_t a) { + if(a & ((1 << FIXED248_FRACTION_BITS) - 1)) { + return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); + } + return a; +} + +float_t fx248Round(const float_t a) { + if(a & ((1 << (FIXED248_FRACTION_BITS - 1)) - 1)) { + return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); + } + return a & ~((1 << FIXED248_FRACTION_BITS) - 1); +} + + + +uint32_t fx248Flooru32(const float_t a) { + return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); +} + +uint32_t fx248Ceilu32(const float_t a) { + return (uint32_t)(((a + ((1 << FIXED248_FRACTION_BITS) - 1)) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); +} + +uint32_t fx248Roundu32(const float_t a) { + return (uint32_t)(((a + (1 << (FIXED248_FRACTION_BITS - 1))) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); +} + +float_t fx248Sqrt(const float_t a) { + if(a == 0) return 0; + + float_t y = a > FIXED248(1, 0) ? a : FIXED248(1, 0); + float_t last = 0; + int max_iter = 16; + while(y != last && max_iter-- > 0) { + last = y; + int32_t div = (int32_t)(((int64_t)a << FIXED248_FRACTION_BITS) / y); + y = (y + div) >> 1; + } + return y; +} + + + +float_t fx248Max(const float_t a, const float_t b) { + return (a > b) ? a : b; +} + +float_t fx248Min(const float_t a, const float_t b) { + return (a < b) ? a : b; +} + +float_t fx248Clamp( + const float_t a, + const float_t min, + const float_t max +) { + return (a < min) ? min : (a > max) ? max : a; +} + +float_t fx248Abs(const float_t a) { + return (a < 0) ? -a : a; +} + + + +float_t fx248Atan2( + const float_t y, + const float_t x +) { + // Handle special cases + if (x == 0) { + if (y > 0) return FX248_HALF_PI; + if (y < 0) return -FX248_HALF_PI; + return 0; + } + + // Use absolute values for quadrant correction + float_t abs_y = y; + if (abs_y < 0) abs_y = -abs_y; + + float_t angle; + if (abs_y < fx248Abs(x)) { + float_t z = fx248Divfx248(y, x); + float_t z2 = fx248Mulfx248(z, z); + float_t z3 = fx248Mulfx248(z2, z); + float_t z5 = fx248Mulfx248(z3, z2); + angle = fx248Subfx248( + fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), + fx248Divfx248(z3, fx248Fromi32(3)) + ); + if (x < 0) { + if (y < 0) { + angle -= FX248_PI; + } else { + angle += FX248_PI; + } + } + } else { + float_t z = fx248Divfx248(x, y); + float_t z2 = fx248Mulfx248(z, z); + float_t z3 = fx248Mulfx248(z2, z); + float_t z5 = fx248Mulfx248(z3, z2); + angle = fx248Subfx248( + fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), + fx248Divfx248(z3, fx248Fromi32(3)) + ); + if (y > 0) { + angle = FX248_HALF_PI - angle; + } else { + angle = -FX248_HALF_PI - angle; + } + } + return angle; +} \ No newline at end of file diff --git a/archive/fixed.h b/archive/fixed.h new file mode 100644 index 0000000..335a149 --- /dev/null +++ b/archive/fixed.h @@ -0,0 +1,379 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +typedef int32_t float_t; + +#define FIXED248_FRACTION_BITS 8 +#define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS) +#define FIXED248_MIN INT32_MIN +#define FIXED248_MAX INT32_MAX +#define FIXED248(i, f) ((float_t)( \ + ((i) << FIXED248_FRACTION_BITS) + \ + (((f) * FIXED248_HIGH_MULTIPLIER) / 100) \ +)) +#define FIXED248_ONE (FIXED248(1, 0)) +#define FIXED248_ZERO (FIXED248(0, 0)) +#define FX248_PI 804 +#define FX248_HALF_PI 402 +#define FX248_3PI_4 603 +#define FX248_NEG_PI -804 + +/** + * Convert an int32_t value to a float_t value. + * + * @param b The int32_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Fromi32(const int32_t b); + +/** + * Convert a uint32_t value to a float_t value. + * + * @param b The uint32_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Fromu32(const uint32_t b); + +/** + * Convert a float_t value to a float_t value. + * + * @param b The float_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Fromf32(const float_t b); + +/** + * Convert a uint16_t value to a float_t value. + * + * @param b The uint16_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Fromu16(const uint16_t b); + +/** + * Convert a uint8_t value to a float_t value. + * + * @param b The uint8_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Fromu8(const uint8_t b); + + + +/** + * Convert a float_t value to an int32_t value. + * + * @param a The float_t value to convert. + * @return The converted int32_t value. + */ +int32_t fx248Toi32(const float_t a); + +/** + * Convert a float_t value to a uint32_t value. + * + * @param a The float_t value to convert. + * @return The converted uint32_t value. + */ +uint32_t fx248Tou32(const float_t a); + +/** + * Convert a float_t value to a float_t value. + * + * @param a The float_t value to convert. + * @return The converted float_t value. + */ +float_t fx248Tof32(const float_t a); + +/** + * Convert a float_t value to a uint16_t value. + * + * @param a The float_t value to convert. + * @return The converted uint16_t value. + */ +uint16_t fx248Tou16(const float_t a); + +/** + * Convert a float_t value to an uint8_t value. + * + * @param a The float_t value to convert. + * @return The converted uint8_t value. + */ +uint8_t fx248Tou8(const float_t a); + + + +/** + * Add a float_t value to another float_t value. + * + * @param a First float_t value. + * @param b Second float_t value to add to the first value. + * @return The result of the addition as a float_t value. + */ +float_t fx248Addfx248(const float_t a, const float_t b); + +/** + * Add an int32_t value to a float_t value. + * + * @param a The float_t value to which the int32_t will be added. + * @param b The int32_t value to add to the float_t value. + * @return The result of the addition as a float_t value. + */ +float_t fx248Addi32(const float_t a, const int32_t b); + +/** + * Add a uint32_t value to a float_t value. + * + * @param a The float_t value to which the uint32_t will be added. + * @param b The uint32_t value to add to the float_t value. + * @return The result of the addition as a float_t value. + */ +float_t fx248Addu32(const float_t a, const uint32_t b); + +/** + * Add a float_t value to a float_t value. + * + * @param a Pointer to the float_t value (will be modified). + * @param b The float_t value to add to the float_t value. + * @return The result of the addition as a float_t value. + */ +float_t fx248Addf32(const float_t a, const float_t b); + + + +/** + * Subtract a float_t value from another float_t value. + * + * @param a First float_t value. + * @param b The float_t value to subtract from the first value. + * @return The result of the subtraction as a float_t value. + */ +float_t fx248Subfx248(const float_t a, const float_t b); + +/** + * Subtract an int32_t value from a float_t value. + * + * @param a The float_t value from which the int32_t will be subtracted. + * @param b The int32_t value to subtract from the float_t value. + * @return The result of the subtraction as a float_t value. + */ +float_t fx248Subi32(const float_t a, const int32_t b); + +/** + * Subtract a uint32_t value from a float_t value. + * + * @param a The float_t value from which the uint32_t will be subtracted. + * @param b The uint32_t value to subtract from the float_t value. + * @return The result of the subtraction as a float_t value. + */ +float_t fx248Subu32(const float_t a, const uint32_t b); + +/** + * Subtract a float_t value from a float_t value. + * + * @param a The float_t value from which the float_t will be subtracted. + * @param b The float_t value to subtract from the float_t value. + * @return The result of the subtraction as a float_t value. + */ +float_t fx248Subf32(const float_t a, const float_t b); + + + +/** + * Multiply two float_t values. + * + * @param a First float_t value. + * @param b Second float_t value to multiply with the first value. + * @return The result of the multiplication as a float_t value. + */ +float_t fx248Mulfx248(const float_t a, const float_t b); + +/** + * Multiply a float_t value by an int32_t value. + * + * @param a The float_t value to multiply. + * @param b The int32_t value to multiply with the float_t value. + * @return The result of the multiplication as a float_t value. + */ +float_t fx248Muli32(const float_t a, const int32_t b); + +/** + * Multiply a float_t value by a uint32_t value. + * + * @param a The float_t value to multiply. + * @param b The uint32_t value to multiply with the float_t value. + * @return The result of the multiplication as a float_t value. + */ +float_t fx248Mulu32(const float_t a, const uint32_t b); + +/** + * Multiply a float_t value by a float_t value. + * + * @param a The float_t value to multiply. + * @param b The float_t value to multiply with the float_t value. + * @return The result of the multiplication as a float_t value. + */ +float_t fx248Mulf32(const float_t a, const float_t b); + + + +/** + * Divide two float_t values. + * + * @param a The float_t value to be divided. + * @param b The float_t value to divide by. + * @return The result of the division as a float_t value. + */ +float_t fx248Divfx248(const float_t a, const float_t b); + +/** + * Divide a float_t value by an int32_t value. + * + * @param a The float_t value to be divided. + * @param b The int32_t value to divide by. + * @return The result of the division as a float_t value. + */ +float_t fx248Divi32(const float_t a, const int32_t b); + +/** + * Divide a float_t value by a uint32_t value. + * + * @param a The float_t value to be divided. + * @param b The uint32_t value to divide by. + * @return The result of the division as a float_t value. + */ +float_t fx248Divu32(const float_t a, const uint32_t b); + +/** + * Divide a float_t value by a float_t value. + * + * @param a The float_t value to be divided. + * @param b The float_t value to divide by. + * @return The result of the division as a float_t value. + */ +float_t fx248Divf32(const float_t a, const float_t b); + + + +/** + * Convert a float_t value to an int32_t value, rounding towards zero. + * + * @param a The float_t value to convert. + * @return The converted int32_t value. + */ +float_t fx248Floor(const float_t a); + +/** + * Convert a float_t value to an int32_t value, rounding towards positive + * infinity. + * + * @param a The float_t value to convert. + * @return The converted int32_t value. + */ +float_t fx248Ceil(const float_t a); + +/** + * Convert a float_t value to an int32_t value, rounding to the nearest + * integer. + * + * @param a The float_t value to convert. + * @return The converted int32_t value. + */ +float_t fx248Round(const float_t a); + + + +/** + * Convert a float_t value to a uint32_t value, rounding towards zero. + * + * @param a The float_t value to convert. + * @return The converted uint32_t value. + */ +uint32_t fx248Flooru32(const float_t a); + +/** + * Convert a float_t value to a uint32_t value, rounding towards positive + * infinity. + * + * @param a The float_t value to convert. + * @return The converted uint32_t value. + */ +uint32_t fx248Ceilu32(const float_t a); + +/** + * Convert a float_t value to a uint32_t value, rounding to the nearest + * integer. + * + * @param a The float_t value to convert. + * @return The converted uint32_t value. + */ +uint32_t fx248Roundu32(const float_t a); + +/** + * Returns the square root of a float_t value. + * + * @param a The float_t value to calculate the square root of. + */ +float_t fx248Sqrt(const float_t a); + + + +/** + * Returns the maximum of two float_t values. + * + * @param a First float_t value. + * @param b Second float_t value. + * @return The maximum of the two values. + */ +float_t fx248Max(const float_t a, const float_t b); + +/** + * Returns the minimum of two float_t values. + * + * @param a First float_t value. + * @param b Second float_t value. + * @return The minimum of the two values. + */ +float_t fx248Min(const float_t a, const float_t b); + +/** + * Clamp a float_t value between a minimum and maximum value. + * + * @param a The float_t value to clamp. + * @param min The minimum value to clamp to. + * @param max The maximum value to clamp to. + * @return The clamped float_t value. + */ +float_t fx248Clamp( + const float_t a, + const float_t min, + const float_t max +); + +/** + * Returns the absolute value of a float_t value. + * + * @param a The float_t value to calculate the absolute value of. + * @return The absolute value as a float_t value. + */ +float_t fx248Abs(const float_t a); + + + +/** + * Calculate the arctangent of a float_t value. + * + * @param y Y coordinate value. + * @param x X coordinate value. + * @return The arctangent of the value as a float_t value. + */ +float_t fx248Atan2( + const float_t y, + const float_t x +); \ No newline at end of file diff --git a/src/dusk/dusk.h b/src/dusk/dusk.h index 5f6c373..8dd5e00 100644 --- a/src/dusk/dusk.h +++ b/src/dusk/dusk.h @@ -15,6 +15,7 @@ #include #include #include +#include typedef bool bool_t; typedef int int_t; diff --git a/src/dusk/entity/entity.c b/src/dusk/entity/entity.c index 16d3d9b..98b7f55 100644 --- a/src/dusk/entity/entity.c +++ b/src/dusk/entity/entity.c @@ -61,40 +61,29 @@ void entityUpdate(entity_t *entity) { ENTITY_CALLBACKS[entity->type].update(entity); - if( - entity->vx == FIXED248(0, 0) && - entity->vy == FIXED248(0, 0) - ) return; + if(entity->vx == 0.0f && entity->vy == 0.0f) return; - fixed248_t newX = entity->x + entity->vx; - fixed248_t newY = entity->y + entity->vy; - fixed248_t halfTileWH = FIXED248(TILE_WIDTH_HEIGHT / 2, 0); + float_t newX = entity->x + entity->vx; + float_t newY = entity->y + entity->vy; + float_t halfTileWH = TILE_WIDTH_HEIGHT / 2.0f; // Because all hit detection is done assuming the entity is a circle, with // its position centered, we need to precalc these; - fixed248_t selfCircX = fx248Addfx248(newX, halfTileWH); - fixed248_t selfCircY = fx248Addfx248(newY, halfTileWH); - fixed248_t selfCircR = halfTileWH; + float_t selfCircX = newX + halfTileWH; + float_t selfCircY = newY + halfTileWH; + float_t selfCircR = halfTileWH; // Check for collisions with tiles - fixed248_t tileStartX = fx248Floor(fx248Divfx248( - (newX - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) - )); - fixed248_t tileStartY = fx248Floor(fx248Divfx248( - (newY - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) - )); - fixed248_t tileEndX = fx248Ceil(fx248Divfx248( - (newX + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) - )); - fixed248_t tileEndY = fx248Ceil(fx248Divfx248( - (newY + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) - )); + float_t tileStartX = floorf((newX - halfTileWH) / TILE_WIDTH_HEIGHT); + float_t tileStartY = floorf((newY - halfTileWH) / TILE_WIDTH_HEIGHT); + float_t tileEndX = ceilf((newX + halfTileWH) / TILE_WIDTH_HEIGHT); + float_t tileEndY = ceilf((newY + halfTileWH) / TILE_WIDTH_HEIGHT); // For each tile - for(fixed248_t y = tileStartY; y <= tileEndY; y += FIXED248_ONE) { - for(fixed248_t x = tileStartX; x <= tileEndX; x += FIXED248_ONE) { - uint16_t tileX = fx248Tou16(x); - uint16_t tileY = fx248Tou16(y); + for(float_t y = tileStartY; y <= tileEndY; y += 1) { + for(float_t x = tileStartX; x <= tileEndX; x += 1) { + uint16_t tileX = (uint16_t)x; + uint16_t tileY = (uint16_t)y; uint16_t chunkX = tileX / CHUNK_WIDTH; uint16_t chunkY = tileY / CHUNK_HEIGHT; chunk_t *chunk = chunkGetChunkAt(chunkX, chunkY); @@ -107,13 +96,9 @@ void entityUpdate(entity_t *entity) { collisionresult_t collision = physicsCheckCircleTile( selfCircX, selfCircY, selfCircR, x, y, tile ); - if(collision.hit && collision.depth > FIXED248(0, 1)) { - fixed248_t slideX = fx248Mulfx248( - collision.normalX, collision.depth - ); - fixed248_t slideY = fx248Mulfx248( - collision.normalY, collision.depth - ); + if(collision.hit && collision.depth > 0.01f) { + float_t slideX = collision.normalX * collision.depth; + float_t slideY = collision.normalY * collision.depth; newX -= slideX; newY -= slideY; } @@ -126,7 +111,7 @@ void entityUpdate(entity_t *entity) { // Skip self and null entities if(otherEntity == entity || otherEntity->type == ENTITY_TYPE_NULL) continue; - fixed248_t otherCircR = halfTileWH; + float_t otherCircR = halfTileWH; // We DONT use selfCircX/Y here because the other entity is ALSO a circle. collisionresult_t collision = physicsCheckCircleCircle( @@ -136,8 +121,8 @@ void entityUpdate(entity_t *entity) { if(!collision.hit) continue; // Collision with entity detected. Slide out of collision. - fixed248_t slideX = fx248Mulfx248(collision.normalX, collision.depth); - fixed248_t slideY = fx248Mulfx248(collision.normalY, collision.depth); + float_t slideX = collision.normalX * collision.depth; + float_t slideY = collision.normalY * collision.depth; newX -= slideX; newY -= slideY; } while(++otherEntity < ENTITIES + ENTITY_COUNT_MAX); diff --git a/src/dusk/entity/entity.h b/src/dusk/entity/entity.h index a9d2ffc..ed91c07 100644 --- a/src/dusk/entity/entity.h +++ b/src/dusk/entity/entity.h @@ -8,7 +8,6 @@ #pragma once #include "player.h" #include "npc.h" -#include "util/fixed.h" #define ENTITY_COUNT_MAX 32 @@ -33,8 +32,8 @@ typedef enum { typedef struct _entity_t { uint32_t id;// Completely unique ID for this entity. - fixed248_t x, y; - fixed248_t vx, vy; + float_t x, y; + float_t vx, vy; entitytype_t type; entitydir_t dir; @@ -69,9 +68,9 @@ void entityLoad(entity_t *entity, const entity_t *source); void entityUpdate(entity_t *entity); /** - * Converts an entity direction to an angle in fixed248_t format. + * Converts an entity direction to an angle in float_t format. * * @param dir The entity direction to convert. * @return The angle corresponding to the entity direction. */ -fixed248_t entityDirToAngle(const entitydir_t dir); \ No newline at end of file +float_t entityDirToAngle(const entitydir_t dir); \ No newline at end of file diff --git a/src/dusk/entity/player.c b/src/dusk/entity/player.c index b5c59be..8a51de8 100644 --- a/src/dusk/entity/player.c +++ b/src/dusk/entity/player.c @@ -114,12 +114,9 @@ void playerEntityUpdate(entity_t *entity) { continue; } - fixed248_t distanceX = fx248Subfx248(other->x, entity->x); - fixed248_t distanceY = fx248Subfx248(other->y, entity->y); - fixed248_t distance = fx248Sqrt(fx248Addfx248( - fx248Mulfx248(distanceX, distanceX), - fx248Mulfx248(distanceY, distanceY) - )); + float_t distanceX = other->x - entity->x; + float_t distanceY = other->y - entity->y; + float_t distance = sqrtf(distanceX * distanceX + distanceY * distanceY); if(distance > PLAYER_INTERACT_RANGE) { other++; @@ -127,16 +124,16 @@ void playerEntityUpdate(entity_t *entity) { } // Get angle - fixed248_t angle = fx248Atan2(distanceY, distanceX); - while(angle < 0) angle += FX248_PI; - fixed248_t selfAngle = entityDirToAngle(entity->dir); - while(selfAngle < 0) selfAngle += FX248_PI; - + float_t angle = atan2f(distanceY, distanceX); + while(angle < 0) angle += M_PI; + float_t selfAngle = entityDirToAngle(entity->dir); + while(selfAngle < 0) selfAngle += M_PI; + // Check if angle is within range - fixed248_t angleDiff = fx248Subfx248(angle, selfAngle); - if(angleDiff > FX248_HALF_PI) angleDiff -= FX248_PI; - if(angleDiff < -FX248_HALF_PI) angleDiff += FX248_PI; - if(fx248Abs(angleDiff) > PLAYER_INTERACT_ANGLE) { + float_t angleDiff = angle - selfAngle; + if(angleDiff > (M_PI_2)) angleDiff -= M_PI; + if(angleDiff < -M_PI_2) angleDiff += M_PI; + if(fabsf(angleDiff) > PLAYER_INTERACT_ANGLE) { other++; continue; } @@ -149,12 +146,12 @@ void playerEntityUpdate(entity_t *entity) { } } -fixed248_t entityDirToAngle(const entitydir_t dir) { +float_t entityDirToAngle(const entitydir_t dir) { switch(dir) { - case ENTITY_DIR_NORTH: return FX248_HALF_PI; - case ENTITY_DIR_SOUTH: return -FX248_HALF_PI; + case ENTITY_DIR_NORTH: return (M_PI_2); + case ENTITY_DIR_SOUTH: return -(M_PI_2); case ENTITY_DIR_EAST: return 0; - case ENTITY_DIR_WEST: return FX248_PI; + case ENTITY_DIR_WEST: return (M_PI); default: return 0; // Should never happen } } \ No newline at end of file diff --git a/src/dusk/entity/player.h b/src/dusk/entity/player.h index 2f30ced..d07a121 100644 --- a/src/dusk/entity/player.h +++ b/src/dusk/entity/player.h @@ -7,7 +7,6 @@ #pragma once #include "dusk.h" -#include "util/fixed.h" #include "item/inventory.h" typedef struct _entity_t entity_t; @@ -17,12 +16,10 @@ typedef struct { } playerentity_t; #define PLAYER_ENTITY_ID (UINT32_MAX-1) -#define PLAYER_MOVE_SPEED FIXED248(1, 0) -#define PLAYER_MOVE_SPEED_XY FIXED248(0, 80) -#define PLAYER_INTERACT_RANGE FIXED248( \ - (TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3)), 0 \ -) -#define PLAYER_INTERACT_ANGLE ((fixed248_t)175) +#define PLAYER_MOVE_SPEED 1.0f +#define PLAYER_MOVE_SPEED_XY 0.70710678118f +#define PLAYER_INTERACT_RANGE (TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3)) +#define PLAYER_INTERACT_ANGLE 0.68359375f extern inventory_t PLAYER_INVENTORY; diff --git a/src/dusk/physics/physics.c b/src/dusk/physics/physics.c index 1ac4f82..55130dc 100644 --- a/src/dusk/physics/physics.c +++ b/src/dusk/physics/physics.c @@ -9,23 +9,20 @@ #include "world/tiledata.h" collisionresult_t physicsCheckCircleCircle( - fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r, - fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r + float_t circle0x, float_t circle0y, float_t circle0r, + float_t circle1x, float_t circle1y, float_t circle1r ) { collisionresult_t result; // Compute vector between centers - fixed248_t dx = fx248Subfx248(circle1x, circle0x); - fixed248_t dy = fx248Subfx248(circle1y, circle0y); + float_t dx = circle1x - circle0x; + float_t dy = circle1y - circle0y; // Distance squared between centers - fixed248_t distSq = fx248Addfx248( - fx248Mulfx248(dx, dx), - fx248Mulfx248(dy, dy) - ); + float_t distSq = (dx * dx) + (dy * dy); // Sum of radii - fixed248_t rSum = fx248Addfx248(circle0r, circle1r); - fixed248_t rSumSq = fx248Mulfx248(rSum, rSum); + float_t rSum = circle0r + circle1r; + float_t rSumSq = rSum * rSum; if(distSq > rSumSq) { // No collision @@ -34,66 +31,66 @@ collisionresult_t physicsCheckCircleCircle( } // Collision: calculate normal and penetration depth - fixed248_t dist = fx248Sqrt(distSq); + float_t dist = sqrtf(distSq); // If centers are the same, pick arbitrary normal (1,0) if(dist == 0) { - result.normalX = FIXED248(1,0); + result.normalX = 1; result.normalY = 0; result.depth = rSum; } else { // Normalized direction from circle0 to circle1 - result.normalX = fx248Divfx248(dx, dist); - result.normalY = fx248Divfx248(dy, dist); + result.normalX = dx / dist; + result.normalY = dy / dist; // Penetration depth = sum of radii - distance - result.depth = fx248Subfx248(rSum, dist); + result.depth = rSum - dist; } result.hit = true; return result; } collisionresult_t physicsCheckCircleAABB( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t aabbX, fixed248_t aabbY, - fixed248_t aabbWidth, fixed248_t aabbHeight + float_t circleX, float_t circleY, float_t circleR, + float_t aabbX, float_t aabbY, + float_t aabbWidth, float_t aabbHeight ) { collisionresult_t result; // Find the closest point on the AABB to the circle center - fixed248_t closestX = fx248Max( - aabbX, fx248Min(circleX, fx248Addfx248(aabbX, aabbWidth)) + float_t closestX = fmaxf( + aabbX, fminf(circleX, aabbX + aabbWidth) ); - fixed248_t closestY = fx248Max( - aabbY, fx248Min(circleY, fx248Addfx248(aabbY, aabbHeight)) + float_t closestY = fmaxf( + aabbY, fminf(circleY, aabbY + aabbHeight) ); // Vector from circle center to closest point - fixed248_t dx = fx248Subfx248(closestX, circleX); - fixed248_t dy = fx248Subfx248(closestY, circleY); + float_t dx = closestX - circleX; + float_t dy = closestY - circleY; // Distance squared from circle center to closest point - fixed248_t distSq = fx248Addfx248(fx248Mulfx248(dx, dx), fx248Mulfx248(dy, dy)); + float_t distSq = (dx * dx) + (dy * dy); // Check if distance is less than radius squared - if(distSq > fx248Mulfx248(circleR, circleR)) { + if(distSq > (circleR * circleR)) { result.hit = false; return result; } // Collision: calculate normal and penetration depth - fixed248_t dist = fx248Sqrt(distSq); - - if(dist <= FIXED248(0, 1)) { + float_t dist = sqrtf(distSq); + + if(dist <= 1) { // Circle center is at the AABB corner - result.normalX = FIXED248(1,0); - result.normalY = FIXED248(0,1); + result.normalX = 1.0f; + result.normalY = 0.0f; result.depth = circleR; } else { // Normalized direction from circle center to closest point - result.normalX = fx248Divfx248(dx, dist); - result.normalY = fx248Divfx248(dy, dist); + result.normalX = dx / dist; + result.normalY = dy / dist; // Penetration depth = radius - distance - result.depth = fx248Subfx248(circleR, dist); + result.depth = circleR - dist; } result.hit = true; @@ -101,116 +98,99 @@ collisionresult_t physicsCheckCircleAABB( } void physicsClosestPointOnSegment( - fixed248_t ax, fixed248_t ay, - fixed248_t bx, fixed248_t by, - fixed248_t px, fixed248_t py, - fixed248_t *outX, fixed248_t *outY + float_t ax, float_t ay, + float_t bx, float_t by, + float_t px, float_t py, + float_t *outX, float_t *outY ) { - fixed248_t abx = fx248Subfx248(bx, ax); - fixed248_t aby = fx248Subfx248(by, ay); - fixed248_t apx = fx248Subfx248(px, ax); - fixed248_t apy = fx248Subfx248(py, ay); + float_t abx = bx - ax; + float_t aby = by - ay; + float_t apx = px - ax; + float_t apy = py - ay; - fixed248_t abLenSq = fx248Addfx248( - fx248Mulfx248(abx, abx), - fx248Mulfx248(aby, aby) - ); + float_t abLenSq = (abx * abx) + (aby * aby); - if(abLenSq == FIXED248_ZERO) { + if(abLenSq == 0) { *outX = ax; *outY = ay; return; } - fixed248_t t = fx248Divfx248( - fx248Addfx248(fx248Mulfx248(apx, abx), fx248Mulfx248(apy, aby)), - abLenSq - ); + float_t t = apx * abx + apy * aby; + t /= abLenSq; - if(t < FIXED248_ZERO) t = FIXED248_ZERO; - if(t > FIXED248_ONE) t = FIXED248_ONE; + if(t < 0) t = 0; + if(t > 1) t = 1; - *outX = fx248Addfx248(ax, fx248Mulfx248(abx, t)); - *outY = fx248Addfx248(ay, fx248Mulfx248(aby, t)); + *outX = ax + (abx * t); + *outY = ay + (aby * t); } bool_t physicsIsPointInTriangle( - fixed248_t px, fixed248_t py, - fixed248_t ax, fixed248_t ay, - fixed248_t bx, fixed248_t by, - fixed248_t cx, fixed248_t cy + float_t px, float_t py, + float_t ax, float_t ay, + float_t bx, float_t by, + float_t cx, float_t cy ) { - fixed248_t abx = fx248Subfx248(bx, ax); - fixed248_t aby = fx248Subfx248(by, ay); - fixed248_t bcx = fx248Subfx248(cx, bx); - fixed248_t bcy = fx248Subfx248(cy, by); - fixed248_t cax = fx248Subfx248(ax, cx); - fixed248_t cay = fx248Subfx248(ay, cy); + float_t abx = bx - ax; + float_t aby = by - ay; + float_t bcx = cx - bx; + float_t bcy = cy - by; + float_t cax = ax - cx; + float_t cay = ay - cy; - fixed248_t apx = fx248Subfx248(px, ax); - fixed248_t apy = fx248Subfx248(py, ay); - fixed248_t bpx = fx248Subfx248(px, bx); - fixed248_t bpy = fx248Subfx248(py, by); - fixed248_t cpx = fx248Subfx248(px, cx); - fixed248_t cpy = fx248Subfx248(py, cy); + float_t apx = px - ax; + float_t apy = py - ay; + float_t bpx = px - bx; + float_t bpy = py - by; + float_t cpx = px - cx; + float_t cpy = py - cy; - fixed248_t cross1 = fx248Subfx248( - fx248Mulfx248(abx, apy), - fx248Mulfx248(aby, apx) - ); - fixed248_t cross2 = fx248Subfx248( - fx248Mulfx248(bcx, bpy), - fx248Mulfx248(bcy, bpx) - ); - fixed248_t cross3 = fx248Subfx248( - fx248Mulfx248(cax, cpy), - fx248Mulfx248(cay, cpx) - ); + float_t cross1 = (abx * apy) - (aby * apx); + float_t cross2 = (bcx * bpy) - (bcy * bpx); + float_t cross3 = (cax * cpy) - (cay * cpx); bool_t hasNeg = ( - (cross1 < FIXED248_ZERO) || - (cross2 < FIXED248_ZERO) || - (cross3 < FIXED248_ZERO) + (cross1 < 0) || + (cross2 < 0) || + (cross3 < 0) ); bool_t hasPos = ( - (cross1 > FIXED248_ZERO) || - (cross2 > FIXED248_ZERO) || - (cross3 > FIXED248_ZERO) + (cross1 > 0) || + (cross2 > 0) || + (cross3 > 0) ); return !(hasNeg && hasPos); } collisionresult_t physicsCheckCircleTriangle( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t triX0, fixed248_t triY0, - fixed248_t triX1, fixed248_t triY1, - fixed248_t triX2, fixed248_t triY2 + float_t circleX, float_t circleY, float_t circleR, + float_t triX0, float_t triY0, + float_t triX1, float_t triY1, + float_t triX2, float_t triY2 ) { collisionresult_t result = { .hit = false }; - fixed248_t vx[3] = { triX0, triX1, triX2 }; - fixed248_t vy[3] = { triY0, triY1, triY2 }; + float_t vx[3] = { triX0, triX1, triX2 }; + float_t vy[3] = { triY0, triY1, triY2 }; - fixed248_t closestX = FIXED248_ZERO; - fixed248_t closestY = FIXED248_ZERO; - fixed248_t minDistSq = FIXED248_MAX; + float_t closestX = 0; + float_t closestY = 0; + float_t minDistSq = FLT_MAX; for(uint8_t i = 0; i < 3; ++i) { uint8_t j = (i + 1) % 3; - fixed248_t testX, testY; + float_t testX, testY; physicsClosestPointOnSegment( vx[i], vy[i], vx[j], vy[j], circleX, circleY, &testX, &testY ); - fixed248_t dx = fx248Subfx248(circleX, testX); - fixed248_t dy = fx248Subfx248(circleY, testY); - fixed248_t distSq = fx248Addfx248( - fx248Mulfx248(dx, dx), - fx248Mulfx248(dy, dy) - ); + float_t dx = circleX - testX; + float_t dy = circleY - testY; + float_t distSq = (dx * dx) + (dy * dy); if(distSq < minDistSq) { minDistSq = distSq; @@ -221,44 +201,44 @@ collisionresult_t physicsCheckCircleTriangle( } } - fixed248_t dist = fx248Sqrt(minDistSq); - fixed248_t invDist = ( - (dist != FIXED248_ZERO) ? - fx248Divfx248(FIXED248_ONE, dist) : - FIXED248_ONE + float_t dist = sqrtf(minDistSq); + float_t invDist = ( + (dist != 0) ? + (1.0f / dist) : + 1.0f ); - result.normalX = fx248Mulfx248(-result.normalX, invDist); - result.normalY = fx248Mulfx248(-result.normalY, invDist); + result.normalX = -result.normalX * invDist; + result.normalY = -result.normalY * invDist; if(physicsIsPointInTriangle( circleX, circleY, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2] )) { result.hit = true; - result.depth = fx248Subfx248(circleR, dist); + result.depth = circleR - dist; return result; } if(dist < circleR) { result.hit = true; - result.depth = fx248Subfx248(circleR, dist); + result.depth = circleR - dist; } return result; } collisionresult_t physicsCheckCircleTile( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t tileX, fixed248_t tileY, tile_t tile + float_t circleX, float_t circleY, float_t circleR, + float_t tileX, float_t tileY, tile_t tile ) { collisionresult_t result; - #define tw FIXED248(TILE_WIDTH_HEIGHT, 0) - #define th FIXED248(TILE_WIDTH_HEIGHT, 0) - #define lx fx248Mulfx248(tileX, tw) - #define ty fx248Mulfx248(tileY, th) - #define rx fx248Addfx248(lx, tw) - #define by fx248Addfx248(ty, th) + #define tw (TILE_WIDTH_HEIGHT) + #define th (TILE_WIDTH_HEIGHT) + #define lx (tileX * tw) + #define ty (tileY * th) + #define rx (lx + tw) + #define by (ty + th) switch(TILE_META_DATA[tile].solidType) { case TILE_SOLID_FULL: diff --git a/src/dusk/physics/physics.h b/src/dusk/physics/physics.h index a0c7625..ba61244 100644 --- a/src/dusk/physics/physics.h +++ b/src/dusk/physics/physics.h @@ -6,13 +6,12 @@ */ #pragma once -#include "util/fixed.h" #include "world/tile.h" typedef struct { bool_t hit; - fixed248_t normalX, normalY; - fixed248_t depth; + float_t normalX, normalY; + float_t depth; } collisionresult_t; /** @@ -27,8 +26,8 @@ typedef struct { * @return A collisionresult_t structure containing collision information. */ collisionresult_t physicsCheckCircleCircle( - fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r, - fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r + float_t circle0x, float_t circle0y, float_t circle0r, + float_t circle1x, float_t circle1y, float_t circle1r ); /** @@ -44,9 +43,9 @@ collisionresult_t physicsCheckCircleCircle( * @return A collisionresult_t structure containing collision information. */ collisionresult_t physicsCheckCircleAABB( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t aabb, fixed248_t aabbY, - fixed248_t aabbWidth, fixed248_t aabbHeight + float_t circleX, float_t circleY, float_t circleR, + float_t aabb, float_t aabbY, + float_t aabbWidth, float_t aabbHeight ); /** @@ -62,10 +61,10 @@ collisionresult_t physicsCheckCircleAABB( * @param outY Pointer to store the Y coordinate of the closest point. */ void physicsClosestPointOnSegment( - fixed248_t ax, fixed248_t ay, - fixed248_t bx, fixed248_t by, - fixed248_t px, fixed248_t py, - fixed248_t *outX, fixed248_t *outY + float_t ax, float_t ay, + float_t bx, float_t by, + float_t px, float_t py, + float_t *outX, float_t *outY ); /** @@ -82,10 +81,10 @@ void physicsClosestPointOnSegment( * @return true if the point is inside the triangle, false otherwise. */ bool_t physicsIsPointInTriangle( - fixed248_t px, fixed248_t py, - fixed248_t x0, fixed248_t y0, - fixed248_t x1, fixed248_t y1, - fixed248_t x2, fixed248_t y2 + float_t px, float_t py, + float_t x0, float_t y0, + float_t x1, float_t y1, + float_t x2, float_t y2 ); /** @@ -103,10 +102,10 @@ bool_t physicsIsPointInTriangle( * @return A collisionresult_t structure containing collision information. */ collisionresult_t physicsCheckCircleTriangle( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t triX0, fixed248_t triY0, - fixed248_t triX1, fixed248_t triY1, - fixed248_t triX2, fixed248_t triY2 + float_t circleX, float_t circleY, float_t circleR, + float_t triX0, float_t triY0, + float_t triX1, float_t triY1, + float_t triX2, float_t triY2 ); /** @@ -121,6 +120,6 @@ collisionresult_t physicsCheckCircleTriangle( * @return A collisionresult_t structure containing collision information. */ collisionresult_t physicsCheckCircleTile( - fixed248_t circleX, fixed248_t circleY, fixed248_t circleR, - fixed248_t tileX, fixed248_t tileY, tile_t tile + float_t circleX, float_t circleY, float_t circleR, + float_t tileX, float_t tileY, tile_t tile ); \ No newline at end of file diff --git a/src/dusk/util/CMakeLists.txt b/src/dusk/util/CMakeLists.txt index 24877e0..915d256 100644 --- a/src/dusk/util/CMakeLists.txt +++ b/src/dusk/util/CMakeLists.txt @@ -6,7 +6,6 @@ # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE - fixed.c memory.c string.c ) \ No newline at end of file diff --git a/src/dusk/util/fixed.c b/src/dusk/util/fixed.c deleted file mode 100644 index f664f80..0000000 --- a/src/dusk/util/fixed.c +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "fixed.h" -#include "assert/assert.h" - -fixed248_t fx248Fromi32(const int32_t b) { - return (fixed248_t)b << FIXED248_FRACTION_BITS; -} - -fixed248_t fx248Fromu32(const uint32_t b) { - return (fixed248_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - -fixed248_t fx248Fromf32(const float_t b) { - return (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS)); -} - -fixed248_t fx248Fromu16(const uint16_t b) { - return (fixed248_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - -fixed248_t fx248Fromu8(const uint8_t b) { - return (fixed248_t)((int32_t)b << FIXED248_FRACTION_BITS); -} - - - -int32_t fx248Toi32(const fixed248_t a) { - return 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); -} - -uint16_t fx248Tou16(const fixed248_t a) { - return (uint16_t)(a >> FIXED248_FRACTION_BITS); -} - -uint8_t fx248Tou8(const fixed248_t a) { - return (uint8_t)(a >> FIXED248_FRACTION_BITS); -} - - - -fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b) { - return a + b; -} - -fixed248_t fx248Addi32(const fixed248_t a, const int32_t b) { - return fx248Addfx248(a, fx248Fromi32(b)); -} - -fixed248_t fx248Addu32(const fixed248_t a, const uint32_t b) { - return fx248Addfx248(a, fx248Fromu32(b)); -} - -fixed248_t fx248Addf32(const fixed248_t a, const float_t b) { - return fx248Addfx248(a, fx248Fromf32(b)); -} - - - -fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b) { - return a - b; -} - -fixed248_t fx248Subi32(const fixed248_t a, const int32_t b) { - return fx248Subfx248(a, fx248Fromi32(b)); -} - -fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b) { - return fx248Subfx248(a, fx248Fromu32(b)); -} - -fixed248_t fx248Subf32(const fixed248_t a, const float_t b) { - return fx248Subfx248(a, fx248Fromf32(b)); -} - - - -fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b) { - return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); -} - -fixed248_t fx248Muli32(const fixed248_t a, const int32_t b) { - return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); -} - -fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b) { - return (fixed248_t)( - ((int64_t)a * (int64_t)(int32_t)b - ) >> FIXED248_FRACTION_BITS); -} - -fixed248_t fx248Mulf32(const fixed248_t a, const float_t b) { - return (fixed248_t)(( - (int64_t)a * (int64_t)(b * (1 << FIXED248_FRACTION_BITS)) - ) >> FIXED248_FRACTION_BITS); -} - - - -fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b) { - assertFalse(b == 0, "Division by zero in fx248Divfx248"); - return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); -} - -fixed248_t fx248Divi32(const fixed248_t a, const int32_t b) { - assertFalse(b == 0, "Division by zero in fx248Divi32"); - return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); -} - -fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b) { - assertFalse(b == 0, "Division by zero in fx248Divu32"); - return (fixed248_t)( - ((int64_t)a << FIXED248_FRACTION_BITS - ) / (int64_t)(int32_t)b); -} - -fixed248_t fx248Divf32(const fixed248_t a, const float_t b) { - assertFalse(b == 0, "Division by zero in fx248Divf32"); - return (fixed248_t)(( - (int64_t)a << FIXED248_FRACTION_BITS - ) / (int64_t)(b * (1 << FIXED248_FRACTION_BITS))); -} - - - -fixed248_t fx248Floor(const fixed248_t a) { - return a & ~((1 << FIXED248_FRACTION_BITS) - 1); -} - -fixed248_t fx248Ceil(const fixed248_t a) { - if(a & ((1 << FIXED248_FRACTION_BITS) - 1)) { - return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); - } - return a; -} - -fixed248_t fx248Round(const fixed248_t a) { - if(a & ((1 << (FIXED248_FRACTION_BITS - 1)) - 1)) { - return (a & ~((1 << FIXED248_FRACTION_BITS) - 1)) + (1 << FIXED248_FRACTION_BITS); - } - return a & ~((1 << FIXED248_FRACTION_BITS) - 1); -} - - - -uint32_t fx248Flooru32(const fixed248_t a) { - return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -uint32_t fx248Ceilu32(const fixed248_t a) { - return (uint32_t)(((a + ((1 << FIXED248_FRACTION_BITS) - 1)) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -uint32_t fx248Roundu32(const fixed248_t a) { - return (uint32_t)(((a + (1 << (FIXED248_FRACTION_BITS - 1))) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); -} - -fixed248_t fx248Sqrt(const fixed248_t a) { - if(a == 0) return 0; - - fixed248_t y = a > FIXED248(1, 0) ? a : FIXED248(1, 0); - fixed248_t last = 0; - int max_iter = 16; - while(y != last && max_iter-- > 0) { - last = y; - int32_t div = (int32_t)(((int64_t)a << FIXED248_FRACTION_BITS) / y); - y = (y + div) >> 1; - } - return y; -} - - - -fixed248_t fx248Max(const fixed248_t a, const fixed248_t b) { - return (a > b) ? a : b; -} - -fixed248_t fx248Min(const fixed248_t a, const fixed248_t b) { - return (a < b) ? a : b; -} - -fixed248_t fx248Clamp( - const fixed248_t a, - const fixed248_t min, - const fixed248_t max -) { - return (a < min) ? min : (a > max) ? max : a; -} - -fixed248_t fx248Abs(const fixed248_t a) { - return (a < 0) ? -a : a; -} - - - -fixed248_t fx248Atan2( - const fixed248_t y, - const fixed248_t x -) { - // Handle special cases - if (x == 0) { - if (y > 0) return FX248_HALF_PI; - if (y < 0) return -FX248_HALF_PI; - return 0; - } - - // Use absolute values for quadrant correction - fixed248_t abs_y = y; - if (abs_y < 0) abs_y = -abs_y; - - fixed248_t angle; - if (abs_y < fx248Abs(x)) { - fixed248_t z = fx248Divfx248(y, x); - fixed248_t z2 = fx248Mulfx248(z, z); - fixed248_t z3 = fx248Mulfx248(z2, z); - fixed248_t z5 = fx248Mulfx248(z3, z2); - angle = fx248Subfx248( - fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), - fx248Divfx248(z3, fx248Fromi32(3)) - ); - if (x < 0) { - if (y < 0) { - angle -= FX248_PI; - } else { - angle += FX248_PI; - } - } - } else { - fixed248_t z = fx248Divfx248(x, y); - fixed248_t z2 = fx248Mulfx248(z, z); - fixed248_t z3 = fx248Mulfx248(z2, z); - fixed248_t z5 = fx248Mulfx248(z3, z2); - angle = fx248Subfx248( - fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))), - fx248Divfx248(z3, fx248Fromi32(3)) - ); - if (y > 0) { - angle = FX248_HALF_PI - angle; - } else { - angle = -FX248_HALF_PI - angle; - } - } - return angle; -} \ No newline at end of file diff --git a/src/dusk/util/fixed.h b/src/dusk/util/fixed.h deleted file mode 100644 index 6e2ae2b..0000000 --- a/src/dusk/util/fixed.h +++ /dev/null @@ -1,379 +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" - -typedef int32_t fixed248_t; - -#define FIXED248_FRACTION_BITS 8 -#define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS) -#define FIXED248_MIN INT32_MIN -#define FIXED248_MAX INT32_MAX -#define FIXED248(i, f) ((fixed248_t)( \ - ((i) << FIXED248_FRACTION_BITS) + \ - (((f) * FIXED248_HIGH_MULTIPLIER) / 100) \ -)) -#define FIXED248_ONE (FIXED248(1, 0)) -#define FIXED248_ZERO (FIXED248(0, 0)) -#define FX248_PI 804 -#define FX248_HALF_PI 402 -#define FX248_3PI_4 603 -#define FX248_NEG_PI -804 - -/** - * 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 fx248Fromu32(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 uint16_t value to a fixed248_t value. - * - * @param b The uint16_t value to convert. - * @return The converted fixed248_t value. - */ -fixed248_t fx248Fromu16(const uint16_t b); - -/** - * Convert a uint8_t value to a fixed248_t value. - * - * @param b The uint8_t value to convert. - * @return The converted fixed248_t value. - */ -fixed248_t fx248Fromu8(const uint8_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); - -/** - * Convert a fixed248_t value to a uint16_t value. - * - * @param a The fixed248_t value to convert. - * @return The converted uint16_t value. - */ -uint16_t fx248Tou16(const fixed248_t a); - -/** - * Convert a fixed248_t value to an uint8_t value. - * - * @param a The fixed248_t value to convert. - * @return The converted uint8_t value. - */ -uint8_t fx248Tou8(const fixed248_t a); - - - -/** - * Add a fixed248_t value to another fixed248_t value. - * - * @param a First fixed248_t value. - * @param b Second fixed248_t value to add to the first value. - * @return The result of the addition as a fixed248_t value. - */ -fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b); - -/** - * Add an int32_t value to a fixed248_t value. - * - * @param a The fixed248_t value to which the int32_t will be added. - * @param b The int32_t value to add to the fixed248_t value. - * @return The result of the addition as a fixed248_t value. - */ -fixed248_t fx248Addi32(const fixed248_t a, const int32_t b); - -/** - * Add a uint32_t value to a fixed248_t value. - * - * @param a The fixed248_t value to which the uint32_t will be added. - * @param b The uint32_t value to add to the fixed248_t value. - * @return The result of the addition as a fixed248_t value. - */ -fixed248_t fx248Addu32(const 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. - * @return The result of the addition as a fixed248_t value. - */ -fixed248_t fx248Addf32(const fixed248_t a, const float_t b); - - - -/** - * Subtract a fixed248_t value from another fixed248_t value. - * - * @param a First fixed248_t value. - * @param b The fixed248_t value to subtract from the first value. - * @return The result of the subtraction as a fixed248_t value. - */ -fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b); - -/** - * Subtract an int32_t value from a fixed248_t value. - * - * @param a The fixed248_t value from which the int32_t will be subtracted. - * @param b The int32_t value to subtract from the fixed248_t value. - * @return The result of the subtraction as a fixed248_t value. - */ -fixed248_t fx248Subi32(const fixed248_t a, const int32_t b); - -/** - * Subtract a uint32_t value from a fixed248_t value. - * - * @param a The fixed248_t value from which the uint32_t will be subtracted. - * @param b The uint32_t value to subtract from the fixed248_t value. - * @return The result of the subtraction as a fixed248_t value. - */ -fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b); - -/** - * Subtract a float_t value from a fixed248_t value. - * - * @param a The fixed248_t value from which the float_t will be subtracted. - * @param b The float_t value to subtract from the fixed248_t value. - * @return The result of the subtraction as a fixed248_t value. - */ -fixed248_t fx248Subf32(const fixed248_t a, const float_t b); - - - -/** - * Multiply two fixed248_t values. - * - * @param a First fixed248_t value. - * @param b Second fixed248_t value to multiply with the first value. - * @return The result of the multiplication as a fixed248_t value. - */ -fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b); - -/** - * Multiply a fixed248_t value by an int32_t value. - * - * @param a The fixed248_t value to multiply. - * @param b The int32_t value to multiply with the fixed248_t value. - * @return The result of the multiplication as a fixed248_t value. - */ -fixed248_t fx248Muli32(const fixed248_t a, const int32_t b); - -/** - * Multiply a fixed248_t value by a uint32_t value. - * - * @param a The fixed248_t value to multiply. - * @param b The uint32_t value to multiply with the fixed248_t value. - * @return The result of the multiplication as a fixed248_t value. - */ -fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b); - -/** - * Multiply a fixed248_t value by a float_t value. - * - * @param a The fixed248_t value to multiply. - * @param b The float_t value to multiply with the fixed248_t value. - * @return The result of the multiplication as a fixed248_t value. - */ -fixed248_t fx248Mulf32(const fixed248_t a, const float_t b); - - - -/** - * Divide two fixed248_t values. - * - * @param a The fixed248_t value to be divided. - * @param b The fixed248_t value to divide by. - * @return The result of the division as a fixed248_t value. - */ -fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b); - -/** - * Divide a fixed248_t value by an int32_t value. - * - * @param a The fixed248_t value to be divided. - * @param b The int32_t value to divide by. - * @return The result of the division as a fixed248_t value. - */ -fixed248_t fx248Divi32(const fixed248_t a, const int32_t b); - -/** - * Divide a fixed248_t value by a uint32_t value. - * - * @param a The fixed248_t value to be divided. - * @param b The uint32_t value to divide by. - * @return The result of the division as a fixed248_t value. - */ -fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b); - -/** - * Divide a fixed248_t value by a float_t value. - * - * @param a The fixed248_t value to be divided. - * @param b The float_t value to divide by. - * @return The result of the division as a fixed248_t value. - */ -fixed248_t fx248Divf32(const 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. - */ -fixed248_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. - */ -fixed248_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. - */ -fixed248_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); - -/** - * Returns the square root of a fixed248_t value. - * - * @param a The fixed248_t value to calculate the square root of. - */ -fixed248_t fx248Sqrt(const fixed248_t a); - - - -/** - * Returns the maximum of two fixed248_t values. - * - * @param a First fixed248_t value. - * @param b Second fixed248_t value. - * @return The maximum of the two values. - */ -fixed248_t fx248Max(const fixed248_t a, const fixed248_t b); - -/** - * Returns the minimum of two fixed248_t values. - * - * @param a First fixed248_t value. - * @param b Second fixed248_t value. - * @return The minimum of the two values. - */ -fixed248_t fx248Min(const fixed248_t a, const fixed248_t b); - -/** - * Clamp a fixed248_t value between a minimum and maximum value. - * - * @param a The fixed248_t value to clamp. - * @param min The minimum value to clamp to. - * @param max The maximum value to clamp to. - * @return The clamped fixed248_t value. - */ -fixed248_t fx248Clamp( - const fixed248_t a, - const fixed248_t min, - const fixed248_t max -); - -/** - * Returns the absolute value of a fixed248_t value. - * - * @param a The fixed248_t value to calculate the absolute value of. - * @return The absolute value as a fixed248_t value. - */ -fixed248_t fx248Abs(const fixed248_t a); - - - -/** - * Calculate the arctangent of a fixed248_t value. - * - * @param y Y coordinate value. - * @param x X coordinate value. - * @return The arctangent of the value as a fixed248_t value. - */ -fixed248_t fx248Atan2( - const fixed248_t y, - const fixed248_t x -); \ No newline at end of file diff --git a/src/dusk/world/chunk.c b/src/dusk/world/chunk.c index 47abf71..1deeef8 100644 --- a/src/dusk/world/chunk.c +++ b/src/dusk/world/chunk.c @@ -292,10 +292,10 @@ void chunkUnload(chunk_t *chunk) { // If the entity is still within our chunk bounds, it's getting unloaded if( - fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && - fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && - fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT && - fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + floorf(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && + ceilf(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && + floorf(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT && + ceilf(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT ) { shouldUnload = true; } else { diff --git a/src/dusk/world/overworld.c b/src/dusk/world/overworld.c index b028077..66c1035 100644 --- a/src/dusk/world/overworld.c +++ b/src/dusk/world/overworld.c @@ -47,8 +47,8 @@ void overworldUpdate() { entity->type == ENTITY_TYPE_PLAYER, "First entity must be player" ); - OVERWORLD_CAMERA_X = fx248Flooru32(entity->x); - OVERWORLD_CAMERA_Y = fx248Flooru32(entity->y); + OVERWORLD_CAMERA_X = (uint32_t)floorf(entity->x); + OVERWORLD_CAMERA_Y = (uint32_t)floorf(entity->y); uint16_t x, y; uint16_t halfWidth, halfHeight; diff --git a/src/duskraylib/display/draw/drawoverworld.c b/src/duskraylib/display/draw/drawoverworld.c index 47b83be..4cafd8e 100644 --- a/src/duskraylib/display/draw/drawoverworld.c +++ b/src/duskraylib/display/draw/drawoverworld.c @@ -113,8 +113,8 @@ void drawOverworldDrawEntity(const entity_t *entity) { assertNotNull(entity, "Entity pointer cannot be NULL"); if(entity->type == ENTITY_TYPE_NULL) return; // Skip null entities - uint32_t x = fx248Tou32(entity->x); - uint32_t y = fx248Tou32(entity->y); + uint32_t x = (uint32_t)(entity->x); + uint32_t y = (uint32_t)(entity->y); uint32_t row = 0; uint32_t col = entity->dir; diff --git a/tools/mapcompile/helper.py b/tools/mapcompile/helper.py index be93631..fe932ed 100644 --- a/tools/mapcompile/helper.py +++ b/tools/mapcompile/helper.py @@ -1,5 +1,2 @@ def floatToFixed248(value): - # Converts a float to the fixed248_t used internally. - high24 = int(value) & 0xFFFFFF - low8 = int((value * 256.0 - high24) * 256.0) & 0xFF - return f'((fixed248_t){(high24 << 8) | low8})' \ No newline at end of file + return value; \ No newline at end of file diff --git a/tools/mapcompile/mapcompile.py b/tools/mapcompile/mapcompile.py index 313ef3f..802b75b 100644 --- a/tools/mapcompile/mapcompile.py +++ b/tools/mapcompile/mapcompile.py @@ -128,8 +128,8 @@ with open(headerPath, 'w') as f: f.write(f"#define WORLD_HEIGHT {worldHeight}\n") # Write out other global variables. - f.write(f"#define WORLD_PLAYER_SPAWN_X ((fixed248_t){floatToFixed248(mapData['playerSpawnX'])})\n") - f.write(f"#define WORLD_PLAYER_SPAWN_Y ((fixed248_t){floatToFixed248(mapData['playerSpawnY'])})\n") + f.write(f"#define WORLD_PLAYER_SPAWN_X ((float_t){floatToFixed248(mapData['playerSpawnX'])})\n") + f.write(f"#define WORLD_PLAYER_SPAWN_Y ((float_t){floatToFixed248(mapData['playerSpawnY'])})\n") f.write("\n")