ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glide64 / ucode09.h
CommitLineData
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// December 2008 Created by Gonetz (Gonetz@ngs.ru)
41//
42//****************************************************************
43
44void uc9_rpdcmd ();
45
46typedef float M44[4][4];
47
48struct ZSORTRDP {
49 float view_scale[2];
50 float view_trans[2];
51 float scale_x;
52 float scale_y;
53} zSortRdp = {{0, 0}, {0, 0}, 0, 0};
54
55//RSP command VRCPL
56static int Calc_invw (int w) {
57 int count, neg;
58 union {
59 wxInt32 W;
60 wxUint32 UW;
61 wxInt16 HW[2];
62 wxUint16 UHW[2];
63 } Result;
64 Result.W = w;
65 if (Result.UW == 0) {
66 Result.UW = 0x7FFFFFFF;
67 } else {
68 if (Result.W < 0) {
69 neg = TRUE;
70 if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) {
71 Result.W = ~Result.W + 1;
72 } else {
73 Result.W = ~Result.W;
74 }
75 } else {
76 neg = FALSE;
77 }
78 for (count = 31; count > 0; count--) {
79 if ((Result.W & (1 << count))) {
80 Result.W &= (0xFFC00000 >> (31 - count) );
81 count = 0;
82 }
83 }
84 Result.W = 0x7FFFFFFF / Result.W;
85 for (count = 31; count > 0; count--) {
86 if ((Result.W & (1 << count))) {
87 Result.W &= (0xFFFF8000 >> (31 - count) );
88 count = 0;
89 }
90 }
91 if (neg == TRUE) {
92 Result.W = ~Result.W;
93 }
94 }
95 return Result.W;
96}
97
98static void uc9_draw_object (wxUint8 * addr, wxUint32 type)
99{
100Check_FrameSkip;
101
102 wxUint32 textured, vnum, vsize;
103 switch (type) {
104 case 1: //sh tri
105 textured = 0;
106 vnum = 3;
107 vsize = 8;
108 break;
109 case 2: //tx tri
110 textured = 1;
111 vnum = 3;
112 vsize = 16;
113 break;
114 case 3: //sh quad
115 textured = 0;
116 vnum = 4;
117 vsize = 8;
118 break;
119 case 4: //tx quad
120 textured = 1;
121 vnum = 4;
122 vsize = 16;
123 break;
124 case 0: //null
125 default:
126 textured = vnum = vsize = 0;
127 break;
128 }
129 VERTEX vtx[4];
130 for (wxUint32 i = 0; i < vnum; i++)
131 {
132 VERTEX &v = vtx[i];
133 v.sx = zSortRdp.scale_x * ((short*)addr)[0^1];
134 v.sy = zSortRdp.scale_y * ((short*)addr)[1^1];
135 v.sz = 1.0f;
136 v.r = addr[4^3];
137 v.g = addr[5^3];
138 v.b = addr[6^3];
139 v.a = addr[7^3];
140 v.flags = 0;
141 v.uv_scaled = 0;
142 v.uv_calculated = 0xFFFFFFFF;
143 v.shade_mod = 0;
144 v.scr_off = 0;
145 v.screen_translated = 2;
146 if (textured)
147 {
148 v.ou = ((short*)addr)[4^1];
149 v.ov = ((short*)addr)[5^1];
150 v.w = Calc_invw(((int*)addr)[3]) / 31.0f;
151 v.oow = 1.0f / v.w;
152 FRDP ("v%d - sx: %f, sy: %f ou: %f, ov: %f, w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.ou*rdp.tiles[rdp.cur_tile].s_scale, v.ov*rdp.tiles[rdp.cur_tile].t_scale, v.w, v.r, v.g, v.b, v.a);
153 }
154 else
155 {
156 v.oow = v.w = 1.0f;
157 FRDP ("v%d - sx: %f, sy: %f r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.r, v.g, v.b, v.a);
158 }
159 addr += vsize;
160 }
161 //*
162 VERTEX *pV[4] = {
163 &vtx[0],
164 &vtx[1],
165 &vtx[2],
166 &vtx[3]
167 };
168 if (vnum == 3)
169 {
170 FRDP("uc9:Tri #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
171 draw_tri (pV, 0);
172 rdp.tri_n ++;
173 }
174 else
175 {
176 FRDP("uc9:Quad #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
177 draw_tri (pV, 0);
178 draw_tri (pV+1, 0);
179 rdp.tri_n += 2;
180 }
181}
182
183static wxUint32 uc9_load_object (wxUint32 zHeader, wxUint32 * rdpcmds)
184{
185 wxUint32 type = zHeader & 7;
186 wxUint8 * addr = gfx.RDRAM + (zHeader&0xFFFFFFF8);
187 switch (type) {
188 case 1: //sh tri
189 case 3: //sh quad
190 {
191 rdp.cmd1 = ((wxUint32*)addr)[1];
192 if (rdp.cmd1 != rdpcmds[0])
193 {
194 rdpcmds[0] = rdp.cmd1;
195 uc9_rpdcmd ();
196 }
197 update ();
198 uc9_draw_object(addr + 8, type);
199 }
200 break;
201 case 0: //null
202 case 2: //tx tri
203 case 4: //tx quad
204 {
205 rdp.cmd1 = ((wxUint32*)addr)[1];
206 if (rdp.cmd1 != rdpcmds[0])
207 {
208 rdpcmds[0] = rdp.cmd1;
209 uc9_rpdcmd ();
210 }
211 rdp.cmd1 = ((wxUint32*)addr)[2];
212 if (rdp.cmd1 != rdpcmds[1])
213 {
214 uc9_rpdcmd ();
215 rdpcmds[1] = rdp.cmd1;
216 }
217 rdp.cmd1 = ((wxUint32*)addr)[3];
218 if (rdp.cmd1 != rdpcmds[2])
219 {
220 uc9_rpdcmd ();
221 rdpcmds[2] = rdp.cmd1;
222 }
223 if (type)
224 {
225 update ();
226 uc9_draw_object(addr + 16, type);
227 }
228 }
229 break;
230 }
231 return segoffset(((wxUint32*)addr)[0]);
232}
233
234static void uc9_object ()
235{
236 LRDP("uc9:object\n");
237 wxUint32 rdpcmds[3] = {0, 0, 0};
238 wxUint32 cmd1 = rdp.cmd1;
239 wxUint32 zHeader = segoffset(rdp.cmd0);
240 while (zHeader)
241 zHeader = uc9_load_object(zHeader, rdpcmds);
242 zHeader = segoffset(cmd1);
243 while (zHeader)
244 zHeader = uc9_load_object(zHeader, rdpcmds);
245}
246
247static void uc9_mix ()
248{
249 LRDP("uc9:mix IGNORED\n");
250}
251
252static void uc9_fmlight ()
253{
254 int mid = rdp.cmd0&0xFF;
255 rdp.num_lights = 1 + ((rdp.cmd1>>12)&0xFF);
256 wxUint32 a = -1024 + (rdp.cmd1&0xFFF);
257 FRDP ("uc9:fmlight matrix: %d, num: %d, dmem: %04lx\n", mid, rdp.num_lights, a);
258
259 M44 *m = NULL;
260 switch (mid) {
261 case 4:
262 m = (M44*)rdp.model;
263 break;
264 case 6:
265 m = (M44*)rdp.proj;
266 break;
267 case 8:
268 m = (M44*)rdp.combined;
269 break;
270 }
271
272 rdp.light[rdp.num_lights].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f;
273 rdp.light[rdp.num_lights].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f;
274 rdp.light[rdp.num_lights].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f;
275 rdp.light[rdp.num_lights].a = 1.0f;
276 FRDP ("ambient light: r: %.3f, g: %.3f, b: %.3f\n", rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b);
277 a += 8;
278 wxUint32 i;
279 for (i = 0; i < rdp.num_lights; i++)
280 {
281 rdp.light[i].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f;
282 rdp.light[i].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f;
283 rdp.light[i].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f;
284 rdp.light[i].a = 1.0f;
285 rdp.light[i].dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f;
286 rdp.light[i].dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f;
287 rdp.light[i].dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f;
288 FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n",
289 i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b,
290 rdp.light[i].dir_x, rdp.light[i].dir_y, rdp.light[i].dir_z);
291// TransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m);
292 InverseTransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m);
293 NormalizeVector (rdp.light_vector[i]);
294 FRDP ("light vector: n: %d, x: %.3f, y: %.3f, z: %.3f\n",
295 i, rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]);
296 a += 24;
297 }
298 for (i = 0; i < 2; i++)
299 {
300 float dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f;
301 float dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f;
302 float dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f;
303 if (sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) < 0.98)
304 {
305 rdp.use_lookat = FALSE;
306 return;
307 }
308 rdp.lookat[i][0] = dir_x;
309 rdp.lookat[i][1] = dir_y;
310 rdp.lookat[i][2] = dir_z;
311 a += 24;
312 }
313 rdp.use_lookat = TRUE;
314}
315
316static void uc9_light ()
317{
318 wxUint32 csrs = -1024 + ((rdp.cmd0>>12)&0xFFF);
319 wxUint32 nsrs = -1024 + (rdp.cmd0&0xFFF);
320 wxUint32 num = 1 + ((rdp.cmd1>>24)&0xFF);
321 wxUint32 cdest = -1024 + ((rdp.cmd1>>12)&0xFFF);
322 wxUint32 tdest = -1024 + (rdp.cmd1&0xFFF);
323 int use_material = (csrs != 0x0ff0);
324 tdest >>= 1;
325 FRDP ("uc9:light n: %d, colsrs: %04lx, normales: %04lx, coldst: %04lx, texdst: %04lx\n", num, csrs, nsrs, cdest, tdest);
326 VERTEX v;
327 for (wxUint32 i = 0; i < num; i++)
328 {
329 v.vec[0] = ((char*)gfx.DMEM)[(nsrs++)^3];
330 v.vec[1] = ((char*)gfx.DMEM)[(nsrs++)^3];
331 v.vec[2] = ((char*)gfx.DMEM)[(nsrs++)^3];
332 calc_sphere (&v);
333// calc_linear (&v);
334 NormalizeVector (v.vec);
335 calc_light (&v);
336 v.a = 0xFF;
337 if (use_material)
338 {
339 v.r = (wxUint8)(((wxUint32)v.r * gfx.DMEM[(csrs++)^3])>>8);
340 v.g = (wxUint8)(((wxUint32)v.g * gfx.DMEM[(csrs++)^3])>>8);
341 v.b = (wxUint8)(((wxUint32)v.b * gfx.DMEM[(csrs++)^3])>>8);
342 v.a = gfx.DMEM[(csrs++)^3];
343 }
344 gfx.DMEM[(cdest++)^3] = v.r;
345 gfx.DMEM[(cdest++)^3] = v.g;
346 gfx.DMEM[(cdest++)^3] = v.b;
347 gfx.DMEM[(cdest++)^3] = v.a;
348 ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ou;
349 ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ov;
350 }
351}
352
353static void uc9_mtxtrnsp ()
354{
355 LRDP("uc9:mtxtrnsp - ignored\n");
356 /*
357 LRDP("uc9:mtxtrnsp ");
358 M44 *s;
359 switch (rdp.cmd1&0xF) {
360 case 4:
361 s = (M44*)rdp.model;
362 LRDP("Model\n");
363 break;
364 case 6:
365 s = (M44*)rdp.proj;
366 LRDP("Proj\n");
367 break;
368 case 8:
369 s = (M44*)rdp.combined;
370 LRDP("Comb\n");
371 break;
372 }
373 float m = *s[1][0];
374 *s[1][0] = *s[0][1];
375 *s[0][1] = m;
376 m = *s[2][0];
377 *s[2][0] = *s[0][2];
378 *s[0][2] = m;
379 m = *s[2][1];
380 *s[2][1] = *s[1][2];
381 *s[1][2] = m;
382 */
383}
384
385static void uc9_mtxcat ()
386{
387 LRDP("uc9:mtxcat ");
388 M44 *s = NULL;
389 M44 *t = NULL;
390 wxUint32 S = rdp.cmd0&0xF;
391 wxUint32 T = (rdp.cmd1>>16)&0xF;
392 wxUint32 D = rdp.cmd1&0xF;
393 switch (S) {
394 case 4:
395 s = (M44*)rdp.model;
396 LRDP("Model * ");
397 break;
398 case 6:
399 s = (M44*)rdp.proj;
400 LRDP("Proj * ");
401 break;
402 case 8:
403 s = (M44*)rdp.combined;
404 LRDP("Comb * ");
405 break;
406 }
407 switch (T) {
408 case 4:
409 t = (M44*)rdp.model;
410 LRDP("Model -> ");
411 break;
412 case 6:
413 t = (M44*)rdp.proj;
414 LRDP("Proj -> ");
415 break;
416 case 8:
417 LRDP("Comb -> ");
418 t = (M44*)rdp.combined;
419 break;
420 }
421 DECLAREALIGN16VAR(m[4][4]);
422 MulMatrices(*s, *t, m);
423
424 switch (D) {
425 case 4:
426 memcpy (rdp.model, m, 64);;
427 LRDP("Model\n");
428 break;
429 case 6:
430 memcpy (rdp.proj, m, 64);;
431 LRDP("Proj\n");
432 break;
433 case 8:
434 memcpy (rdp.combined, m, 64);;
435 LRDP("Comb\n");
436 break;
437 }
438#ifdef EXTREME_LOGGING
439 FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]);
440 FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]);
441 FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]);
442 FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]);
443 FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]);
444 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]);
445 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]);
446 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]);
447 FRDP ("\ncombined\n{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]);
448 FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]);
449 FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]);
450 FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]);
451#endif
452}
453
454typedef struct {
455 short sy;
456 short sx;
457 int invw;
458 short yi;
459 short xi;
460 short wi;
461 wxUint8 fog;
462 wxUint8 cc;
463} zSortVDest;
464
465static void uc9_mult_mpmtx ()
466{
467 //int id = rdp.cmd0&0xFF;
468 int num = 1+ ((rdp.cmd1>>24)&0xFF);
469 int src = -1024 + ((rdp.cmd1>>12)&0xFFF);
470 int dst = -1024 + (rdp.cmd1&0xFFF);
471 FRDP ("uc9:mult_mpmtx from: %04lx to: %04lx n: %d\n", src, dst, num);
472 short * saddr = (short*)(gfx.DMEM+src);
473 zSortVDest * daddr = (zSortVDest*)(gfx.DMEM+dst);
474 int idx = 0;
475 zSortVDest v;
476 memset(&v, 0, sizeof(zSortVDest));
477 //float scale_x = 4.0f/rdp.scale_x;
478 //float scale_y = 4.0f/rdp.scale_y;
479 for (int i = 0; i < num; i++)
480 {
481 short sx = saddr[(idx++)^1];
482 short sy = saddr[(idx++)^1];
483 short sz = saddr[(idx++)^1];
484 float x = sx*rdp.combined[0][0] + sy*rdp.combined[1][0] + sz*rdp.combined[2][0] + rdp.combined[3][0];
485 float y = sx*rdp.combined[0][1] + sy*rdp.combined[1][1] + sz*rdp.combined[2][1] + rdp.combined[3][1];
486 float z = sx*rdp.combined[0][2] + sy*rdp.combined[1][2] + sz*rdp.combined[2][2] + rdp.combined[3][2];
487 float w = sx*rdp.combined[0][3] + sy*rdp.combined[1][3] + sz*rdp.combined[2][3] + rdp.combined[3][3];
488 v.sx = (short)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]);
489 v.sy = (short)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]);
490
491 v.xi = (short)x;
492 v.yi = (short)y;
493 v.wi = (short)w;
494 v.invw = Calc_invw((int)(w * 31.0));
495
496 if (w < 0.0f)
497 v.fog = 0;
498 else
499 {
500 int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset);
501 if (fog > 255)
502 fog = 255;
503 v.fog = (fog >= 0) ? (wxUint8)fog : 0;
504 }
505
506 v.cc = 0;
507 if (x < -w) v.cc |= 0x10;
508 if (x > w) v.cc |= 0x01;
509 if (y < -w) v.cc |= 0x20;
510 if (y > w) v.cc |= 0x02;
511 if (w < 0.1f) v.cc |= 0x04;
512
513 daddr[i] = v;
514 //memcpy(gfx.DMEM+dst+sizeof(zSortVDest)*i, &v, sizeof(zSortVDest));
515// FRDP("v%d x: %d, y: %d, z: %d -> sx: %d, sy: %d, w: %d, xi: %d, yi: %d, wi: %d, fog: %d\n", i, sx, sy, sz, v.sx, v.sy, v.invw, v.xi, v.yi, v.wi, v.fog);
516 FRDP("v%d x: %d, y: %d, z: %d -> sx: %04lx, sy: %04lx, invw: %08lx - %f, xi: %04lx, yi: %04lx, wi: %04lx, fog: %04lx\n", i, sx, sy, sz, v.sx, v.sy, v.invw, w, v.xi, v.yi, v.wi, v.fog);
517 }
518}
519
520static void uc9_link_subdl ()
521{
522 LRDP("uc9:link_subdl IGNORED\n");
523}
524
525static void uc9_set_subdl ()
526{
527 LRDP("uc9:set_subdl IGNORED\n");
528}
529
530static void uc9_wait_signal ()
531{
532 LRDP("uc9:wait_signal IGNORED\n");
533}
534
535static void uc9_send_signal ()
536{
537 LRDP("uc9:send_signal IGNORED\n");
538}
539
540void uc9_movemem ()
541{
542 LRDP("uc9:movemem\n");
543 int idx = rdp.cmd0 & 0x0E;
544 int ofs = ((rdp.cmd0>>6)&0x1ff)<<3;
545 int len = (1 + ((rdp.cmd0>>15)&0x1ff))<<3;
546 FRDP ("uc9:movemem ofs: %d, len: %d. ", ofs, len);
547 int flag = rdp.cmd0 & 0x01;
548 wxUint32 addr = segoffset(rdp.cmd1);
549 switch (idx)
550 {
551
552 case 0: //save/load
553 if (flag == 0)
554 {
555 int dmem_addr = (idx<<3) + ofs;
556 FRDP ("Load to DMEM. %08lx -> %08lx\n", addr, dmem_addr);
557 memcpy(gfx.DMEM + dmem_addr, gfx.RDRAM + addr, len);
558 }
559 else
560 {
561 int dmem_addr = (idx<<3) + ofs;
562 FRDP ("Load from DMEM. %08lx -> %08lx\n", dmem_addr, addr);
563 memcpy(gfx.RDRAM + addr, gfx.DMEM + dmem_addr, len);
564 }
565 break;
566
567 case 4: // model matrix
568 case 6: // projection matrix
569 case 8: // combined matrix
570 {
571 DECLAREALIGN16VAR(m[4][4]);
572 load_matrix(m, addr);
573 switch (idx)
574 {
575 case 4: // model matrix
576 LRDP("Modelview load\n");
577 modelview_load (m);
578 break;
579 case 6: // projection matrix
580 LRDP("Projection load\n");
581 projection_load (m);
582 break;
583 case 8: // projection matrix
584 LRDP("Combined load\n");
585 rdp.update &= ~UPDATE_MULT_MAT;
586 memcpy (rdp.combined, m, 64);;
587 break;
588 }
589#ifdef EXTREME_LOGGING
590 FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]);
591 FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]);
592 FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]);
593 FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]);
594 FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]);
595 FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]);
596 FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]);
597 FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]);
598 FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]);
599 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]);
600 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]);
601 FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]);
602#endif
603 }
604 break;
605
606 case 10:
607 LRDP("Othermode - IGNORED\n");
608 break;
609
610 case 12: // VIEWPORT
611 {
612 wxUint32 a = addr >> 1;
613 short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2;
614 short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2;
615 short scale_z = ((short*)gfx.RDRAM)[(a+2)^1];
616 rdp.fog_multiplier = ((short*)gfx.RDRAM)[(a+3)^1];
617 short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2;
618 short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2;
619 short trans_z = ((short*)gfx.RDRAM)[(a+6)^1];
620 rdp.fog_offset = ((short*)gfx.RDRAM)[(a+7)^1];
621 rdp.view_scale[0] = scale_x * rdp.scale_x;
622 rdp.view_scale[1] = scale_y * rdp.scale_y;
623 rdp.view_scale[2] = 32.0f * scale_z;
624 rdp.view_trans[0] = trans_x * rdp.scale_x;
625 rdp.view_trans[1] = trans_y * rdp.scale_y;
626 rdp.view_trans[2] = 32.0f * trans_z;
627 zSortRdp.view_scale[0] = (float)(scale_x*4);
628 zSortRdp.view_scale[1] = (float)(scale_y*4);
629 zSortRdp.view_trans[0] = (float)(trans_x*4);
630 zSortRdp.view_trans[1] = (float)(trans_y*4);
631 zSortRdp.scale_x = rdp.scale_x / 4.0f;
632 zSortRdp.scale_y = rdp.scale_y / 4.0f;
633
634 rdp.update |= UPDATE_VIEWPORT;
635
636 rdp.mipmap_level = 0;
637 rdp.cur_tile = 0;
638 TILE *tmp_tile = &rdp.tiles[0];
639 tmp_tile->on = 1;
640 tmp_tile->org_s_scale = 0xFFFF;
641 tmp_tile->org_t_scale = 0xFFFF;
642 tmp_tile->s_scale = 0.031250f;
643 tmp_tile->t_scale = 0.031250f;
644
645 rdp.geom_mode |= 0x0200;
646
647 FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z,
648 trans_x, trans_y, trans_z, a);
649 FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset);
650 }
651 break;
652
653 default:
654 FRDP ("** UNKNOWN %d\n", idx);
655 }
656
657}
658
659static void uc9_setscissor()
660{
661 rdp_setscissor();
662
663 if ((rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0]))
664 {
665 float w = (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) / 2.0f;
666 float h = (rdp.scissor_o.lr_y - rdp.scissor_o.ul_y) / 2.0f;
667 rdp.view_scale[0] = w * rdp.scale_x;
668 rdp.view_scale[1] = h * rdp.scale_y;
669 rdp.view_trans[0] = w * rdp.scale_x;
670 rdp.view_trans[1] = h * rdp.scale_y;
671 zSortRdp.view_scale[0] = w * 4.0f;
672 zSortRdp.view_scale[1] = h * 4.0f;
673 zSortRdp.view_trans[0] = w * 4.0f;
674 zSortRdp.view_trans[1] = h * 4.0f;
675 zSortRdp.scale_x = rdp.scale_x / 4.0f;
676 zSortRdp.scale_y = rdp.scale_y / 4.0f;
677 rdp.update |= UPDATE_VIEWPORT;
678
679 rdp.mipmap_level = 0;
680 rdp.cur_tile = 0;
681 TILE *tmp_tile = &rdp.tiles[0];
682 tmp_tile->on = 1;
683 tmp_tile->org_s_scale = 0xFFFF;
684 tmp_tile->org_t_scale = 0xFFFF;
685 tmp_tile->s_scale = 0.031250f;
686 tmp_tile->t_scale = 0.031250f;
687
688 rdp.geom_mode |= 0x0200;
689 }
690}