pokeemerald/include/fpmath.h

62 lines
1.6 KiB
C

#ifndef FPMATH_H_
#define FPMATH_H_
typedef s16 q4_12_t;
typedef u32 uq4_12_t;
#define Q_4_12_SHIFT (12)
#define UQ_4_12_SHIFT (12)
// Converts a number to Q8.8 fixed-point format
#define Q_8_8(n) ((s16)((n) * 256))
// Converts a number to Q4.12 fixed-point format
#define Q_4_12(n) ((q4_12_t)((n) * 4096))
#define UQ_4_12(n) ((uq4_12_t)((n) * 4096))
// Converts a number to Q24.8 fixed-point format
#define Q_24_8(n) ((s32)((n) << 8))
// Converts a Q8.8 fixed-point format number to a regular integer
#define Q_8_8_TO_INT(n) ((s32)((n) / 256))
// Converts a Q4.12 fixed-point format number to a regular integer
#define Q_4_12_TO_INT(n) ((s32)((n) / 4096))
#define UQ_4_12_TO_INT(n) ((u32)((n) / 4096))
// Converts a Q24.8 fixed-point format number to a regular integer
#define Q_24_8_TO_INT(n) ((s32)((n) >> 8))
// Rounding value for Q4.12 fixed-point format
#define Q_4_12_ROUND ((1) << (Q_4_12_SHIFT - 1))
#define UQ_4_12_ROUND ((1) << (UQ_4_12_SHIFT - 1))
// Basic arithmetic for fixed point number formats
// Consumers should use encapsulated functions where possible
// FP API does not provide sanity checks against overflows
static inline uq4_12_t uq4_12_add(uq4_12_t a, uq4_12_t b)
{
return a + b;
}
static inline uq4_12_t uq4_12_subtract(uq4_12_t a, uq4_12_t b)
{
return a - b;
}
static inline uq4_12_t uq4_12_multiply(uq4_12_t a, uq4_12_t b)
{
u32 product = (u32) a * b;
return (product + UQ_4_12_ROUND) >> UQ_4_12_SHIFT;
}
static inline uq4_12_t uq4_12_divide(uq4_12_t dividend, uq4_12_t divisor)
{
if (divisor == UQ_4_12(0.0)) return UQ_4_12(0);
return (dividend << UQ_4_12_SHIFT) / divisor;
}
#endif // FPMATH_H_