rev |
line source |
nuclear@0
|
1 #include <stdint.h>
|
nuclear@1
|
2 #include <math.h>
|
nuclear@0
|
3 #include "dsregs.h"
|
nuclear@0
|
4 #include "ds3.h"
|
nuclear@0
|
5
|
nuclear@0
|
6 void ds3_enable(unsigned int x)
|
nuclear@0
|
7 {
|
nuclear@0
|
8 REG_DISP3DCNT |= x;
|
nuclear@0
|
9 }
|
nuclear@0
|
10
|
nuclear@0
|
11 void ds3_disable(unsigned int x)
|
nuclear@0
|
12 {
|
nuclear@0
|
13 REG_DISP3DCNT &= ~x;
|
nuclear@0
|
14 }
|
nuclear@0
|
15
|
nuclear@0
|
16 void ds3_clear_color(uint16_t color, int a)
|
nuclear@0
|
17 {
|
nuclear@0
|
18 REG_CLEAR_COLOR = color | ((a & 0x1f) << 16);
|
nuclear@0
|
19 }
|
nuclear@0
|
20
|
nuclear@0
|
21 void ds3_clear_depth(int z)
|
nuclear@0
|
22 {
|
nuclear@0
|
23 REG_CLEAR_DEPTH = z;
|
nuclear@0
|
24 }
|
nuclear@0
|
25
|
nuclear@0
|
26 void ds3_viewport(int x, int y, int w, int h)
|
nuclear@0
|
27 {
|
nuclear@0
|
28 int x1 = x + w - 1;
|
nuclear@0
|
29 int y1 = y + h - 1;
|
nuclear@0
|
30
|
nuclear@0
|
31 if(x1 > 255) x1 = 255;
|
nuclear@0
|
32 if(y1 > 191) y1 = 191;
|
nuclear@0
|
33
|
nuclear@0
|
34 REG_VIEWPORT = x | (y << 8) | (x1 << 16) | (y1 << 24);
|
nuclear@0
|
35 }
|
nuclear@0
|
36
|
nuclear@0
|
37 void ds3_matrix_mode(int mmode)
|
nuclear@0
|
38 {
|
nuclear@0
|
39 REG_MTX_MODE = mmode;
|
nuclear@0
|
40 }
|
nuclear@0
|
41
|
nuclear@0
|
42 void ds3_load_identity(void)
|
nuclear@0
|
43 {
|
nuclear@0
|
44 REG_MTX_IDENTITY = 0;
|
nuclear@0
|
45 }
|
nuclear@0
|
46
|
nuclear@0
|
47 void ds3_load_matrix(int32_t *m)
|
nuclear@0
|
48 {
|
nuclear@0
|
49 int i;
|
nuclear@0
|
50 for(i=0; i<16; i++) {
|
nuclear@0
|
51 int16_t val = (int16_t)(*m++ >> 4);
|
nuclear@0
|
52 REG_MTX_LOAD_4X4 = val;
|
nuclear@0
|
53 }
|
nuclear@0
|
54 }
|
nuclear@0
|
55
|
nuclear@1
|
56 void ds3_load_matrix4x3(int32_t *m)
|
nuclear@1
|
57 {
|
nuclear@1
|
58 int i;
|
nuclear@1
|
59 for(i=0; i<12; i++) {
|
nuclear@1
|
60 int16_t val = (int16_t)(*m++ >> 4);
|
nuclear@1
|
61 REG_MTX_LOAD_4X3 = val;
|
nuclear@1
|
62 }
|
nuclear@1
|
63 }
|
nuclear@1
|
64
|
nuclear@1
|
65 void ds3_mult_matrix(int32_t *m)
|
nuclear@1
|
66 {
|
nuclear@1
|
67 int i;
|
nuclear@1
|
68 for(i=0; i<16; i++) {
|
nuclear@1
|
69 int16_t val = (int16_t)(*m++ >> 4);
|
nuclear@1
|
70 REG_MTX_MULT_4X4 = val;
|
nuclear@1
|
71 }
|
nuclear@1
|
72 }
|
nuclear@1
|
73
|
nuclear@1
|
74 void ds3_mult_matrix4x3(int32_t *m)
|
nuclear@1
|
75 {
|
nuclear@1
|
76 int i;
|
nuclear@1
|
77 for(i=0; i<12; i++) {
|
nuclear@1
|
78 int16_t val = (int16_t)(*m++ >> 4);
|
nuclear@1
|
79 REG_MTX_MULT_4X3 = val;
|
nuclear@1
|
80 }
|
nuclear@1
|
81 }
|
nuclear@1
|
82
|
nuclear@1
|
83 void ds3_mult_matrix3x3(int32_t *m)
|
nuclear@1
|
84 {
|
nuclear@1
|
85 int i;
|
nuclear@1
|
86 for(i=0; i<9; i++) {
|
nuclear@1
|
87 int16_t val = (int16_t)(*m++ >> 4);
|
nuclear@1
|
88 REG_MTX_MULT_3X3 = val;
|
nuclear@1
|
89 }
|
nuclear@1
|
90 }
|
nuclear@1
|
91
|
nuclear@0
|
92 void ds3_push_matrix(void)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 REG_MTX_PUSH = 0;
|
nuclear@0
|
95 }
|
nuclear@0
|
96
|
nuclear@0
|
97 void ds3_pop_matrix(void)
|
nuclear@0
|
98 {
|
nuclear@0
|
99 REG_MTX_POP = 1;
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 void ds3_translate(int32_t x, int32_t y, int32_t z)
|
nuclear@0
|
103 {
|
nuclear@0
|
104 REG_MTX_TRANS = (int16_t)(x >> 4);
|
nuclear@0
|
105 REG_MTX_TRANS = (int16_t)(y >> 4);
|
nuclear@0
|
106 REG_MTX_TRANS = (int16_t)(z >> 4);
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 void ds3_scale(int32_t x, int32_t y, int32_t z)
|
nuclear@0
|
110 {
|
nuclear@0
|
111 REG_MTX_SCALE = (int16_t)(x >> 4);
|
nuclear@0
|
112 REG_MTX_SCALE = (int16_t)(y >> 4);
|
nuclear@0
|
113 REG_MTX_SCALE = (int16_t)(z >> 4);
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 void ds3_swap_buffers(void)
|
nuclear@0
|
117 {
|
nuclear@0
|
118 REG_SWAP_BUFFERS = 0;
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 void ds3_begin(int prim)
|
nuclear@0
|
122 {
|
nuclear@0
|
123 REG_BEGIN_VTXS = prim;
|
nuclear@0
|
124 }
|
nuclear@0
|
125
|
nuclear@0
|
126 void ds3_end(void)
|
nuclear@0
|
127 {
|
nuclear@0
|
128 REG_END_VTXS = 0;
|
nuclear@0
|
129 }
|
nuclear@0
|
130
|
nuclear@0
|
131 void ds3_vertex3(int32_t x, int32_t y, int32_t z)
|
nuclear@0
|
132 {
|
nuclear@0
|
133 REG_VTX_16 = ((x >> 4) & 0xffff) | ((y << 12) & 0xffff0000);
|
nuclear@0
|
134 REG_VTX_16 = (z >> 4) & 0xffff;
|
nuclear@0
|
135 }
|
nuclear@0
|
136
|
nuclear@1
|
137 void ds3_vertex3f(float x, float y, float z)
|
nuclear@1
|
138 {
|
nuclear@1
|
139 ds3_vertex3((int32_t)(x * 65536.0f), (int32_t)(y * 65536.0f), (int32_t)(z * 65536.0f));
|
nuclear@1
|
140 }
|
nuclear@1
|
141
|
nuclear@1
|
142 void ds3_vertex2(int32_t x, int32_t y)
|
nuclear@1
|
143 {
|
nuclear@1
|
144 REG_VTX_XY = ((x >> 4) & 0xffff) | ((y << 12) & 0xffff0000);
|
nuclear@1
|
145 }
|
nuclear@1
|
146
|
nuclear@1
|
147 void ds3_vertex2f(float x, float y)
|
nuclear@1
|
148 {
|
nuclear@1
|
149 ds3_vertex2((int32_t)(x * 65536.0f), (int32_t)(y * 65536.0f));
|
nuclear@1
|
150 }
|
nuclear@1
|
151
|
nuclear@0
|
152 void ds3_color(uint16_t color)
|
nuclear@0
|
153 {
|
nuclear@0
|
154 REG_COLOR = color;
|
nuclear@0
|
155 }
|
nuclear@0
|
156
|
nuclear@0
|
157 void ds3_color3b(unsigned char r, unsigned char g, unsigned char b)
|
nuclear@0
|
158 {
|
nuclear@0
|
159 REG_COLOR = RGB15(r >> 3, g >> 3, b >> 3);
|
nuclear@0
|
160 }
|
nuclear@1
|
161
|
nuclear@1
|
162 void ds3_color3f(float r, float g, float b)
|
nuclear@1
|
163 {
|
nuclear@1
|
164 uint16_t ir = r * 31.0f;
|
nuclear@1
|
165 uint16_t ig = g * 31.0f;
|
nuclear@1
|
166 uint16_t ib = b * 31.0f;
|
nuclear@1
|
167 REG_COLOR = RGB15(ir, ig, ib);
|
nuclear@1
|
168 }
|
nuclear@1
|
169
|
nuclear@1
|
170 void ds3_normal(int32_t x, int32_t y, int32_t z)
|
nuclear@1
|
171 {
|
nuclear@1
|
172 REG_NORMAL = ((x >> 7) & 0x3ff) | ((y << 17) & 0xffc00) | ((z << 27) & 0x3ff00000);
|
nuclear@1
|
173 }
|
nuclear@1
|
174
|
nuclear@1
|
175 void ds3_normal3f(float x, float y, float z)
|
nuclear@1
|
176 {
|
nuclear@1
|
177 ds3_normal((int32_t)(x * 65536.0f), (int32_t)(y * 65536.0f), (int32_t)(z * 65536.0f));
|
nuclear@1
|
178 }
|
nuclear@1
|
179
|
nuclear@1
|
180 void ds3_texcoord2(int32_t s, int32_t t)
|
nuclear@1
|
181 {
|
nuclear@1
|
182 REG_TEXCOORD = (((s) >> 12) & 0xffff) | (((t) << 4) & 0xffff0000);
|
nuclear@1
|
183 }
|
nuclear@1
|
184
|
nuclear@1
|
185 void ds3_texcoord2f(float s, float t)
|
nuclear@1
|
186 {
|
nuclear@1
|
187 ds3_texcoord2((int32_t)(s * 65536.0f), (int32_t)(t * 65536.0f));
|
nuclear@1
|
188 }
|
nuclear@1
|
189
|
nuclear@1
|
190 void ds3_ortho(int32_t left, int32_t right, int32_t top, int32_t bottom, int32_t znear, int32_t zfar)
|
nuclear@1
|
191 {
|
nuclear@1
|
192 int32_t m[16] = {0};
|
nuclear@1
|
193 int32_t dx = right - left;
|
nuclear@1
|
194 int32_t dy = top - bottom;
|
nuclear@1
|
195 int32_t dz = zfar - znear;
|
nuclear@1
|
196
|
nuclear@2
|
197 m[0] = x16div(0x20000, dx);
|
nuclear@2
|
198 m[5] = x16div(0x20000, dy);
|
nuclear@2
|
199 m[10] = x16div(-0x20000, dz);
|
nuclear@2
|
200 m[12] = x16div(-(right + left), dx);
|
nuclear@2
|
201 m[13] = x16div(-(top + bottom), dy);
|
nuclear@2
|
202 m[14] = x16div(-(zfar + znear), dz);
|
nuclear@2
|
203 m[15] = 65536;
|
nuclear@1
|
204
|
nuclear@1
|
205 ds3_mult_matrix(m);
|
nuclear@1
|
206 }
|
nuclear@1
|
207
|
nuclear@1
|
208 void ds3_orthof(float left, float right, float top, float bottom, float znear, float zfar)
|
nuclear@1
|
209 {
|
nuclear@1
|
210 int32_t m[16] = {0};
|
nuclear@1
|
211 float dx = right - left;
|
nuclear@1
|
212 float dy = top - bottom;
|
nuclear@1
|
213 float dz = zfar - znear;
|
nuclear@1
|
214
|
nuclear@1
|
215 m[0] = (int32_t)(2.0f / dx * 65536.0f);
|
nuclear@1
|
216 m[5] = (int32_t)(2.0f / dy * 65536.0f);
|
nuclear@1
|
217 m[10] = (int32_t)(-2.0f / dz * 65536.0f);
|
nuclear@2
|
218 m[12] = (int32_t)(-(right + left) / dx * 65536.0f);
|
nuclear@2
|
219 m[13] = (int32_t)(-(top + bottom) / dy * 65536.0f);
|
nuclear@2
|
220 m[14] = (int32_t)(-(zfar + znear) / dz * 65536.0f);
|
nuclear@2
|
221 m[15] = 65536;
|
nuclear@1
|
222
|
nuclear@1
|
223 ds3_mult_matrix(m);
|
nuclear@1
|
224 }
|
nuclear@1
|
225
|
nuclear@1
|
226 void ds3_frustum(int32_t left, int32_t right, int32_t top, int32_t bottom, int32_t znear, int32_t zfar)
|
nuclear@1
|
227 {
|
nuclear@1
|
228 int32_t m[16] = {0};
|
nuclear@1
|
229
|
nuclear@1
|
230 int32_t dx = right - left;
|
nuclear@1
|
231 int32_t dy = top - bottom;
|
nuclear@1
|
232 int32_t dz = zfar - znear;
|
nuclear@1
|
233
|
nuclear@2
|
234 int32_t a = x16div(right + left, dx);
|
nuclear@2
|
235 int32_t b = x16div(top + bottom, dy);
|
nuclear@2
|
236 int32_t c = x16div(-(zfar + znear), dz);
|
nuclear@2
|
237 int32_t d = x16div(-((zfar >> 8) * znear) << 1, dz);
|
nuclear@1
|
238
|
nuclear@2
|
239 m[0] = x16div(znear << 1, dx);
|
nuclear@2
|
240 m[5] = x16div(znear << 1, dy);
|
nuclear@1
|
241 m[8] = a;
|
nuclear@1
|
242 m[9] = b;
|
nuclear@1
|
243 m[10] = c;
|
nuclear@1
|
244 m[11] = -65536;
|
nuclear@1
|
245 m[14] = d;
|
nuclear@1
|
246
|
nuclear@1
|
247 ds3_mult_matrix(m);
|
nuclear@1
|
248 }
|
nuclear@1
|
249
|
nuclear@2
|
250 void g3d_frustumf(float left, float right, float bottom, float top, float nr, float fr)
|
nuclear@1
|
251 {
|
nuclear@1
|
252 int32_t m[16] = {0};
|
nuclear@1
|
253
|
nuclear@1
|
254 float dx = right - left;
|
nuclear@1
|
255 float dy = top - bottom;
|
nuclear@1
|
256 float dz = fr - nr;
|
nuclear@1
|
257
|
nuclear@1
|
258 float a = (right + left) / dx;
|
nuclear@1
|
259 float b = (top + bottom) / dy;
|
nuclear@1
|
260 float c = -(fr + nr) / dz;
|
nuclear@1
|
261 float d = -2.0 * fr * nr / dz;
|
nuclear@1
|
262
|
nuclear@1
|
263 m[0] = (int32_t)(2.0 * nr / dx * 65536.0f);
|
nuclear@1
|
264 m[5] = (int32_t)(2.0 * nr / dy * 65536.0f);
|
nuclear@1
|
265 m[8] = (int32_t)(a * 65536.0f);
|
nuclear@1
|
266 m[9] = (int32_t)(b * 65536.0f);
|
nuclear@1
|
267 m[10] = (int32_t)(c * 65536.0f);
|
nuclear@1
|
268 m[11] = -65536;
|
nuclear@1
|
269 m[14] = (int32_t)(d * 65536.0f);
|
nuclear@1
|
270
|
nuclear@1
|
271 ds3_mult_matrix(m);
|
nuclear@1
|
272 }
|
nuclear@1
|
273
|
nuclear@2
|
274 void ds3_perspectivef(float vfov_deg, float aspect, float znear, float zfar)
|
nuclear@1
|
275 {
|
nuclear@1
|
276 int32_t m[16] = {0};
|
nuclear@1
|
277
|
nuclear@1
|
278 float vfov = M_PI * vfov_deg / 180.0f;
|
nuclear@1
|
279 float s = 1.0f / tan(vfov * 0.5f);
|
nuclear@1
|
280 float range = znear - zfar;
|
nuclear@1
|
281
|
nuclear@1
|
282 m[0] = (int32_t)(s / aspect * 65536.0f);
|
nuclear@1
|
283 m[5] = (int32_t)(s * 65536.0f);
|
nuclear@1
|
284 m[10] = (int32_t)((znear + zfar) / range * 65536.0f);
|
nuclear@1
|
285 m[11] = -65536;
|
nuclear@1
|
286 m[14] = (int32_t)(2.0f * znear * zfar / range * 65536.0f);
|
nuclear@1
|
287
|
nuclear@1
|
288 ds3_mult_matrix(m);
|
nuclear@1
|
289 }
|
nuclear@2
|
290
|
nuclear@2
|
291 int32_t x16div(int32_t a, int32_t b)
|
nuclear@2
|
292 {
|
nuclear@2
|
293 REG_DIVCNT = DIVCNT_64_32;
|
nuclear@2
|
294 REG_DIV_NUMER = (int64_t)a << 16;
|
nuclear@2
|
295 REG_DIV_DENOM = (int64_t)b;
|
nuclear@2
|
296
|
nuclear@2
|
297 while(REG_DIVCNT & DIVCNT_BUSY);
|
nuclear@2
|
298 return (int32_t)REG_DIV_RESULT;
|
nuclear@2
|
299 }
|