Copy3DEngine/include/C3D/fixed.h

108 lines
1.9 KiB
C
Raw Permalink Normal View History

2023-07-20 12:31:08 +02:00
//---
// fixed: 16:16 fixed-point arithmetic
//---
//vient de https://gitea.planet-casio.com/Slyvtt/OutRun/src/branch/master/src
//
#pragma once
2024-10-05 00:56:13 +02:00
2023-07-20 12:31:08 +02:00
#include <stdint.h>
2024-10-05 00:56:13 +02:00
#include "config.h"
2023-07-20 12:31:08 +02:00
typedef int32_t fixed_t;
/* Standard arithmetic. */
2024-08-09 18:40:08 +02:00
typedef struct {
int32_t x ,y;
} V2d;
2023-07-20 12:31:08 +02:00
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 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 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);
}
}
2024-08-09 18:40:08 +02:00
2024-10-05 00:56:13 +02:00
static inline fixed_t fixabs(fixed_t x){
2024-10-05 21:48:42 +02:00
return x & 0x7FFFFFFF;
2024-10-05 00:56:13 +02:00
}
2024-08-09 18:40:08 +02:00
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;
}