98e75f2d |
1 | /* |
2 | * Glide64 - Glide video plugin for Nintendo 64 emulators. |
3 | * Copyright (c) 2002 Dave2001 |
4 | * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | //**************************************************************** |
22 | // |
23 | // Glide64 - Glide Plugin for Nintendo 64 emulators |
24 | // Project started on December 29th, 2001 |
25 | // |
26 | // Authors: |
27 | // Dave2001, original author, founded the project in 2001, left it in 2002 |
28 | // Gugaman, joined the project in 2002, left it in 2002 |
29 | // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 |
30 | // Hiroshi 'KoolSmoky' Morii, joined the project in 2007 |
31 | // |
32 | //**************************************************************** |
33 | // |
34 | // To modify Glide64: |
35 | // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. |
36 | // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. |
37 | // |
38 | //**************************************************************** |
39 | // |
40 | // January 2004 Created by Gonetz (Gonetz@ngs.ru) |
41 | // |
42 | //**************************************************************** |
43 | |
44 | wxUint32 uc8_normale_addr = 0; |
45 | float uc8_coord_mod[16]; |
46 | |
47 | static void uc8_vertex () |
48 | { |
49 | Check_FrameSkip; |
50 | |
51 | if (rdp.update & UPDATE_MULT_MAT) |
52 | { |
53 | rdp.update ^= UPDATE_MULT_MAT; |
54 | MulMatrices(rdp.model, rdp.proj, rdp.combined); |
55 | } |
56 | |
57 | wxUint32 addr = segoffset(rdp.cmd1); |
58 | int v0, i, n; |
59 | float x, y, z; |
60 | |
61 | rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF; |
62 | rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; |
63 | |
64 | FRDP ("uc8:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); |
65 | |
66 | if (v0 < 0) |
67 | { |
68 | RDP_E ("** ERROR: uc2:vertex v0 < 0\n"); |
69 | LRDP("** ERROR: uc2:vertex v0 < 0\n"); |
70 | return; |
71 | } |
72 | //* |
73 | // This is special, not handled in update() |
74 | if (rdp.update & UPDATE_LIGHTS) |
75 | { |
76 | rdp.update ^= UPDATE_LIGHTS; |
77 | |
78 | // Calculate light vectors |
79 | for (wxUint32 l=0; l<rdp.num_lights; l++) |
80 | { |
81 | InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model); |
82 | NormalizeVector (rdp.light_vector[l]); |
83 | #ifdef EXTREME_LOGGING |
84 | FRDP("light_vector[%d] x: %f, y: %f, z: %f\n", l, rdp.light_vector[l][0], rdp.light_vector[l][1], rdp.light_vector[l][2]); |
85 | #endif |
86 | } |
87 | } |
88 | //*/ |
89 | #ifdef __ARM_NEON__ |
90 | float32x4_t comb0, comb1, comb2, comb3; |
91 | float32x4_t v_xyzw; |
92 | comb0 = vld1q_f32(rdp.combined[0]); |
93 | comb1 = vld1q_f32(rdp.combined[1]); |
94 | comb2 = vld1q_f32(rdp.combined[2]); |
95 | comb3 = vld1q_f32(rdp.combined[3]); |
96 | |
97 | float32x4_t uc8_8_11, uc8_12_15; |
98 | uc8_8_11 = vld1q_f32(uc8_coord_mod+8); |
99 | uc8_12_15 = vld1q_f32(uc8_coord_mod+12); |
100 | float32x4_t unite={1.0f, 1.0f, 1.0f, 1.0f}; |
101 | |
102 | float32x4_t rdplight[12], rdpcolor[12]; |
103 | for (i=0; i<rdp.num_lights; i++) { |
104 | rdplight[i] = vld1q_f32(&rdp.light[i].x); |
105 | rdpcolor[i] = vld1q_f32(&rdp.light[i].r); |
106 | } |
107 | |
108 | #endif |
109 | for (i=0; i < (n<<4); i+=16) |
110 | { |
111 | VERTEX *v = &rdp.vtx[v0 + (i>>4)]; |
112 | x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; |
113 | y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; |
114 | z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; |
115 | v->flags = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; |
116 | v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; |
117 | v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; |
118 | v->uv_scaled = 0; |
119 | v->a = ((wxUint8*)gfx.RDRAM)[(addr+i + 15)^3]; |
120 | |
121 | #ifdef EXTREME_LOGGING |
122 | FRDP ("before v%d - x: %f, y: %f, z: %f\n", i>>4, x, y, z); |
123 | #endif |
124 | #ifdef __ARM_NEON__ |
125 | v_xyzw = x*comb0+y*comb1+z*comb2+comb3; |
126 | //vst1q_f32((float*)v, v_xyzw); |
127 | #else |
128 | v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; |
129 | v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; |
130 | v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; |
131 | v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; |
132 | #endif |
133 | |
134 | #ifdef EXTREME_LOGGING |
135 | FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, flags: %d\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov, v->flags); |
136 | #endif |
137 | v->uv_calculated = 0xFFFFFFFF; |
138 | v->screen_translated = 0; |
139 | v->shade_mod = 0; |
140 | #ifdef __ARM_NEON__ |
141 | v->x=v_xyzw[0]; |
142 | v->y=v_xyzw[1]; |
143 | v->z=v_xyzw[2]; |
144 | v->w=v_xyzw[3]; |
145 | #endif |
146 | |
147 | ///* |
148 | v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3]; |
149 | v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3]; |
150 | v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3]; |
151 | |
152 | if (fabs(v->w) < 0.001) v->w = 0.001f; |
153 | v->oow = 1.0f / v->w; |
154 | #ifdef __ARM_NEON__ |
155 | v_xyzw *= v->oow; |
156 | v->x_w=v_xyzw[0]; |
157 | v->y_w=v_xyzw[1]; |
158 | v->z_w=v_xyzw[2]; |
159 | #else |
160 | v->x_w = v->x * v->oow; |
161 | v->y_w = v->y * v->oow; |
162 | v->z_w = v->z * v->oow; |
163 | #endif |
164 | |
165 | v->scr_off = 0; |
166 | if (v->x < -v->w) v->scr_off |= 1; |
167 | if (v->x > v->w) v->scr_off |= 2; |
168 | if (v->y < -v->w) v->scr_off |= 4; |
169 | if (v->y > v->w) v->scr_off |= 8; |
170 | if (v->w < 0.1f) v->scr_off |= 16; |
171 | #ifdef EXTREME_LOGGING |
172 | FRDP ("r: %02lx, g: %02lx, b: %02lx, a: %02lx\n", v->r, v->g, v->b, v->a); |
173 | #endif |
174 | |
175 | if ((rdp.geom_mode & 0x00020000)) |
176 | { |
177 | wxUint32 shift = v0 << 1; |
178 | v->vec[0] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 0)^3]; |
179 | v->vec[1] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 1)^3]; |
180 | v->vec[2] = (char)(v->flags&0xff); |
181 | |
182 | if (rdp.geom_mode & 0x80000) |
183 | { |
184 | calc_linear (v); |
185 | #ifdef EXTREME_LOGGING |
186 | FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); |
187 | #endif |
188 | } |
189 | else if (rdp.geom_mode & 0x40000) |
190 | { |
191 | calc_sphere (v); |
192 | #ifdef EXTREME_LOGGING |
193 | FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); |
194 | #endif |
195 | } |
196 | // FRDP("calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx, nx: %.3f, ny: %.3f, nz: %.3f\n", v->r, v->g, v->b, v->vec[0], v->vec[1], v->vec[2]); |
197 | FRDP("v[%d] calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", i>>4, v->r, v->g, v->b); |
198 | #ifdef __ARM_NEON__ |
199 | float32x4_t color = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b, 1.0f}; |
200 | #else |
201 | float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; |
202 | #endif |
203 | FRDP("ambient light. r: %f, g: %f, b: %f\n", color[0], color[1], color[2]); |
204 | float light_intensity = 0.0f; |
205 | wxUint32 l; |
206 | if (rdp.geom_mode & 0x00400000) |
207 | { |
208 | NormalizeVector (v->vec); |
209 | for (l = 0; l < rdp.num_lights-1; l++) |
210 | { |
211 | if (!rdp.light[l].nonblack) |
212 | continue; |
213 | light_intensity = DotProduct (rdp.light_vector[l], v->vec); |
214 | FRDP("light %d, intensity : %f\n", l, light_intensity); |
215 | if (light_intensity < 0.0f) |
216 | continue; |
217 | //* |
218 | if (rdp.light[l].ca > 0.0f) |
219 | { |
220 | #ifdef __ARM_NEON__ |
221 | float32x4_t vxyzw = (v_xyzw + uc8_8_11)*uc8_12_15 - rdplight[l]; |
222 | vxyzw = vxyzw*vxyzw; |
223 | float invlen = 65536.0f/(vxyzw[0]+vxyzw[1]+vxyzw[2]+vxyzw[3]); |
224 | float p_i = rdp.light[l].ca * invlen; |
225 | #else |
226 | float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; |
227 | float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; |
228 | float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; |
229 | float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; |
230 | float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; |
231 | float p_i = rdp.light[l].ca / len; |
232 | #endif |
233 | if (p_i > 1.0f) p_i = 1.0f; |
234 | light_intensity *= p_i; |
235 | #if __ARM_NEON__ |
236 | FRDP("light %d, 1/len: %f, p_intensity : %f\n", l, invlen, p_i); |
237 | #else |
238 | FRDP("light %d, len: %f, p_intensity : %f\n", l, len, p_i); |
239 | #endif |
240 | } |
241 | //*/ |
242 | #ifdef __ARM_NEON__ |
243 | color += rdpcolor[l] * light_intensity; |
244 | #else |
245 | color[0] += rdp.light[l].r * light_intensity; |
246 | color[1] += rdp.light[l].g * light_intensity; |
247 | color[2] += rdp.light[l].b * light_intensity; |
248 | #endif |
249 | FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); |
250 | } |
251 | light_intensity = DotProduct (rdp.light_vector[l], v->vec); |
252 | FRDP("light %d, intensity : %f\n", l, light_intensity); |
253 | if (light_intensity > 0.0f) |
254 | { |
255 | #ifdef __ARM_NEON__ |
256 | color += rdpcolor[l] * light_intensity; |
257 | #else |
258 | color[0] += rdp.light[l].r * light_intensity; |
259 | color[1] += rdp.light[l].g * light_intensity; |
260 | color[2] += rdp.light[l].b * light_intensity; |
261 | #endif |
262 | } |
263 | FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); |
264 | } |
265 | else |
266 | { |
267 | for (l = 0; l < rdp.num_lights; l++) |
268 | { |
269 | if (rdp.light[l].nonblack && rdp.light[l].nonzero) |
270 | { |
271 | #ifdef __ARM_NEON__ |
272 | float32x4_t vxyzw = (v_xyzw + uc8_8_11)*uc8_12_15 - rdplight[l]; |
273 | vxyzw = vxyzw*vxyzw; |
274 | float invlen = 65536.0f/(vxyzw[0]+vxyzw[1]+vxyzw[2]+vxyzw[3]); |
275 | light_intensity = rdp.light[l].ca * invlen; |
276 | #else |
277 | float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; |
278 | float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; |
279 | float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; |
280 | float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; |
281 | float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; |
282 | light_intensity = rdp.light[l].ca / len; |
283 | #endif |
284 | if (light_intensity > 1.0f) light_intensity = 1.0f; |
285 | FRDP("light %d, p_intensity : %f\n", l, light_intensity); |
286 | #ifdef __ARM_NEON__ |
287 | color += rdpcolor[l] * light_intensity; |
288 | #else |
289 | color[0] += rdp.light[l].r * light_intensity; |
290 | color[1] += rdp.light[l].g * light_intensity; |
291 | color[2] += rdp.light[l].b * light_intensity; |
292 | #endif |
293 | //FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); |
294 | } |
295 | } |
296 | } |
297 | #ifdef __ARM_NEON__ |
298 | color = vminq_f32(color, unite); |
299 | #else |
300 | if (color[0] > 1.0f) color[0] = 1.0f; |
301 | if (color[1] > 1.0f) color[1] = 1.0f; |
302 | if (color[2] > 1.0f) color[2] = 1.0f; |
303 | #endif |
304 | v->r = (wxUint8)(((float)v->r)*color[0]); |
305 | v->g = (wxUint8)(((float)v->g)*color[1]); |
306 | v->b = (wxUint8)(((float)v->b)*color[2]); |
307 | #ifdef EXTREME_LOGGING |
308 | FRDP("color after light: r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", v->r, v->g, v->b); |
309 | #endif |
310 | } |
311 | } |
312 | } |
313 | |
314 | static void uc8_moveword () |
315 | { |
316 | wxUint8 index = (wxUint8)((rdp.cmd0 >> 16) & 0xFF); |
317 | wxUint16 offset = (wxUint16)(rdp.cmd0 & 0xFFFF); |
318 | wxUint32 data = rdp.cmd1; |
319 | |
320 | FRDP ("uc8:moveword "); |
321 | |
322 | switch (index) |
323 | { |
324 | // NOTE: right now it's assuming that it sets the integer part first. This could |
325 | // be easily fixed, but only if i had something to test with. |
326 | |
327 | case 0x02: |
328 | rdp.num_lights = (data / 48); |
329 | rdp.update |= UPDATE_LIGHTS; |
330 | FRDP ("numlights: %d\n", rdp.num_lights); |
331 | break; |
332 | |
333 | case 0x04: |
334 | if (offset == 0x04) |
335 | { |
336 | rdp.clip_ratio = sqrt((float)rdp.cmd1); |
337 | rdp.update |= UPDATE_VIEWPORT; |
338 | } |
339 | FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); |
340 | break; |
341 | |
342 | case 0x06: // moveword SEGMENT |
343 | { |
344 | FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2); |
345 | rdp.segment[(offset >> 2) & 0xF] = data; |
346 | } |
347 | break; |
348 | |
349 | case 0x08: |
350 | { |
351 | rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); |
352 | rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); |
353 | FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); |
354 | } |
355 | break; |
356 | |
357 | case 0x0c: |
358 | RDP_E ("uc8:moveword forcemtx - IGNORED\n"); |
359 | LRDP("forcemtx - IGNORED\n"); |
360 | break; |
361 | |
362 | case 0x0e: |
363 | LRDP("perspnorm - IGNORED\n"); |
364 | break; |
365 | |
366 | case 0x10: // moveword coord mod |
367 | { |
368 | wxUint8 n = offset >> 2; |
369 | |
370 | FRDP ("coord mod:%d, %08lx\n", n, data); |
371 | if (rdp.cmd0&8) |
372 | return; |
373 | wxUint32 idx = (rdp.cmd0>>1)&3; |
374 | wxUint32 pos = rdp.cmd0&0x30; |
375 | if (pos == 0) |
376 | { |
377 | uc8_coord_mod[0+idx] = (short)(rdp.cmd1>>16); |
378 | uc8_coord_mod[1+idx] = (short)(rdp.cmd1&0xffff); |
379 | } |
380 | else if (pos == 0x10) |
381 | { |
382 | uc8_coord_mod[4+idx] = (rdp.cmd1>>16)/65536.0f; |
383 | uc8_coord_mod[5+idx] = (rdp.cmd1&0xffff)/65536.0f; |
384 | uc8_coord_mod[12+idx] = uc8_coord_mod[0+idx] + uc8_coord_mod[4+idx]; |
385 | uc8_coord_mod[13+idx] = uc8_coord_mod[1+idx] + uc8_coord_mod[5+idx]; |
386 | |
387 | } |
388 | else if (pos == 0x20) |
389 | { |
390 | uc8_coord_mod[8+idx] = (short)(rdp.cmd1>>16); |
391 | uc8_coord_mod[9+idx] = (short)(rdp.cmd1&0xffff); |
392 | #ifdef EXTREME_LOGGING |
393 | if (idx) |
394 | { |
395 | for (int k = 8; k < 16; k++) |
396 | { |
397 | FRDP("coord_mod[%d]=%f\n", k, uc8_coord_mod[k]); |
398 | } |
399 | } |
400 | #endif |
401 | } |
402 | |
403 | } |
404 | break; |
405 | |
406 | default: |
407 | FRDP_E("uc8:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); |
408 | FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); |
409 | } |
410 | } |
411 | |
412 | static void uc8_movemem () |
413 | { |
414 | int idx = rdp.cmd0 & 0xFF; |
415 | wxUint32 addr = segoffset(rdp.cmd1); |
416 | int ofs = (rdp.cmd0 >> 5) & 0x3FFF; |
417 | |
418 | FRDP ("uc8:movemem ofs:%d ", ofs); |
419 | |
420 | switch (idx) |
421 | { |
422 | case 8: // VIEWPORT |
423 | { |
424 | wxUint32 a = addr >> 1; |
425 | short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; |
426 | short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; |
427 | short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; |
428 | short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; |
429 | short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; |
430 | short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; |
431 | rdp.view_scale[0] = scale_x * rdp.scale_x; |
432 | rdp.view_scale[1] = -scale_y * rdp.scale_y; |
433 | rdp.view_scale[2] = 32.0f * scale_z; |
434 | rdp.view_trans[0] = trans_x * rdp.scale_x; |
435 | rdp.view_trans[1] = trans_y * rdp.scale_y; |
436 | rdp.view_trans[2] = 32.0f * trans_z; |
437 | |
438 | rdp.update |= UPDATE_VIEWPORT; |
439 | |
440 | FRDP ("viewport scale(%d, %d), trans(%d, %d), from:%08lx\n", scale_x, scale_y, |
441 | trans_x, trans_y, a); |
442 | } |
443 | break; |
444 | |
445 | case 10: // LIGHT |
446 | { |
447 | int n = (ofs / 48); |
448 | if (n < 2) |
449 | { |
450 | char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3]; |
451 | rdp.lookat[n][0] = (float)(dir_x) / 127.0f; |
452 | char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3]; |
453 | rdp.lookat[n][1] = (float)(dir_y) / 127.0f; |
454 | char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3]; |
455 | rdp.lookat[n][2] = (float)(dir_z) / 127.0f; |
456 | rdp.use_lookat = TRUE; |
457 | if (n == 1) |
458 | { |
459 | if (!dir_x && !dir_y) |
460 | rdp.use_lookat = FALSE; |
461 | } |
462 | FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); |
463 | return; |
464 | } |
465 | n -= 2; |
466 | wxUint8 col = gfx.RDRAM[(addr+0)^3]; |
467 | rdp.light[n].r = (float)col / 255.0f; |
468 | rdp.light[n].nonblack = col; |
469 | col = gfx.RDRAM[(addr+1)^3]; |
470 | rdp.light[n].g = (float)col / 255.0f; |
471 | rdp.light[n].nonblack += col; |
472 | col = gfx.RDRAM[(addr+2)^3]; |
473 | rdp.light[n].b = (float)col / 255.0f; |
474 | rdp.light[n].nonblack += col; |
475 | rdp.light[n].a = 1.0f; |
476 | rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f; |
477 | rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f; |
478 | rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f; |
479 | // ** |
480 | wxUint32 a = addr >> 1; |
481 | rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+16)^1]); |
482 | rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+17)^1]); |
483 | rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+18)^1]); |
484 | rdp.light[n].w = (float)(((short*)gfx.RDRAM)[(a+19)^1]); |
485 | rdp.light[n].nonzero = gfx.RDRAM[(addr+12)^3]; |
486 | rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f; |
487 | //rdp.light[n].la = rdp.light[n].ca * 1.0f; |
488 | #ifdef EXTREME_LOGGING |
489 | FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, w: %f, ca: %f\n", |
490 | n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].w, rdp.light[n].ca); |
491 | #endif |
492 | FRDP ("light: n: %d, r: %f, g: %f, b: %f. dir: x: %.3f, y: %.3f, z: %.3f\n", |
493 | n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, |
494 | rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); |
495 | #ifdef EXTREME_LOGGING |
496 | for (int t=0; t < 24; t++) |
497 | { |
498 | FRDP ("light[%d] = 0x%04lx \n", t, ((wxUint16*)gfx.RDRAM)[(a+t)^1]); |
499 | } |
500 | #endif |
501 | } |
502 | break; |
503 | |
504 | case 14: //Normales |
505 | { |
506 | uc8_normale_addr = segoffset(rdp.cmd1); |
507 | FRDP ("Normale - addr: %08lx\n", uc8_normale_addr); |
508 | #ifdef EXTREME_LOGGING |
509 | int i; |
510 | for (i = 0; i < 32; i++) |
511 | { |
512 | char x = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 0)^3]; |
513 | char y = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 1)^3]; |
514 | FRDP("#%d x = %d, y = %d\n", i, x, y); |
515 | } |
516 | wxUint32 a = uc8_normale_addr >> 1; |
517 | for (i = 0; i < 32; i++) |
518 | { |
519 | FRDP ("n[%d] = 0x%04lx \n", i, ((wxUint16*)gfx.RDRAM)[(a+i)^1]); |
520 | } |
521 | #endif |
522 | } |
523 | break; |
524 | |
525 | default: |
526 | FRDP ("uc8:movemem unknown (%d)\n", idx); |
527 | } |
528 | } |
529 | |
530 | |
531 | static void uc8_tri4() //by Gugaman Apr 19 2002 |
532 | { |
533 | Check_FrameSkip; |
534 | |
535 | if (rdp.skip_drawing) |
536 | { |
537 | LRDP("uc8:tri4. skipped\n"); |
538 | return; |
539 | } |
540 | |
541 | FRDP("uc8:tri4 (#%d - #%d), %d-%d-%d, %d-%d-%d, %d-%d-%d, %d-%d-%d\n", |
542 | rdp.tri_n, |
543 | rdp.tri_n+3, |
544 | ((rdp.cmd0 >> 23) & 0x1F), |
545 | ((rdp.cmd0 >> 18) & 0x1F), |
546 | ((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3)), |
547 | ((rdp.cmd0 >> 10) & 0x1F), |
548 | ((rdp.cmd0 >> 5) & 0x1F), |
549 | ((rdp.cmd0 >> 0) & 0x1F), |
550 | ((rdp.cmd1 >> 25) & 0x1F), |
551 | ((rdp.cmd1 >> 20) & 0x1F), |
552 | ((rdp.cmd1 >> 15) & 0x1F), |
553 | ((rdp.cmd1 >> 10) & 0x1F), |
554 | ((rdp.cmd1 >> 5) & 0x1F), |
555 | ((rdp.cmd1 >> 0) & 0x1F)); |
556 | |
557 | VERTEX *v[12] = { |
558 | &rdp.vtx[(rdp.cmd0 >> 23) & 0x1F], |
559 | &rdp.vtx[(rdp.cmd0 >> 18) & 0x1F], |
560 | &rdp.vtx[((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3))], |
561 | &rdp.vtx[(rdp.cmd0 >> 10) & 0x1F], |
562 | &rdp.vtx[(rdp.cmd0 >> 5) & 0x1F], |
563 | &rdp.vtx[(rdp.cmd0 >> 0) & 0x1F], |
564 | &rdp.vtx[(rdp.cmd1 >> 25) & 0x1F], |
565 | &rdp.vtx[(rdp.cmd1 >> 20) & 0x1F], |
566 | &rdp.vtx[(rdp.cmd1 >> 15) & 0x1F], |
567 | &rdp.vtx[(rdp.cmd1 >> 10) & 0x1F], |
568 | &rdp.vtx[(rdp.cmd1 >> 5) & 0x1F], |
569 | &rdp.vtx[(rdp.cmd1 >> 0) & 0x1F] |
570 | }; |
571 | |
572 | int updated = 0; |
573 | |
574 | if (cull_tri(v)) |
575 | rdp.tri_n ++; |
576 | else |
577 | { |
578 | updated = 1; |
579 | update (); |
580 | |
581 | draw_tri (v); |
582 | rdp.tri_n ++; |
583 | } |
584 | |
585 | if (cull_tri(v+3)) |
586 | rdp.tri_n ++; |
587 | else |
588 | { |
589 | if (!updated) |
590 | { |
591 | updated = 1; |
592 | update (); |
593 | } |
594 | |
595 | draw_tri (v+3); |
596 | rdp.tri_n ++; |
597 | } |
598 | |
599 | if (cull_tri(v+6)) |
600 | rdp.tri_n ++; |
601 | else |
602 | { |
603 | if (!updated) |
604 | { |
605 | updated = 1; |
606 | update (); |
607 | } |
608 | |
609 | draw_tri (v+6); |
610 | rdp.tri_n ++; |
611 | } |
612 | |
613 | if (cull_tri(v+9)) |
614 | rdp.tri_n ++; |
615 | else |
616 | { |
617 | if (!updated) |
618 | { |
619 | updated = 1; |
620 | update (); |
621 | } |
622 | |
623 | draw_tri (v+9); |
624 | rdp.tri_n ++; |
625 | } |
626 | } |