]> git.bts.cx Git - sun.git/blob - runtime/src/sun/vm/fixed.h
do not evaluate variables until they are used
[sun.git] / runtime / src / sun / vm / fixed.h
1 #ifndef SUN_VM_FIXED_H
2 #define SUN_VM_FIXED_H
3
4 // Reference: https://en.wikipedia.org/wiki/Q_(number_format)
5 // http://www.superkits.net/whitepapers/Fixed%20Point%20Representation%20&%20Fractional%20Math.pdf
6
7 #include <assert.h>
8 #include <stdint.h>
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 #define FIXED_FRACTIONAL_BITS 8
15 #define FIXED_INTEGRAL_BITS 8
16
17 #define FIXED_ONE (1 << FIXED_FRACTIONAL_BITS)
18
19 typedef int32_t Fixed;
20 static_assert(sizeof(Fixed) == sizeof(int32_t), "Fixed incorrect size");
21
22 #define _fixed(v) ((Fixed)((v)))
23
24 #define FIXED(x) (_fixed((x) * FIXED_ONE))
25 #define FIXED_TO_INT(x) ((int)((int32_t)(x) / FIXED_ONE))
26
27 #define FIXED_FROM_FLOAT(x) (_fixed((x) * (float)FIXED_ONE))
28 #define FIXED_TO_FLOAT(x) ((float)((x) / (float)FIXED_ONE))
29
30 #define fixedLT(lhs, rhs) ((int32_t)(lhs) < (int32_t)(rhs))
31 #define fixedGT(lhs, rhs) ((int32_t)(lhs) > (int32_t)(rhs))
32
33 #define fixedNegate(v) (_fixed(-(int32_t)(v)))
34
35 #define fixedAdd(lhs, rhs) (_fixed((int32_t)(lhs) + (int32_t)(rhs)))
36 #define fixedSubtract(lhs, rhs) (_fixed((int32_t)(lhs) - (int32_t)(rhs)))
37
38 #define fixedMultiply(lhs, rhs) (_fixed((((int32_t)(lhs) * (int32_t)(rhs))) / FIXED_ONE))
39 #define fixedDivide(lhs, rhs) (_fixed(((int32_t)(lhs * FIXED_ONE) / (int32_t)(rhs))))
40 #define fixedMod(lhs, rhs) (_fixed((int32_t)(lhs) % (int32_t)(rhs)))
41
42 static inline Fixed fixedSgn(Fixed v) {
43 return v == 0 ? 0 : (fixedGT(v, 0) ? FIXED(1) : FIXED(-1));
44 }
45
46 static inline Fixed fixedMin(Fixed lhs, Fixed rhs) {
47 return fixedLT(lhs, rhs) ? lhs : rhs;
48 }
49
50 static inline Fixed fixedMax(Fixed lhs, Fixed rhs) {
51 return fixedGT(lhs, rhs) ? lhs : rhs;
52 }
53
54 static inline Fixed fixedMid(Fixed val1, Fixed val2, Fixed val3) {
55 return fixedMin(fixedMin(fixedMax(val1, val2), fixedMax(val2, val3)), fixedMax(val1, val3));
56 }
57
58 static inline Fixed fixedClamp(Fixed a, Fixed b, Fixed v) {
59 return fixedMin(fixedMax(v, a), b);
60 }
61
62 static inline Fixed fixedUnclampedLerp(Fixed a, Fixed b, Fixed t) {
63 Fixed v = fixedSubtract(fixedMultiply(a, fixedSubtract(FIXED(1), t)), fixedMultiply(b, t));
64 return v;
65 }
66
67 static inline Fixed fixedUnclampedUnlerp(Fixed a, Fixed b, Fixed v) {
68 Fixed t = fixedDivide(fixedSubtract(v, a), fixedSubtract(b, a));
69 return t;
70 }
71
72 static inline Fixed fixedLerp(Fixed a, Fixed b, Fixed t) {
73 Fixed clampedT = fixedClamp(FIXED(0), FIXED(1), t);
74 Fixed v = fixedUnclampedLerp(a, b, clampedT);
75 return v;
76 }
77
78 static inline Fixed fixedUnlerp(Fixed a, Fixed b, Fixed v) {
79 Fixed t = fixedUnclampedUnlerp(a, b, v);
80 Fixed clampedT = fixedClamp(FIXED(0), FIXED(1), t);
81 return clampedT;
82 }
83
84 extern Fixed fixedSqrt(Fixed value);
85 extern Fixed fixedSin(Fixed value);
86 extern Fixed fixedCos(Fixed value);
87 extern Fixed fixedAtan2(Fixed x, Fixed y);
88 extern Fixed fixedAbs(Fixed value);
89 extern Fixed fixedCeil(Fixed value);
90 extern Fixed fixedFloor(Fixed value);
91
92 #ifdef __cplusplus
93 }
94 #endif
95
96 #endif