//--- // fixed: 16:16 fixed-point arithmetic //--- //vient de https://gitea.planet-casio.com/Slyvtt/OutRun/src/branch/master/src // #pragma once #include #include "config.h" typedef int32_t fixed_t; /* Standard arithmetic. */ typedef struct { int32_t x,y; } V2d; typedef struct { int16_t x,y; } V2d16; 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) { if(!right) return 0; /* 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 fixfloat(float constant) { return (fixed_t)(constant * 65536); } static inline fixed_t fdec(fixed_t f) { return f & 0xffff; } 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 fsq(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 fixabs(fixed_t x){ return x > 0 ? x:-x; } static inline fixed_t fV2d_dotp(V2d u, V2d v){ return fmul(u.x,v.x) + fmul(u.y,v.y); } static inline uint16_t mul_color(uint16_t color, fixed_t multpl){ int r = color & 31; int g = (color>>5) & 63; int b = (color>>11) & 31; r *= multpl; g *= multpl; b *= multpl; return (ffloor(b)<<11) | (ffloor(g)<<5) | r; }