//--- // fixed: 16:16 fixed-point arithmetic //--- #pragma once #include typedef int32_t fixed_t; #include "util.h" /* Type of map coordinates */ typedef fixed_t map_coord_t; /* Standard arithmetic. */ static inline fixed_t fmul(fixed_t left, fixed_t right) { /* Generally optimized by the compiler to use dmuls.l and xtrct */ int64_t p = (int64_t)left * (int64_t)right; return (int32_t)(p >> 16); } static inline fixed_t fdiv(fixed_t left, fixed_t right) { /* Pretty slow */ int64_t d = (int64_t)left << 16; return d / right; } #define fix(x) ((int)((x) * 65536)) static inline fixed_t fixdouble(double constant) { return (fixed_t)(constant * 65536); } static inline fixed_t fdec(fixed_t f) { return f & 0xffff; } static inline fixed_t fsqrt(fixed_t f) { return sqrtll((int64_t)f << 16); } static inline int ffloor(fixed_t f) { return f >> 16; } static inline int fceil(fixed_t f) { return (f + 0xffff) >> 16; } static inline int fround(fixed_t f) { return (f + 0x8000) >> 16; } static inline float f2float(fixed_t f) { return (float)f / 65536; } static inline double f2double(fixed_t f) { return (double)f / 65536; } static inline fixed_t feasein(fixed_t x) { return fmul(x, x); } static inline fixed_t fease(fixed_t x) { if(x <= fix(0.5)) { return 2 * fmul(x, x); } else { x = fix(1) - x; return fix(1) - 2 * fmul(x, x); } } static inline fixed_t fclamp(fixed_t x, fixed_t min, fixed_t max) { return (x <= min) ? min : (x >= max) ? max : x; }