Suspiciously everything worked when changing to floats
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -92,6 +92,6 @@ assets/borrowed
|
|||||||
|
|
||||||
/archive0
|
/archive0
|
||||||
/archive1
|
/archive1
|
||||||
/archive
|
# /archive
|
||||||
|
|
||||||
__pycache__
|
__pycache__
|
257
archive/fixed.c
Normal file
257
archive/fixed.c
Normal file
@@ -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;
|
||||||
|
}
|
379
archive/fixed.h
Normal file
379
archive/fixed.h
Normal file
@@ -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
|
||||||
|
);
|
@@ -15,6 +15,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
typedef bool bool_t;
|
typedef bool bool_t;
|
||||||
typedef int int_t;
|
typedef int int_t;
|
||||||
|
@@ -61,40 +61,29 @@ void entityUpdate(entity_t *entity) {
|
|||||||
|
|
||||||
ENTITY_CALLBACKS[entity->type].update(entity);
|
ENTITY_CALLBACKS[entity->type].update(entity);
|
||||||
|
|
||||||
if(
|
if(entity->vx == 0.0f && entity->vy == 0.0f) return;
|
||||||
entity->vx == FIXED248(0, 0) &&
|
|
||||||
entity->vy == FIXED248(0, 0)
|
|
||||||
) return;
|
|
||||||
|
|
||||||
fixed248_t newX = entity->x + entity->vx;
|
float_t newX = entity->x + entity->vx;
|
||||||
fixed248_t newY = entity->y + entity->vy;
|
float_t newY = entity->y + entity->vy;
|
||||||
fixed248_t halfTileWH = FIXED248(TILE_WIDTH_HEIGHT / 2, 0);
|
float_t halfTileWH = TILE_WIDTH_HEIGHT / 2.0f;
|
||||||
|
|
||||||
// Because all hit detection is done assuming the entity is a circle, with
|
// Because all hit detection is done assuming the entity is a circle, with
|
||||||
// its position centered, we need to precalc these;
|
// its position centered, we need to precalc these;
|
||||||
fixed248_t selfCircX = fx248Addfx248(newX, halfTileWH);
|
float_t selfCircX = newX + halfTileWH;
|
||||||
fixed248_t selfCircY = fx248Addfx248(newY, halfTileWH);
|
float_t selfCircY = newY + halfTileWH;
|
||||||
fixed248_t selfCircR = halfTileWH;
|
float_t selfCircR = halfTileWH;
|
||||||
|
|
||||||
// Check for collisions with tiles
|
// Check for collisions with tiles
|
||||||
fixed248_t tileStartX = fx248Floor(fx248Divfx248(
|
float_t tileStartX = floorf((newX - halfTileWH) / TILE_WIDTH_HEIGHT);
|
||||||
(newX - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
|
float_t tileStartY = floorf((newY - halfTileWH) / TILE_WIDTH_HEIGHT);
|
||||||
));
|
float_t tileEndX = ceilf((newX + halfTileWH) / TILE_WIDTH_HEIGHT);
|
||||||
fixed248_t tileStartY = fx248Floor(fx248Divfx248(
|
float_t tileEndY = ceilf((newY + halfTileWH) / TILE_WIDTH_HEIGHT);
|
||||||
(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)
|
|
||||||
));
|
|
||||||
|
|
||||||
// For each tile
|
// For each tile
|
||||||
for(fixed248_t y = tileStartY; y <= tileEndY; y += FIXED248_ONE) {
|
for(float_t y = tileStartY; y <= tileEndY; y += 1) {
|
||||||
for(fixed248_t x = tileStartX; x <= tileEndX; x += FIXED248_ONE) {
|
for(float_t x = tileStartX; x <= tileEndX; x += 1) {
|
||||||
uint16_t tileX = fx248Tou16(x);
|
uint16_t tileX = (uint16_t)x;
|
||||||
uint16_t tileY = fx248Tou16(y);
|
uint16_t tileY = (uint16_t)y;
|
||||||
uint16_t chunkX = tileX / CHUNK_WIDTH;
|
uint16_t chunkX = tileX / CHUNK_WIDTH;
|
||||||
uint16_t chunkY = tileY / CHUNK_HEIGHT;
|
uint16_t chunkY = tileY / CHUNK_HEIGHT;
|
||||||
chunk_t *chunk = chunkGetChunkAt(chunkX, chunkY);
|
chunk_t *chunk = chunkGetChunkAt(chunkX, chunkY);
|
||||||
@@ -107,13 +96,9 @@ void entityUpdate(entity_t *entity) {
|
|||||||
collisionresult_t collision = physicsCheckCircleTile(
|
collisionresult_t collision = physicsCheckCircleTile(
|
||||||
selfCircX, selfCircY, selfCircR, x, y, tile
|
selfCircX, selfCircY, selfCircR, x, y, tile
|
||||||
);
|
);
|
||||||
if(collision.hit && collision.depth > FIXED248(0, 1)) {
|
if(collision.hit && collision.depth > 0.01f) {
|
||||||
fixed248_t slideX = fx248Mulfx248(
|
float_t slideX = collision.normalX * collision.depth;
|
||||||
collision.normalX, collision.depth
|
float_t slideY = collision.normalY * collision.depth;
|
||||||
);
|
|
||||||
fixed248_t slideY = fx248Mulfx248(
|
|
||||||
collision.normalY, collision.depth
|
|
||||||
);
|
|
||||||
newX -= slideX;
|
newX -= slideX;
|
||||||
newY -= slideY;
|
newY -= slideY;
|
||||||
}
|
}
|
||||||
@@ -126,7 +111,7 @@ void entityUpdate(entity_t *entity) {
|
|||||||
// Skip self and null entities
|
// Skip self and null entities
|
||||||
if(otherEntity == entity || otherEntity->type == ENTITY_TYPE_NULL) continue;
|
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.
|
// We DONT use selfCircX/Y here because the other entity is ALSO a circle.
|
||||||
collisionresult_t collision = physicsCheckCircleCircle(
|
collisionresult_t collision = physicsCheckCircleCircle(
|
||||||
@@ -136,8 +121,8 @@ void entityUpdate(entity_t *entity) {
|
|||||||
if(!collision.hit) continue;
|
if(!collision.hit) continue;
|
||||||
|
|
||||||
// Collision with entity detected. Slide out of collision.
|
// Collision with entity detected. Slide out of collision.
|
||||||
fixed248_t slideX = fx248Mulfx248(collision.normalX, collision.depth);
|
float_t slideX = collision.normalX * collision.depth;
|
||||||
fixed248_t slideY = fx248Mulfx248(collision.normalY, collision.depth);
|
float_t slideY = collision.normalY * collision.depth;
|
||||||
newX -= slideX;
|
newX -= slideX;
|
||||||
newY -= slideY;
|
newY -= slideY;
|
||||||
} while(++otherEntity < ENTITIES + ENTITY_COUNT_MAX);
|
} while(++otherEntity < ENTITIES + ENTITY_COUNT_MAX);
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
#include "util/fixed.h"
|
|
||||||
|
|
||||||
#define ENTITY_COUNT_MAX 32
|
#define ENTITY_COUNT_MAX 32
|
||||||
|
|
||||||
@@ -33,8 +32,8 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct _entity_t {
|
typedef struct _entity_t {
|
||||||
uint32_t id;// Completely unique ID for this entity.
|
uint32_t id;// Completely unique ID for this entity.
|
||||||
fixed248_t x, y;
|
float_t x, y;
|
||||||
fixed248_t vx, vy;
|
float_t vx, vy;
|
||||||
entitytype_t type;
|
entitytype_t type;
|
||||||
entitydir_t dir;
|
entitydir_t dir;
|
||||||
|
|
||||||
@@ -69,9 +68,9 @@ void entityLoad(entity_t *entity, const entity_t *source);
|
|||||||
void entityUpdate(entity_t *entity);
|
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.
|
* @param dir The entity direction to convert.
|
||||||
* @return The angle corresponding to the entity direction.
|
* @return The angle corresponding to the entity direction.
|
||||||
*/
|
*/
|
||||||
fixed248_t entityDirToAngle(const entitydir_t dir);
|
float_t entityDirToAngle(const entitydir_t dir);
|
@@ -114,12 +114,9 @@ void playerEntityUpdate(entity_t *entity) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed248_t distanceX = fx248Subfx248(other->x, entity->x);
|
float_t distanceX = other->x - entity->x;
|
||||||
fixed248_t distanceY = fx248Subfx248(other->y, entity->y);
|
float_t distanceY = other->y - entity->y;
|
||||||
fixed248_t distance = fx248Sqrt(fx248Addfx248(
|
float_t distance = sqrtf(distanceX * distanceX + distanceY * distanceY);
|
||||||
fx248Mulfx248(distanceX, distanceX),
|
|
||||||
fx248Mulfx248(distanceY, distanceY)
|
|
||||||
));
|
|
||||||
|
|
||||||
if(distance > PLAYER_INTERACT_RANGE) {
|
if(distance > PLAYER_INTERACT_RANGE) {
|
||||||
other++;
|
other++;
|
||||||
@@ -127,16 +124,16 @@ void playerEntityUpdate(entity_t *entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get angle
|
// Get angle
|
||||||
fixed248_t angle = fx248Atan2(distanceY, distanceX);
|
float_t angle = atan2f(distanceY, distanceX);
|
||||||
while(angle < 0) angle += FX248_PI;
|
while(angle < 0) angle += M_PI;
|
||||||
fixed248_t selfAngle = entityDirToAngle(entity->dir);
|
float_t selfAngle = entityDirToAngle(entity->dir);
|
||||||
while(selfAngle < 0) selfAngle += FX248_PI;
|
while(selfAngle < 0) selfAngle += M_PI;
|
||||||
|
|
||||||
// Check if angle is within range
|
// Check if angle is within range
|
||||||
fixed248_t angleDiff = fx248Subfx248(angle, selfAngle);
|
float_t angleDiff = angle - selfAngle;
|
||||||
if(angleDiff > FX248_HALF_PI) angleDiff -= FX248_PI;
|
if(angleDiff > (M_PI_2)) angleDiff -= M_PI;
|
||||||
if(angleDiff < -FX248_HALF_PI) angleDiff += FX248_PI;
|
if(angleDiff < -M_PI_2) angleDiff += M_PI;
|
||||||
if(fx248Abs(angleDiff) > PLAYER_INTERACT_ANGLE) {
|
if(fabsf(angleDiff) > PLAYER_INTERACT_ANGLE) {
|
||||||
other++;
|
other++;
|
||||||
continue;
|
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) {
|
switch(dir) {
|
||||||
case ENTITY_DIR_NORTH: return FX248_HALF_PI;
|
case ENTITY_DIR_NORTH: return (M_PI_2);
|
||||||
case ENTITY_DIR_SOUTH: return -FX248_HALF_PI;
|
case ENTITY_DIR_SOUTH: return -(M_PI_2);
|
||||||
case ENTITY_DIR_EAST: return 0;
|
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
|
default: return 0; // Should never happen
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
#include "util/fixed.h"
|
|
||||||
#include "item/inventory.h"
|
#include "item/inventory.h"
|
||||||
|
|
||||||
typedef struct _entity_t entity_t;
|
typedef struct _entity_t entity_t;
|
||||||
@@ -17,12 +16,10 @@ typedef struct {
|
|||||||
} playerentity_t;
|
} playerentity_t;
|
||||||
|
|
||||||
#define PLAYER_ENTITY_ID (UINT32_MAX-1)
|
#define PLAYER_ENTITY_ID (UINT32_MAX-1)
|
||||||
#define PLAYER_MOVE_SPEED FIXED248(1, 0)
|
#define PLAYER_MOVE_SPEED 1.0f
|
||||||
#define PLAYER_MOVE_SPEED_XY FIXED248(0, 80)
|
#define PLAYER_MOVE_SPEED_XY 0.70710678118f
|
||||||
#define PLAYER_INTERACT_RANGE FIXED248( \
|
#define PLAYER_INTERACT_RANGE (TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3))
|
||||||
(TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3)), 0 \
|
#define PLAYER_INTERACT_ANGLE 0.68359375f
|
||||||
)
|
|
||||||
#define PLAYER_INTERACT_ANGLE ((fixed248_t)175)
|
|
||||||
|
|
||||||
extern inventory_t PLAYER_INVENTORY;
|
extern inventory_t PLAYER_INVENTORY;
|
||||||
|
|
||||||
|
@@ -9,23 +9,20 @@
|
|||||||
#include "world/tiledata.h"
|
#include "world/tiledata.h"
|
||||||
|
|
||||||
collisionresult_t physicsCheckCircleCircle(
|
collisionresult_t physicsCheckCircleCircle(
|
||||||
fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r,
|
float_t circle0x, float_t circle0y, float_t circle0r,
|
||||||
fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r
|
float_t circle1x, float_t circle1y, float_t circle1r
|
||||||
) {
|
) {
|
||||||
collisionresult_t result;
|
collisionresult_t result;
|
||||||
// Compute vector between centers
|
// Compute vector between centers
|
||||||
fixed248_t dx = fx248Subfx248(circle1x, circle0x);
|
float_t dx = circle1x - circle0x;
|
||||||
fixed248_t dy = fx248Subfx248(circle1y, circle0y);
|
float_t dy = circle1y - circle0y;
|
||||||
|
|
||||||
// Distance squared between centers
|
// Distance squared between centers
|
||||||
fixed248_t distSq = fx248Addfx248(
|
float_t distSq = (dx * dx) + (dy * dy);
|
||||||
fx248Mulfx248(dx, dx),
|
|
||||||
fx248Mulfx248(dy, dy)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Sum of radii
|
// Sum of radii
|
||||||
fixed248_t rSum = fx248Addfx248(circle0r, circle1r);
|
float_t rSum = circle0r + circle1r;
|
||||||
fixed248_t rSumSq = fx248Mulfx248(rSum, rSum);
|
float_t rSumSq = rSum * rSum;
|
||||||
|
|
||||||
if(distSq > rSumSq) {
|
if(distSq > rSumSq) {
|
||||||
// No collision
|
// No collision
|
||||||
@@ -34,66 +31,66 @@ collisionresult_t physicsCheckCircleCircle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Collision: calculate normal and penetration depth
|
// 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 centers are the same, pick arbitrary normal (1,0)
|
||||||
if(dist == 0) {
|
if(dist == 0) {
|
||||||
result.normalX = FIXED248(1,0);
|
result.normalX = 1;
|
||||||
result.normalY = 0;
|
result.normalY = 0;
|
||||||
result.depth = rSum;
|
result.depth = rSum;
|
||||||
} else {
|
} else {
|
||||||
// Normalized direction from circle0 to circle1
|
// Normalized direction from circle0 to circle1
|
||||||
result.normalX = fx248Divfx248(dx, dist);
|
result.normalX = dx / dist;
|
||||||
result.normalY = fx248Divfx248(dy, dist);
|
result.normalY = dy / dist;
|
||||||
// Penetration depth = sum of radii - distance
|
// Penetration depth = sum of radii - distance
|
||||||
result.depth = fx248Subfx248(rSum, dist);
|
result.depth = rSum - dist;
|
||||||
}
|
}
|
||||||
result.hit = true;
|
result.hit = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
collisionresult_t physicsCheckCircleAABB(
|
collisionresult_t physicsCheckCircleAABB(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t aabbX, fixed248_t aabbY,
|
float_t aabbX, float_t aabbY,
|
||||||
fixed248_t aabbWidth, fixed248_t aabbHeight
|
float_t aabbWidth, float_t aabbHeight
|
||||||
) {
|
) {
|
||||||
collisionresult_t result;
|
collisionresult_t result;
|
||||||
|
|
||||||
// Find the closest point on the AABB to the circle center
|
// Find the closest point on the AABB to the circle center
|
||||||
fixed248_t closestX = fx248Max(
|
float_t closestX = fmaxf(
|
||||||
aabbX, fx248Min(circleX, fx248Addfx248(aabbX, aabbWidth))
|
aabbX, fminf(circleX, aabbX + aabbWidth)
|
||||||
);
|
);
|
||||||
fixed248_t closestY = fx248Max(
|
float_t closestY = fmaxf(
|
||||||
aabbY, fx248Min(circleY, fx248Addfx248(aabbY, aabbHeight))
|
aabbY, fminf(circleY, aabbY + aabbHeight)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Vector from circle center to closest point
|
// Vector from circle center to closest point
|
||||||
fixed248_t dx = fx248Subfx248(closestX, circleX);
|
float_t dx = closestX - circleX;
|
||||||
fixed248_t dy = fx248Subfx248(closestY, circleY);
|
float_t dy = closestY - circleY;
|
||||||
|
|
||||||
// Distance squared from circle center to closest point
|
// 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
|
// Check if distance is less than radius squared
|
||||||
if(distSq > fx248Mulfx248(circleR, circleR)) {
|
if(distSq > (circleR * circleR)) {
|
||||||
result.hit = false;
|
result.hit = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collision: calculate normal and penetration depth
|
// Collision: calculate normal and penetration depth
|
||||||
fixed248_t dist = fx248Sqrt(distSq);
|
float_t dist = sqrtf(distSq);
|
||||||
|
|
||||||
if(dist <= FIXED248(0, 1)) {
|
if(dist <= 1) {
|
||||||
// Circle center is at the AABB corner
|
// Circle center is at the AABB corner
|
||||||
result.normalX = FIXED248(1,0);
|
result.normalX = 1.0f;
|
||||||
result.normalY = FIXED248(0,1);
|
result.normalY = 0.0f;
|
||||||
result.depth = circleR;
|
result.depth = circleR;
|
||||||
} else {
|
} else {
|
||||||
// Normalized direction from circle center to closest point
|
// Normalized direction from circle center to closest point
|
||||||
result.normalX = fx248Divfx248(dx, dist);
|
result.normalX = dx / dist;
|
||||||
result.normalY = fx248Divfx248(dy, dist);
|
result.normalY = dy / dist;
|
||||||
// Penetration depth = radius - distance
|
// Penetration depth = radius - distance
|
||||||
result.depth = fx248Subfx248(circleR, dist);
|
result.depth = circleR - dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.hit = true;
|
result.hit = true;
|
||||||
@@ -101,116 +98,99 @@ collisionresult_t physicsCheckCircleAABB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void physicsClosestPointOnSegment(
|
void physicsClosestPointOnSegment(
|
||||||
fixed248_t ax, fixed248_t ay,
|
float_t ax, float_t ay,
|
||||||
fixed248_t bx, fixed248_t by,
|
float_t bx, float_t by,
|
||||||
fixed248_t px, fixed248_t py,
|
float_t px, float_t py,
|
||||||
fixed248_t *outX, fixed248_t *outY
|
float_t *outX, float_t *outY
|
||||||
) {
|
) {
|
||||||
fixed248_t abx = fx248Subfx248(bx, ax);
|
float_t abx = bx - ax;
|
||||||
fixed248_t aby = fx248Subfx248(by, ay);
|
float_t aby = by - ay;
|
||||||
fixed248_t apx = fx248Subfx248(px, ax);
|
float_t apx = px - ax;
|
||||||
fixed248_t apy = fx248Subfx248(py, ay);
|
float_t apy = py - ay;
|
||||||
|
|
||||||
fixed248_t abLenSq = fx248Addfx248(
|
float_t abLenSq = (abx * abx) + (aby * aby);
|
||||||
fx248Mulfx248(abx, abx),
|
|
||||||
fx248Mulfx248(aby, aby)
|
|
||||||
);
|
|
||||||
|
|
||||||
if(abLenSq == FIXED248_ZERO) {
|
if(abLenSq == 0) {
|
||||||
*outX = ax;
|
*outX = ax;
|
||||||
*outY = ay;
|
*outY = ay;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed248_t t = fx248Divfx248(
|
float_t t = apx * abx + apy * aby;
|
||||||
fx248Addfx248(fx248Mulfx248(apx, abx), fx248Mulfx248(apy, aby)),
|
t /= abLenSq;
|
||||||
abLenSq
|
|
||||||
);
|
|
||||||
|
|
||||||
if(t < FIXED248_ZERO) t = FIXED248_ZERO;
|
if(t < 0) t = 0;
|
||||||
if(t > FIXED248_ONE) t = FIXED248_ONE;
|
if(t > 1) t = 1;
|
||||||
|
|
||||||
*outX = fx248Addfx248(ax, fx248Mulfx248(abx, t));
|
*outX = ax + (abx * t);
|
||||||
*outY = fx248Addfx248(ay, fx248Mulfx248(aby, t));
|
*outY = ay + (aby * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t physicsIsPointInTriangle(
|
bool_t physicsIsPointInTriangle(
|
||||||
fixed248_t px, fixed248_t py,
|
float_t px, float_t py,
|
||||||
fixed248_t ax, fixed248_t ay,
|
float_t ax, float_t ay,
|
||||||
fixed248_t bx, fixed248_t by,
|
float_t bx, float_t by,
|
||||||
fixed248_t cx, fixed248_t cy
|
float_t cx, float_t cy
|
||||||
) {
|
) {
|
||||||
fixed248_t abx = fx248Subfx248(bx, ax);
|
float_t abx = bx - ax;
|
||||||
fixed248_t aby = fx248Subfx248(by, ay);
|
float_t aby = by - ay;
|
||||||
fixed248_t bcx = fx248Subfx248(cx, bx);
|
float_t bcx = cx - bx;
|
||||||
fixed248_t bcy = fx248Subfx248(cy, by);
|
float_t bcy = cy - by;
|
||||||
fixed248_t cax = fx248Subfx248(ax, cx);
|
float_t cax = ax - cx;
|
||||||
fixed248_t cay = fx248Subfx248(ay, cy);
|
float_t cay = ay - cy;
|
||||||
|
|
||||||
fixed248_t apx = fx248Subfx248(px, ax);
|
float_t apx = px - ax;
|
||||||
fixed248_t apy = fx248Subfx248(py, ay);
|
float_t apy = py - ay;
|
||||||
fixed248_t bpx = fx248Subfx248(px, bx);
|
float_t bpx = px - bx;
|
||||||
fixed248_t bpy = fx248Subfx248(py, by);
|
float_t bpy = py - by;
|
||||||
fixed248_t cpx = fx248Subfx248(px, cx);
|
float_t cpx = px - cx;
|
||||||
fixed248_t cpy = fx248Subfx248(py, cy);
|
float_t cpy = py - cy;
|
||||||
|
|
||||||
fixed248_t cross1 = fx248Subfx248(
|
float_t cross1 = (abx * apy) - (aby * apx);
|
||||||
fx248Mulfx248(abx, apy),
|
float_t cross2 = (bcx * bpy) - (bcy * bpx);
|
||||||
fx248Mulfx248(aby, apx)
|
float_t cross3 = (cax * cpy) - (cay * cpx);
|
||||||
);
|
|
||||||
fixed248_t cross2 = fx248Subfx248(
|
|
||||||
fx248Mulfx248(bcx, bpy),
|
|
||||||
fx248Mulfx248(bcy, bpx)
|
|
||||||
);
|
|
||||||
fixed248_t cross3 = fx248Subfx248(
|
|
||||||
fx248Mulfx248(cax, cpy),
|
|
||||||
fx248Mulfx248(cay, cpx)
|
|
||||||
);
|
|
||||||
|
|
||||||
bool_t hasNeg = (
|
bool_t hasNeg = (
|
||||||
(cross1 < FIXED248_ZERO) ||
|
(cross1 < 0) ||
|
||||||
(cross2 < FIXED248_ZERO) ||
|
(cross2 < 0) ||
|
||||||
(cross3 < FIXED248_ZERO)
|
(cross3 < 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
bool_t hasPos = (
|
bool_t hasPos = (
|
||||||
(cross1 > FIXED248_ZERO) ||
|
(cross1 > 0) ||
|
||||||
(cross2 > FIXED248_ZERO) ||
|
(cross2 > 0) ||
|
||||||
(cross3 > FIXED248_ZERO)
|
(cross3 > 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
return !(hasNeg && hasPos);
|
return !(hasNeg && hasPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
collisionresult_t physicsCheckCircleTriangle(
|
collisionresult_t physicsCheckCircleTriangle(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t triX0, fixed248_t triY0,
|
float_t triX0, float_t triY0,
|
||||||
fixed248_t triX1, fixed248_t triY1,
|
float_t triX1, float_t triY1,
|
||||||
fixed248_t triX2, fixed248_t triY2
|
float_t triX2, float_t triY2
|
||||||
) {
|
) {
|
||||||
collisionresult_t result = { .hit = false };
|
collisionresult_t result = { .hit = false };
|
||||||
fixed248_t vx[3] = { triX0, triX1, triX2 };
|
float_t vx[3] = { triX0, triX1, triX2 };
|
||||||
fixed248_t vy[3] = { triY0, triY1, triY2 };
|
float_t vy[3] = { triY0, triY1, triY2 };
|
||||||
|
|
||||||
fixed248_t closestX = FIXED248_ZERO;
|
float_t closestX = 0;
|
||||||
fixed248_t closestY = FIXED248_ZERO;
|
float_t closestY = 0;
|
||||||
fixed248_t minDistSq = FIXED248_MAX;
|
float_t minDistSq = FLT_MAX;
|
||||||
|
|
||||||
for(uint8_t i = 0; i < 3; ++i) {
|
for(uint8_t i = 0; i < 3; ++i) {
|
||||||
uint8_t j = (i + 1) % 3;
|
uint8_t j = (i + 1) % 3;
|
||||||
|
|
||||||
fixed248_t testX, testY;
|
float_t testX, testY;
|
||||||
physicsClosestPointOnSegment(
|
physicsClosestPointOnSegment(
|
||||||
vx[i], vy[i], vx[j], vy[j],
|
vx[i], vy[i], vx[j], vy[j],
|
||||||
circleX, circleY, &testX, &testY
|
circleX, circleY, &testX, &testY
|
||||||
);
|
);
|
||||||
|
|
||||||
fixed248_t dx = fx248Subfx248(circleX, testX);
|
float_t dx = circleX - testX;
|
||||||
fixed248_t dy = fx248Subfx248(circleY, testY);
|
float_t dy = circleY - testY;
|
||||||
fixed248_t distSq = fx248Addfx248(
|
float_t distSq = (dx * dx) + (dy * dy);
|
||||||
fx248Mulfx248(dx, dx),
|
|
||||||
fx248Mulfx248(dy, dy)
|
|
||||||
);
|
|
||||||
|
|
||||||
if(distSq < minDistSq) {
|
if(distSq < minDistSq) {
|
||||||
minDistSq = distSq;
|
minDistSq = distSq;
|
||||||
@@ -221,44 +201,44 @@ collisionresult_t physicsCheckCircleTriangle(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed248_t dist = fx248Sqrt(minDistSq);
|
float_t dist = sqrtf(minDistSq);
|
||||||
fixed248_t invDist = (
|
float_t invDist = (
|
||||||
(dist != FIXED248_ZERO) ?
|
(dist != 0) ?
|
||||||
fx248Divfx248(FIXED248_ONE, dist) :
|
(1.0f / dist) :
|
||||||
FIXED248_ONE
|
1.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
result.normalX = fx248Mulfx248(-result.normalX, invDist);
|
result.normalX = -result.normalX * invDist;
|
||||||
result.normalY = fx248Mulfx248(-result.normalY, invDist);
|
result.normalY = -result.normalY * invDist;
|
||||||
|
|
||||||
if(physicsIsPointInTriangle(
|
if(physicsIsPointInTriangle(
|
||||||
circleX, circleY, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2]
|
circleX, circleY, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2]
|
||||||
)) {
|
)) {
|
||||||
result.hit = true;
|
result.hit = true;
|
||||||
result.depth = fx248Subfx248(circleR, dist);
|
result.depth = circleR - dist;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dist < circleR) {
|
if(dist < circleR) {
|
||||||
result.hit = true;
|
result.hit = true;
|
||||||
result.depth = fx248Subfx248(circleR, dist);
|
result.depth = circleR - dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
collisionresult_t physicsCheckCircleTile(
|
collisionresult_t physicsCheckCircleTile(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t tileX, fixed248_t tileY, tile_t tile
|
float_t tileX, float_t tileY, tile_t tile
|
||||||
) {
|
) {
|
||||||
collisionresult_t result;
|
collisionresult_t result;
|
||||||
|
|
||||||
#define tw FIXED248(TILE_WIDTH_HEIGHT, 0)
|
#define tw (TILE_WIDTH_HEIGHT)
|
||||||
#define th FIXED248(TILE_WIDTH_HEIGHT, 0)
|
#define th (TILE_WIDTH_HEIGHT)
|
||||||
#define lx fx248Mulfx248(tileX, tw)
|
#define lx (tileX * tw)
|
||||||
#define ty fx248Mulfx248(tileY, th)
|
#define ty (tileY * th)
|
||||||
#define rx fx248Addfx248(lx, tw)
|
#define rx (lx + tw)
|
||||||
#define by fx248Addfx248(ty, th)
|
#define by (ty + th)
|
||||||
|
|
||||||
switch(TILE_META_DATA[tile].solidType) {
|
switch(TILE_META_DATA[tile].solidType) {
|
||||||
case TILE_SOLID_FULL:
|
case TILE_SOLID_FULL:
|
||||||
|
@@ -6,13 +6,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util/fixed.h"
|
|
||||||
#include "world/tile.h"
|
#include "world/tile.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool_t hit;
|
bool_t hit;
|
||||||
fixed248_t normalX, normalY;
|
float_t normalX, normalY;
|
||||||
fixed248_t depth;
|
float_t depth;
|
||||||
} collisionresult_t;
|
} collisionresult_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,8 +26,8 @@ typedef struct {
|
|||||||
* @return A collisionresult_t structure containing collision information.
|
* @return A collisionresult_t structure containing collision information.
|
||||||
*/
|
*/
|
||||||
collisionresult_t physicsCheckCircleCircle(
|
collisionresult_t physicsCheckCircleCircle(
|
||||||
fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r,
|
float_t circle0x, float_t circle0y, float_t circle0r,
|
||||||
fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r
|
float_t circle1x, float_t circle1y, float_t circle1r
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,9 +43,9 @@ collisionresult_t physicsCheckCircleCircle(
|
|||||||
* @return A collisionresult_t structure containing collision information.
|
* @return A collisionresult_t structure containing collision information.
|
||||||
*/
|
*/
|
||||||
collisionresult_t physicsCheckCircleAABB(
|
collisionresult_t physicsCheckCircleAABB(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t aabb, fixed248_t aabbY,
|
float_t aabb, float_t aabbY,
|
||||||
fixed248_t aabbWidth, fixed248_t aabbHeight
|
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.
|
* @param outY Pointer to store the Y coordinate of the closest point.
|
||||||
*/
|
*/
|
||||||
void physicsClosestPointOnSegment(
|
void physicsClosestPointOnSegment(
|
||||||
fixed248_t ax, fixed248_t ay,
|
float_t ax, float_t ay,
|
||||||
fixed248_t bx, fixed248_t by,
|
float_t bx, float_t by,
|
||||||
fixed248_t px, fixed248_t py,
|
float_t px, float_t py,
|
||||||
fixed248_t *outX, fixed248_t *outY
|
float_t *outX, float_t *outY
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,10 +81,10 @@ void physicsClosestPointOnSegment(
|
|||||||
* @return true if the point is inside the triangle, false otherwise.
|
* @return true if the point is inside the triangle, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool_t physicsIsPointInTriangle(
|
bool_t physicsIsPointInTriangle(
|
||||||
fixed248_t px, fixed248_t py,
|
float_t px, float_t py,
|
||||||
fixed248_t x0, fixed248_t y0,
|
float_t x0, float_t y0,
|
||||||
fixed248_t x1, fixed248_t y1,
|
float_t x1, float_t y1,
|
||||||
fixed248_t x2, fixed248_t y2
|
float_t x2, float_t y2
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,10 +102,10 @@ bool_t physicsIsPointInTriangle(
|
|||||||
* @return A collisionresult_t structure containing collision information.
|
* @return A collisionresult_t structure containing collision information.
|
||||||
*/
|
*/
|
||||||
collisionresult_t physicsCheckCircleTriangle(
|
collisionresult_t physicsCheckCircleTriangle(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t triX0, fixed248_t triY0,
|
float_t triX0, float_t triY0,
|
||||||
fixed248_t triX1, fixed248_t triY1,
|
float_t triX1, float_t triY1,
|
||||||
fixed248_t triX2, fixed248_t triY2
|
float_t triX2, float_t triY2
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,6 +120,6 @@ collisionresult_t physicsCheckCircleTriangle(
|
|||||||
* @return A collisionresult_t structure containing collision information.
|
* @return A collisionresult_t structure containing collision information.
|
||||||
*/
|
*/
|
||||||
collisionresult_t physicsCheckCircleTile(
|
collisionresult_t physicsCheckCircleTile(
|
||||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
float_t circleX, float_t circleY, float_t circleR,
|
||||||
fixed248_t tileX, fixed248_t tileY, tile_t tile
|
float_t tileX, float_t tileY, tile_t tile
|
||||||
);
|
);
|
@@ -6,7 +6,6 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
fixed.c
|
|
||||||
memory.c
|
memory.c
|
||||||
string.c
|
string.c
|
||||||
)
|
)
|
@@ -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;
|
|
||||||
}
|
|
@@ -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
|
|
||||||
);
|
|
@@ -292,10 +292,10 @@ void chunkUnload(chunk_t *chunk) {
|
|||||||
|
|
||||||
// If the entity is still within our chunk bounds, it's getting unloaded
|
// If the entity is still within our chunk bounds, it's getting unloaded
|
||||||
if(
|
if(
|
||||||
fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
|
floorf(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
|
||||||
fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
|
ceilf(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT &&
|
||||||
fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT &&
|
floorf(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT &&
|
||||||
fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT
|
ceilf(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT
|
||||||
) {
|
) {
|
||||||
shouldUnload = true;
|
shouldUnload = true;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -47,8 +47,8 @@ void overworldUpdate() {
|
|||||||
entity->type == ENTITY_TYPE_PLAYER,
|
entity->type == ENTITY_TYPE_PLAYER,
|
||||||
"First entity must be player"
|
"First entity must be player"
|
||||||
);
|
);
|
||||||
OVERWORLD_CAMERA_X = fx248Flooru32(entity->x);
|
OVERWORLD_CAMERA_X = (uint32_t)floorf(entity->x);
|
||||||
OVERWORLD_CAMERA_Y = fx248Flooru32(entity->y);
|
OVERWORLD_CAMERA_Y = (uint32_t)floorf(entity->y);
|
||||||
|
|
||||||
uint16_t x, y;
|
uint16_t x, y;
|
||||||
uint16_t halfWidth, halfHeight;
|
uint16_t halfWidth, halfHeight;
|
||||||
|
@@ -113,8 +113,8 @@ void drawOverworldDrawEntity(const entity_t *entity) {
|
|||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
if(entity->type == ENTITY_TYPE_NULL) return; // Skip null entities
|
if(entity->type == ENTITY_TYPE_NULL) return; // Skip null entities
|
||||||
|
|
||||||
uint32_t x = fx248Tou32(entity->x);
|
uint32_t x = (uint32_t)(entity->x);
|
||||||
uint32_t y = fx248Tou32(entity->y);
|
uint32_t y = (uint32_t)(entity->y);
|
||||||
uint32_t row = 0;
|
uint32_t row = 0;
|
||||||
uint32_t col = entity->dir;
|
uint32_t col = entity->dir;
|
||||||
|
|
||||||
|
@@ -1,5 +1,2 @@
|
|||||||
def floatToFixed248(value):
|
def floatToFixed248(value):
|
||||||
# Converts a float to the fixed248_t used internally.
|
return value;
|
||||||
high24 = int(value) & 0xFFFFFF
|
|
||||||
low8 = int((value * 256.0 - high24) * 256.0) & 0xFF
|
|
||||||
return f'((fixed248_t){(high24 << 8) | low8})'
|
|
@@ -128,8 +128,8 @@ with open(headerPath, 'w') as f:
|
|||||||
f.write(f"#define WORLD_HEIGHT {worldHeight}\n")
|
f.write(f"#define WORLD_HEIGHT {worldHeight}\n")
|
||||||
|
|
||||||
# Write out other global variables.
|
# 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_X ((float_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_Y ((float_t){floatToFixed248(mapData['playerSpawnY'])})\n")
|
||||||
|
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user