summaryrefslogtreecommitdiff
path: root/maths.c
diff options
context:
space:
mode:
Diffstat (limited to 'maths.c')
-rw-r--r--maths.c327
1 files changed, 229 insertions, 98 deletions
diff --git a/maths.c b/maths.c
index d0bccf3..5ec40d7 100644
--- a/maths.c
+++ b/maths.c
@@ -1,115 +1,246 @@
#include "maths.h"
+#include "plat.h"
-#define sin_table_count 256
-
-static const int sin_table[sin_table_count] = {
- 0, 25, 50, 75,
- 100, 125, 150, 175,
- 200, 224, 249, 273,
- 297, 321, 345, 369,
- 392, 415, 438, 460,
- 483, 505, 526, 548,
- 569, 590, 610, 630,
- 650, 669, 688, 706,
- 724, 742, 759, 775,
- 792, 807, 822, 837,
- 851, 865, 878, 891,
- 903, 915, 926, 936,
- 946, 955, 964, 972,
- 980, 987, 993, 999,
- 1004, 1009, 1013, 1016,
- 1019, 1021, 1023, 1024,
- 1024, 1024, 1023, 1021,
- 1019, 1016, 1013, 1009,
- 1004, 999, 993, 987,
- 980, 972, 964, 955,
- 946, 936, 926, 915,
- 903, 891, 878, 865,
- 851, 837, 822, 807,
- 792, 775, 759, 742,
- 724, 706, 688, 669,
- 650, 630, 610, 590,
- 569, 548, 526, 505,
- 483, 460, 438, 415,
- 392, 369, 345, 321,
- 297, 273, 249, 224,
- 200, 175, 150, 125,
- 100, 75, 50, 25,
- 0, -25, -50, -75,
- -100, -125, -150, -175,
- -200, -224, -249, -273,
- -297, -321, -345, -369,
- -392, -415, -438, -460,
- -483, -505, -526, -548,
- -569, -590, -610, -630,
- -650, -669, -688, -706,
- -724, -742, -759, -775,
- -792, -807, -822, -837,
- -851, -865, -878, -891,
- -903, -915, -926, -936,
- -946, -955, -964, -972,
- -980, -987, -993, -999,
- -1004, -1009, -1013, -1016,
- -1019, -1021, -1023, -1024,
- -1024, -1024, -1023, -1021,
- -1019, -1016, -1013, -1009,
- -1004, -999, -993, -987,
- -980, -972, -964, -955,
- -946, -936, -926, -915,
- -903, -891, -878, -865,
- -851, -837, -822, -807,
- -792, -775, -759, -742,
- -724, -706, -688, -669,
- -650, -630, -610, -590,
- -569, -548, -526, -505,
- -483, -460, -438, -415,
- -392, -369, -345, -321,
- -297, -273, -249, -224,
- -200, -175, -150, -125,
- -100, -75, -50, -25
+int sin_table[sin_table_count] = {
+ 0x000, 0x00c, 0x019, 0x025, 0x032, 0x03e, 0x04b, 0x057,
+ 0x063, 0x070, 0x07c, 0x088, 0x094, 0x0a0, 0x0ac, 0x0b8,
+ 0x0c3, 0x0cf, 0x0da, 0x0e6, 0x0f1, 0x0fc, 0x107, 0x111,
+ 0x11c, 0x126, 0x130, 0x13a, 0x144, 0x14e, 0x157, 0x161,
+ 0x16a, 0x172, 0x17b, 0x183, 0x18b, 0x193, 0x19b, 0x1a2,
+ 0x1a9, 0x1b0, 0x1b7, 0x1bd, 0x1c3, 0x1c9, 0x1ce, 0x1d4,
+ 0x1d9, 0x1dd, 0x1e2, 0x1e6, 0x1e9, 0x1ed, 0x1f0, 0x1f3,
+ 0x1f6, 0x1f8, 0x1fa, 0x1fc, 0x1fd, 0x1fe, 0x1ff, 0x1ff,
+ 0x200, 0x1ff, 0x1ff, 0x1fe, 0x1fd, 0x1fc, 0x1fa, 0x1f8,
+ 0x1f6, 0x1f3, 0x1f0, 0x1ed, 0x1e9, 0x1e6, 0x1e2, 0x1dd,
+ 0x1d9, 0x1d4, 0x1ce, 0x1c9, 0x1c3, 0x1bd, 0x1b7, 0x1b0,
+ 0x1a9, 0x1a2, 0x19b, 0x193, 0x18b, 0x183, 0x17b, 0x172,
+ 0x16a, 0x161, 0x157, 0x14e, 0x144, 0x13a, 0x130, 0x126,
+ 0x11c, 0x111, 0x107, 0x0fc, 0x0f1, 0x0e6, 0x0da, 0x0cf,
+ 0x0c3, 0x0b8, 0x0ac, 0x0a0, 0x094, 0x088, 0x07c, 0x070,
+ 0x063, 0x057, 0x04b, 0x03e, 0x032, 0x025, 0x019, 0x00c,
};
+int cos_table[sin_table_count];
-int fsqrt(int n) {
- int lo, hi, mid, i, mm;
- if (n <= 0) { return -1; }
- lo = mini(1, n);
- hi = maxi(1, n);
- while ((100 << fbits * lo * lo) >> fbits * 2)
- lo *= (10 << fbits) >> fbits;
- while ((5 * hi * hi) >> fbits * 2 > n)
- hi *= (1 << fbits) / 10;
- for (i = 0; i < 100; i++) {
- mid = ((lo + hi) * (1 << fbits)) / (2 << fbits);
- mm = mid * mid >> fbits;
- if (mm == n) return mid;
- if (mm > n) hi = mid;
- else lo = mid;
+int sqrt_table[sqrt_table_count] = {
+ 0x0000, 0x0200, 0x02d4, 0x0376, 0x0400, 0x0478, 0x04e6, 0x054a,
+ 0x05a8, 0x0600, 0x0653, 0x06a2, 0x06ed, 0x0736, 0x077b, 0x07be,
+ 0x0800, 0x083f, 0x087c, 0x08b7, 0x08f1, 0x092a, 0x0961, 0x0997,
+ 0x09cc, 0x0a00, 0x0a32, 0x0a64, 0x0a95, 0x0ac5, 0x0af4, 0x0b22,
+ 0x0b50, 0x0b7d, 0x0ba9, 0x0bd5, 0x0c00, 0x0c2a, 0x0c54, 0x0c7d,
+ 0x0ca6, 0x0cce, 0x0cf6, 0x0d1d, 0x0d44, 0x0d6a, 0x0d90, 0x0db6,
+ 0x0ddb, 0x0e00, 0x0e24, 0x0e48, 0x0e6c, 0x0e8f, 0x0eb2, 0x0ed5,
+ 0x0ef7, 0x0f19, 0x0f3b, 0x0f5c, 0x0f7d, 0x0f9e, 0x0fbf, 0x0fdf,
+ 0x1000, 0x101f, 0x103f, 0x105e, 0x107e, 0x109c, 0x10bb, 0x10da,
+ 0x10f8, 0x1116, 0x1134, 0x1152, 0x116f, 0x118c, 0x11a9, 0x11c6,
+ 0x11e3, 0x1200, 0x121c, 0x1238, 0x1254, 0x1270, 0x128c, 0x12a7,
+ 0x12c2, 0x12de, 0x12f9, 0x1314, 0x132e, 0x1349, 0x1364, 0x137e,
+ 0x1398, 0x13b2, 0x13cc, 0x13e6, 0x1400, 0x1419, 0x1432, 0x144c,
+ 0x1465, 0x147e, 0x1497, 0x14b0, 0x14c8, 0x14e1, 0x14f9, 0x1512,
+ 0x152a, 0x1542, 0x155a, 0x1572, 0x158a, 0x15a2, 0x15b9, 0x15d1,
+ 0x15e8, 0x1600, 0x1617, 0x162e, 0x1645, 0x165c, 0x1673, 0x1689,
+};
+
+#define mtx_stack_max 0x20
+
+int mtx_stack[mtx_stack_max][0x10];
+int mtx_stack_top;
+
+void init_maths(void) {
+ int i, hs = sin_table_count >> 1;
+ int m[0x10];
+ for (
+ i = hs;
+ i < sin_table_count;
+ i++
+ ) {
+ sin_table[i] = -sin_table[i - hs];
}
- return mid;
+ hs >>= 1;
+ for (i = 0; i < sin_table_count; i++) {
+ cos_table[i] = sin_table[(i + hs) & sin_table_mask];
+ }
+ mtx_stack_top = 1;
+ mtx_iden(m);
+ mtx_cpy(mtx_stack[0], m);
+}
+
+int* mtx_iden(int* m) {
+ register int o = f1;
+ m[0] = o;
+ m[1] = 0;
+ m[2] = 0;
+ m[3] = 0;
+ m[4] = 0;
+ m[5] = o;
+ m[6] = 0;
+ m[7] = 0;
+ m[8] = 0;
+ m[9] = 0;
+ m[10] = o;
+ m[11] = 0;
+ m[12] = 0;
+ m[13] = 0;
+ m[14] = 0;
+ m[15] = o;
+ return m;
+}
+
+int* mtx_cpy(int* d, const int* s) {
+ d[0]=s[0];d[1]=s[1];d[2]=s[2];d[3]=s[3];
+ d[4]=s[4];d[5]=s[5];d[6]=s[6];d[7]=s[7];
+ d[8]=s[8];d[9]=s[9];d[10]=s[10];d[11]=s[11];
+ d[12]=s[12];d[13]=s[13];d[14]=s[14];d[15]=s[15];
+ return d;
+}
+
+int* mtx_mul(int* d, const int* a, const int* b) {
+#define mul(a, b) \
+ ((a * b) >> fbits)
+#define dot(x1, y1, z1, w1, x2, y2, z2, w2) \
+ mul(x1, x2) + mul(y1, y2) + mul(z1, z2) + mul(w1, w2)
+ d[0] = dot(a[0], a[1], a[2], a[3], b[0],b[4],b[8], b[12]);
+ d[1] = dot(a[0], a[1], a[2], a[3], b[1],b[5],b[9], b[13]);
+ d[2] = dot(a[0], a[1], a[2], a[3], b[2],b[6],b[10],b[14]);
+ d[3] = dot(a[0], a[1], a[2], a[3], b[3],b[7],b[11],b[15]);
+ d[4] = dot(a[4], a[5], a[6], a[7], b[0],b[4],b[8], b[12]);
+ d[5] = dot(a[4], a[5], a[6], a[7], b[1],b[5],b[9], b[13]);
+ d[6] = dot(a[4], a[5], a[6], a[7], b[2],b[6],b[10],b[14]);
+ d[7] = dot(a[4], a[5], a[6], a[7], b[3],b[7],b[11],b[15]);
+ d[8] = dot(a[8], a[9], a[10],a[11], b[0],b[4],b[8], b[12]);
+ d[9] = dot(a[8], a[9], a[10],a[11], b[1],b[5],b[9], b[13]);
+ d[10] = dot(a[8], a[9], a[10],a[11], b[2],b[6],b[10],b[14]);
+ d[11] = dot(a[8], a[9], a[10],a[11], b[3],b[7],b[11],b[15]);
+ d[12] = dot(a[12],a[13],a[14],a[15], b[0],b[4],b[8], b[12]);
+ d[13] = dot(a[12],a[13],a[14],a[15], b[1],b[5],b[9], b[13]);
+ d[14] = dot(a[12],a[13],a[14],a[15], b[2],b[6],b[10],b[14]);
+ d[15] = dot(a[12],a[13],a[14],a[15], b[3],b[7],b[11],b[15]);
+#undef dot
+#undef mul
+ return d;
+}
+
+void mtx_push(const int* m) {
+ int* d, i;
+ assert(mtx_stack_top < mtx_stack_max);
+ i = mtx_stack_top++;
+ d = mtx_stack[i];
+ mtx_iden(d);
+ mtx_mul(d, mtx_stack[i - 1], m);
+}
+
+void mtx_push_trans(int* v) {
+ int m[0x10];
+ mtx_trans(m, v);
+ mtx_push(m);
+}
+
+void mtx_push_rot_x(int a) {
+ int m[0x10];
+ mtx_rot_x(m, a);
+ mtx_push(m);
+}
+
+void mtx_push_rot_y(int a) {
+ int m[0x10];
+ mtx_rot_y(m, a);
+ mtx_push(m);
+}
+
+void mtx_push_rot_z(int a) {
+ int m[0x10];
+ mtx_rot_z(m, a);
+ mtx_push(m);
+}
+
+int* mtx_pop(void) {
+ assert(mtx_stack_top > 0);
+ return mtx_stack[--mtx_stack_top];
+}
+
+int* mtx_popn(int n) {
+ int* t = mtx_pop(); n--;
+ while (n--)
+ mtx_pop();
+ return t;
+}
+
+int* mtx_peek(void) {
+ return mtx_stack[mtx_stack_top - 1];
+}
+
+int* mtx_trans(int* d, int* v) {
+ mtx_iden(d);
+ d[3] = v[0];
+ d[7] = v[1];
+ d[11] = v[2];
+ return d;
+}
+
+int* mtx_rot_x(int* d, int a) {
+ mtx_iden(d);
+ a &= sin_table_mask;
+ d[5] = cos_table[a];
+ d[6] = -sin_table[a];
+ d[9] = sin_table[a];
+ d[10] = cos_table[a];
+ return d;
}
-int absolute(int x) {
- return x >= 0 ? x : -x;
+int* mtx_rot_y(int* d, int a) {
+ mtx_iden(d);
+ a &= sin_table_mask;
+ d[0] = cos_table[a];
+ d[2] = sin_table[a];
+ d[8] = -sin_table[a];
+ d[10] = cos_table[a];
+ return d;
}
-int fsin(int t) {
- int index, sign;
- sign = t >= 0 ? 1 : -1;
- t = absolute(t);
- index = (t * (sin_table_count) / ((1 << fbits) * 2));
- index = index % sin_table_count;
- return (sign * sin_table[index]) / 2;
+int* mtx_rot_z(int* d, int a) {
+ mtx_iden(d);
+ a &= sin_table_mask;
+ d[0] = cos_table[a];
+ d[1] = -sin_table[a];
+ d[4] = sin_table[a];
+ d[5] = cos_table[a];
+ return d;
}
-int fcos(int t) {
- return fsin((1 << fbits) / 2 - t);
+int* mtx_apply(const int* m, int* v) {
+ int s[4];
+ vec_cpy(s, v, 4);
+#define mul(a, b) \
+ ((a * b) >> fbits)
+#define dot(x1, y1, z1, w1, x2, y2, z2, w2) \
+ mul(x1, x2) + mul(y1, y2) + mul(z1, z2) + mul(w1, w2)
+ v[0] = dot(s[0],s[1],s[2],s[3], m[0], m[1], m[2], m[3]);
+ v[1] = dot(s[0],s[1],s[2],s[3], m[4], m[5], m[6], m[7]);
+ v[2] = dot(s[0],s[1],s[2],s[3], m[8], m[9], m[10],m[11]);
+ v[3] = dot(s[0],s[1],s[2],s[3], m[12],m[13],m[14],m[15]);
+#undef mul
+#undef dot
+ return v;
}
-int ftan(int t) {
- return (fsin(t) << fbits) / fcos(t);
+int* vec_cpy(int* d, const int* s, int c) {
+ int i;
+ for (i = 0; i < c; i++) d[i] = s[i];
+ return d;
}
-int flerp(int a, int b, int t) {
- return a + ((t * (b - a)) >> fbits);
+void persp(int* v, int asp) {
+ v[0] = ((v[0] << fbits) / v[2]);
+ v[1] = ((v[1] << fbits) / v[2]) * asp >> fbits;
+ v[2] = f1;
}
+void ndc2clip(int* c, int* p) {
+ register int hw = c[2] >> 1;
+ register int hh = c[3] >> 1;
+ p[0] = ((hw << fbits) * p[0]) >> fbits;
+ p[1] = ((hh << fbits) * p[1]) >> fbits;
+ p[0] >>= fbits;
+ p[1] >>= fbits;
+ p[0] += hw;
+ p[1] += hh;
+}