Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glide64 / ucodeFB.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// Creation 13 August 2003 Gonetz
41//
42//****************************************************************
43
44static void fb_uc0_moveword()
45{
46 if ((rdp.cmd0 & 0xFF) == 0x06) // segment
47 {
48 rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1;
49 }
50}
51
52static void fb_uc2_moveword()
53{
54 if (((rdp.cmd0 >> 16) & 0xFF) == 0x06) // segment
55 {
56 rdp.segment[((rdp.cmd0 & 0xFFFF) >> 2)&0xF] = rdp.cmd1;
57 }
58}
59
60static void fb_bg_copy ()
61{
62 if (rdp.main_ci == 0)
63 return;
64 CI_STATUS status = rdp.frame_buffers[rdp.ci_count-1].status;
65 if ( (status == ci_copy) )
66 return;
67
68 wxUint32 addr = segoffset(rdp.cmd1) >> 1;
69 wxUint8 imageFmt = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+0)^3];
70 wxUint8 imageSiz = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+1)^3];
71 wxUint32 imagePtr = segoffset(((wxUint32*)gfx.RDRAM)[(addr+8)>>1]);
72 FRDP ("fb_bg_copy. fmt: %d, size: %d, imagePtr %08lx, main_ci: %08lx, cur_ci: %08lx \n", imageFmt, imageSiz, imagePtr, rdp.main_ci, rdp.frame_buffers[rdp.ci_count-1].addr);
73
74 if (status == ci_main)
75 {
76 wxUint16 frameW = ((wxUint16 *)gfx.RDRAM)[(addr+3)^1] >> 2;
77 wxUint16 frameH = ((wxUint16 *)gfx.RDRAM)[(addr+7)^1] >> 2;
78 if ( (frameW == rdp.frame_buffers[rdp.ci_count-1].width) && (frameH == rdp.frame_buffers[rdp.ci_count-1].height) )
79 rdp.main_ci_bg = imagePtr;
80 }
81 else if (imagePtr >= rdp.main_ci && imagePtr < rdp.main_ci_end) //addr within main frame buffer
82 {
83 rdp.copy_ci_index = rdp.ci_count-1;
84 rdp.frame_buffers[rdp.copy_ci_index].status = ci_copy;
85 FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index);
86
87 if (rdp.frame_buffers[rdp.copy_ci_index].addr != rdp.main_ci_bg)
88 {
89 rdp.scale_x = 1.0f;
90 rdp.scale_y = 1.0f;
91 }
92 else
93 {
94 LRDP("motion blur!\n");
95 rdp.motionblur = TRUE;
96 }
97
98 FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", imagePtr, rdp.main_ci);
99 }
100 else if (imagePtr == rdp.zimg)
101 {
102 if (status == ci_unknown)
103 {
104 rdp.frame_buffers[rdp.ci_count-1].status = ci_zcopy;
105 rdp.tmpzimg = rdp.frame_buffers[rdp.ci_count-1].addr;
106 if (!rdp.copy_zi_index)
107 rdp.copy_zi_index = rdp.ci_count-1;
108 FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.copy_ci_index);
109 }
110 }
111}
112
113static void fb_setscissor()
114{
115 rdp.scissor_o.lr_y = (wxUint32)(((rdp.cmd1 & 0x00000FFF) >> 2));
116 if (rdp.ci_count)
117 {
118 rdp.scissor_o.ul_x = (wxUint32)(((rdp.cmd0 & 0x00FFF000) >> 14));
119 rdp.scissor_o.lr_x = (wxUint32)(((rdp.cmd1 & 0x00FFF000) >> 14));
120 COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1];
121 if (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x > (wxUint32)(cur_fb.width >> 1))
122 {
123 if (cur_fb.height == 0 || (cur_fb.width >= rdp.scissor_o.lr_x-1 && cur_fb.width <= rdp.scissor_o.lr_x+1))
124 cur_fb.height = rdp.scissor_o.lr_y;
125 }
126 FRDP("fb_setscissor. lr_x = %d, lr_y = %d, fb_width = %d, fb_height = %d\n", rdp.scissor_o.lr_x, rdp.scissor_o.lr_y, cur_fb.width, cur_fb.height);
127 }
128}
129
130static void fb_uc2_movemem()
131{
132 if ((rdp.cmd0 & 0xFF) == 8)
133 {
134 wxUint32 a = segoffset(rdp.cmd1) >> 1;
135 short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2;
136 short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2;
137 COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1];
138 if ( abs((int)(scale_x + trans_x - cur_fb.width)) < 3)
139 {
140 short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2;
141 short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2;
142 wxUint32 height = scale_y + trans_y;
143 if (height < rdp.scissor_o.lr_y)
144 cur_fb.height = height;
145 }
146 }
147}
148
149static void fb_rect()
150{
151 if (rdp.frame_buffers[rdp.ci_count-1].width == 32)
152 return;
153 int ul_x = ((rdp.cmd1 & 0x00FFF000) >> 14);
154 int lr_x = ((rdp.cmd0 & 0x00FFF000) >> 14);
155 int width = lr_x-ul_x;
156 int diff = abs((int)rdp.frame_buffers[rdp.ci_count-1].width - width);
157 if (diff < 4)
158 {
159 wxUint32 lr_y = min(rdp.scissor_o.lr_y, (rdp.cmd0 & 0xFFF) >> 2);
160 if (rdp.frame_buffers[rdp.ci_count-1].height < lr_y)
161 {
162 FRDP("fb_rect. ul_x: %d, lr_x: %d, fb_height: %d -> %d\n", ul_x, lr_x, rdp.frame_buffers[rdp.ci_count-1].height, lr_y);
163 rdp.frame_buffers[rdp.ci_count-1].height = lr_y;
164 }
165 }
166}
167
168static void fb_rdphalf_1()
169{
170 branch_dl = rdp.cmd1;
171}
172
173
174static void fb_settextureimage()
175{
176 if (rdp.main_ci == 0)
177 return;
178 COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1];
179 if ( cur_fb.status >= ci_copy )
180 return;
181 if (((rdp.cmd0 >> 19) & 0x03) >= 2) //check that texture is 16/32bit
182 {
183 int tex_format = ((rdp.cmd0 >> 21) & 0x07);
184 wxUint32 addr = segoffset(rdp.cmd1);
185 if ( tex_format == 0 )
186 {
187 FRDP ("fb_settextureimage. fmt: %d, size: %d, imagePtr %08lx, main_ci: %08lx, cur_ci: %08lx \n", ((rdp.cmd0 >> 21) & 0x07), ((rdp.cmd0 >> 19) & 0x03), addr, rdp.main_ci, rdp.frame_buffers[rdp.ci_count-1].addr);
188 if (cur_fb.status == ci_main)
189 {
190 rdp.main_ci_last_tex_addr = addr;
191 if (cur_fb.height == 0)
192 {
193 cur_fb.height = rdp.scissor_o.lr_y;
194 rdp.main_ci_end = cur_fb.addr + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1);
195 }
196 }
197 if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer
198 {
199 if (cur_fb.status == ci_main)
200 {
201 rdp.copy_ci_index = rdp.ci_count-1;
202 cur_fb.status = ci_copy_self;
203 rdp.scale_x = rdp.scale_x_bak;
204 rdp.scale_y = rdp.scale_y_bak;
205 FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1);
206 }
207 else
208 {
209 if (cur_fb.width == rdp.frame_buffers[rdp.main_ci_index].width)
210 {
211 rdp.copy_ci_index = rdp.ci_count-1;
212 cur_fb.status = ci_copy;
213 FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index);
214 if ((rdp.main_ci_last_tex_addr >= cur_fb.addr) &&
215 (rdp.main_ci_last_tex_addr < (cur_fb.addr + cur_fb.width*cur_fb.height*cur_fb.size)))
216 {
217 LRDP("motion blur!\n");
218 rdp.motionblur = TRUE;
219 }
220 else
221 {
222 rdp.scale_x = 1.0f;
223 rdp.scale_y = 1.0f;
224 }
225 }
226 else if (!(settings.frame_buffer & fb_ignore_aux_copy) && cur_fb.width < rdp.frame_buffers[rdp.main_ci_index].width)
227 {
228 rdp.copy_ci_index = rdp.ci_count-1;
229 cur_fb.status = ci_aux_copy;
230 FRDP("rdp.frame_buffers[%d].status = ci_aux_copy\n", rdp.copy_ci_index);
231 rdp.scale_x = 1.0f;
232 rdp.scale_y = 1.0f;
233 }
234 else
235 {
236 cur_fb.status = ci_aux;
237 FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.copy_ci_index);
238 }
239 }
240 FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", addr, rdp.main_ci);
241 }
242 ///*
243 else if ((cur_fb.status != ci_main) && (addr >= rdp.zimg && addr < rdp.zimg_end))
244 {
245 cur_fb.status = ci_zcopy;
246 if (!rdp.copy_zi_index)
247 rdp.copy_zi_index = rdp.ci_count-1;
248 FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count-1);
249 }
250 //*/
251 else if ((rdp.maincimg[0].width > 64) && (addr >= rdp.maincimg[0].addr) && (addr < (rdp.maincimg[0].addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2)))
252 {
253 if (cur_fb.status != ci_main)
254 {
255 cur_fb.status = ci_old_copy;
256 FRDP("rdp.frame_buffers[%d].status = ci_old_copy 1, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr);
257 }
258 rdp.read_previous_ci = TRUE;
259 LRDP("read_previous_ci = TRUE\n");
260 }
261 else if ((addr >= rdp.last_drawn_ci_addr) && (addr < (rdp.last_drawn_ci_addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2)))
262 {
263 if (cur_fb.status != ci_main)
264 {
265 cur_fb.status = ci_old_copy;
266 FRDP("rdp.frame_buffers[%d].status = ci_old_copy 2, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr);
267 }
268 rdp.read_previous_ci = TRUE;
269 LRDP("read_previous_ci = TRUE\n");
270 }
271 }
272 else if (fb_hwfbe_enabled && (cur_fb.status == ci_main))
273 {
274 if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer
275 {
276 rdp.copy_ci_index = rdp.ci_count-1;
277 rdp.black_ci_index = rdp.ci_count-1;
278 cur_fb.status = ci_copy_self;
279 FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1);
280 }
281 }
282 }
283 if (cur_fb.status == ci_unknown)
284 {
285 cur_fb.status = ci_aux;
286 FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1);
287 }
288}
289
290static void fb_loadtxtr()
291{
292 if (rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown)
293 {
294 rdp.frame_buffers[rdp.ci_count-1].status = ci_aux;
295 FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1);
296 }
297}
298
299static void fb_setdepthimage()
300{
301 rdp.zimg = segoffset(rdp.cmd1) & BMASK;
302 rdp.zimg_end = rdp.zimg + rdp.ci_width*rdp.ci_height*2;
303 FRDP ("fb_setdepthimage. addr %08lx - %08lx\n", rdp.zimg, rdp.zimg_end);
304 if (rdp.zimg == rdp.main_ci) //strange, but can happen
305 {
306 rdp.frame_buffers[rdp.main_ci_index].status = ci_unknown;
307 if (rdp.main_ci_index < rdp.ci_count)
308 {
309 rdp.frame_buffers[rdp.main_ci_index].status = ci_zimg;
310 FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.main_ci_index);
311 rdp.main_ci_index++;
312 rdp.frame_buffers[rdp.main_ci_index].status = ci_main;
313 FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.main_ci_index);
314 rdp.main_ci = rdp.frame_buffers[rdp.main_ci_index].addr;
315 rdp.main_ci_end = rdp.main_ci + (rdp.frame_buffers[rdp.main_ci_index].width * rdp.frame_buffers[rdp.main_ci_index].height * rdp.frame_buffers[rdp.main_ci_index].size);
316 for (int i = rdp.main_ci_index+1; i < rdp.ci_count; i++)
317 {
318 COLOR_IMAGE & fb = rdp.frame_buffers[i];
319 if (fb.addr == rdp.main_ci)
320 {
321 fb.status = ci_main;
322 FRDP("rdp.frame_buffers[%d].status = ci_main\n", i);
323 }
324 }
325 }
326 else
327 {
328 rdp.main_ci = 0;
329 }
330 }
331 for (int i = 0; i < rdp.ci_count; i++)
332 {
333 COLOR_IMAGE & fb = rdp.frame_buffers[i];
334 if ((fb.addr == rdp.zimg) && (fb.status == ci_aux || fb.status == ci_useless))
335 {
336 fb.status = ci_zimg;
337 FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", i);
338 }
339 }
340}
341
342static void fb_setcolorimage()
343{
344 rdp.ocimg = rdp.cimg;
345 rdp.cimg = segoffset(rdp.cmd1) & BMASK;
346 COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count];
347 cur_fb.width = (rdp.cmd0 & 0xFFF) + 1;
348 if (cur_fb.width == 32 )
349 cur_fb.height = 32;
350 else if (cur_fb.width == 16 )
351 cur_fb.height = 16;
352 else if (rdp.ci_count > 0)
353 cur_fb.height = rdp.scissor_o.lr_y;
354 else
355 cur_fb.height = 0;
356 cur_fb.format = (rdp.cmd0 >> 21) & 0x7;
357 cur_fb.size = (rdp.cmd0 >> 19) & 0x3;
358 cur_fb.addr = rdp.cimg;
359 cur_fb.changed = 1;
360 /*
361 if (rdp.ci_count > 0)
362 if (rdp.frame_buffers[0].addr == rdp.cimg)
363 rdp.frame_buffers[0].height = rdp.scissor_o.lr_y;
364 */
365 FRDP ("fb_setcolorimage. width: %d, height: %d, fmt: %d, size: %d, addr %08lx\n", cur_fb.width, cur_fb.height, cur_fb.format, cur_fb.size, cur_fb.addr);
366 if (rdp.cimg == rdp.zimg)
367 {
368 cur_fb.status = ci_zimg;
369 rdp.zimg_end = rdp.zimg + cur_fb.width*rdp.scissor_o.lr_y*2;
370 FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.ci_count);
371 }
372 else if (rdp.cimg == rdp.tmpzimg)
373 {
374 cur_fb.status = ci_zcopy;
375 if (!rdp.copy_zi_index)
376 rdp.copy_zi_index = rdp.ci_count-1;
377 FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count);
378 }
379 else if (rdp.main_ci != 0)
380 {
381 if (rdp.cimg == rdp.main_ci) //switched to main fb again
382 {
383 cur_fb.height = max(cur_fb.height, rdp.frame_buffers[rdp.main_ci_index].height);
384 rdp.main_ci_index = rdp.ci_count;
385 rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1);
386 cur_fb.status = ci_main;
387 FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count);
388 }
389 else // status is not known yet
390 {
391 cur_fb.status = ci_unknown;
392 }
393 }
394 else
395 {
396 if ((rdp.zimg != rdp.cimg))//&& (rdp.ocimg != rdp.cimg))
397 {
398 rdp.main_ci = rdp.cimg;
399 rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1);
400 rdp.main_ci_index = rdp.ci_count;
401 cur_fb.status = ci_main;
402 FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count);
403 }
404 else
405 {
406 cur_fb.status = ci_unknown;
407 }
408
409 }
410 if (rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown) //status of previous fb was not changed - it is useless
411 {
412 if (fb_hwfbe_enabled && !(settings.frame_buffer & fb_useless_is_useless))
413 {
414 rdp.frame_buffers[rdp.ci_count-1].status = ci_aux;
415 rdp.frame_buffers[rdp.ci_count-1].changed = 0;
416 FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1);
417 }
418 else
419 {
420 rdp.frame_buffers[rdp.ci_count-1].status = ci_useless;
421 /*
422 wxUint32 addr = rdp.frame_buffers[rdp.ci_count-1].addr;
423 for (int i = 0; i < rdp.ci_count - 1; i++)
424 {
425 if (rdp.frame_buffers[i].addr == addr)
426 {
427 rdp.frame_buffers[rdp.ci_count-1].status = rdp.frame_buffers[i].status;
428 break;
429 }
430 }
431 //*/
432 FRDP("rdp.frame_buffers[%d].status = %s\n", rdp.ci_count-1, CIStatus[rdp.frame_buffers[rdp.ci_count-1].status]);
433 }
434 }
435 if (cur_fb.status == ci_main)
436 {
437 int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx.VI_ORIGIN_REG)) ? FALSE : TRUE;
438 if ((rdp.maincimg[0].addr != cur_fb.addr) && SwapOK && viSwapOK)
439 {
440 SwapOK = FALSE;
441 rdp.swap_ci_index = rdp.ci_count;
442 }
443 }
444 rdp.ci_count++;
445 if (rdp.ci_count > NUMTEXBUF) //overflow
446 rdp.halt = 1;
447}
448
449// RDP graphic instructions pointer table used in DetectFrameBufferUsage
450
451static rdp_instr gfx_instruction_lite[9][256] =
452{
453 {
454 // uCode 0 - RSP SW 2.0X
455 // 00-3f
456 // games: Super Mario 64, Tetrisphere, Demos
457 0, 0, 0, 0,
458 0, 0, uc0_displaylist, 0,
459 0, 0, 0, 0,
460 0, 0, 0, 0,
461 0, 0, 0, 0,
462 0, 0, 0, 0,
463 0, 0, 0, 0,
464 0, 0, 0, 0,
465 0, 0, 0, 0,
466 0, 0, 0, 0,
467 0, 0, 0, 0,
468 0, 0, 0, 0,
469 0, 0, 0, 0,
470 0, 0, 0, 0,
471 0, 0, 0, 0,
472 0, 0, 0, 0,
473 // 40-7f: Unused
474 0, 0, 0, 0,
475 0, 0, 0, 0,
476 0, 0, 0, 0,
477 0, 0, 0, 0,
478 0, 0, 0, 0,
479 0, 0, 0, 0,
480 0, 0, 0, 0,
481 0, 0, 0, 0,
482 0, 0, 0, 0,
483 0, 0, 0, 0,
484 0, 0, 0, 0,
485 0, 0, 0, 0,
486 0, 0, 0, 0,
487 0, 0, 0, 0,
488 0, 0, 0, 0,
489 0, 0, 0, 0,
490 // 80-bf: Immediate commands
491 0, 0, 0, 0,
492 0, 0, 0, 0,
493 0, 0, 0, 0,
494 0, 0, 0, 0,
495 0, 0, 0, 0,
496 0, 0, 0, 0,
497 0, 0, 0, 0,
498 0, 0, 0, 0,
499 0, 0, 0, 0,
500 0, 0, 0, 0,
501 0, 0, 0, 0,
502 0, 0, 0, 0,
503 0, 0, 0, 0,
504 0, 0, 0, 0,
505 uc0_enddl, 0, 0, 0,
506 fb_uc0_moveword, 0, uc0_culldl, 0,
507 // c0-ff: RDP commands
508 0, 0, 0, 0,
509 0, 0, 0, 0,
510 0, 0, 0, 0,
511 0, 0, 0, 0,
512 0, 0, 0, 0,
513 0, 0, 0, 0,
514 0, 0, 0, 0,
515 0, 0, 0, 0,
516 0, 0, 0, 0,
517 fb_rect, fb_rect, 0, 0,
518 0, 0, 0, 0,
519 0, fb_setscissor, 0, 0,
520 0, 0, 0, 0,
521 0, 0, fb_rect, 0,
522 0, 0, 0, 0,
523 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
524 },
525
526 // uCode 1 - F3DEX 1.XX
527 // 00-3f
528 // games: Mario Kart, Star Fox
529 {
530 0, 0, 0, 0,
531 0, 0, uc0_displaylist, 0,
532 0, 0, 0, 0,
533 0, 0, 0, 0,
534 0, 0, 0, 0,
535 0, 0, 0, 0,
536 0, 0, 0, 0,
537 0, 0, 0, 0,
538 0, 0, 0, 0,
539 0, 0, 0, 0,
540 0, 0, 0, 0,
541 0, 0, 0, 0,
542 0, 0, 0, 0,
543 0, 0, 0, 0,
544 0, 0, 0, 0,
545 0, 0, 0, 0,
546 // 40-7f: unused
547 0, 0, 0, 0,
548 0, 0, 0, 0,
549 0, 0, 0, 0,
550 0, 0, 0, 0,
551 0, 0, 0, 0,
552 0, 0, 0, 0,
553 0, 0, 0, 0,
554 0, 0, 0, 0,
555 0, 0, 0, 0,
556 0, 0, 0, 0,
557 0, 0, 0, 0,
558 0, 0, 0, 0,
559 0, 0, 0, 0,
560 0, 0, 0, 0,
561 0, 0, 0, 0,
562 0, 0, 0, 0,
563 // 80-bf: Immediate commands
564 0, 0, 0, 0,
565 0, 0, 0, 0,
566 0, 0, 0, 0,
567 0, 0, 0, 0,
568 0, 0, 0, 0,
569 0, 0, 0, 0,
570 0, 0, 0, 0,
571 0, 0, 0, 0,
572 0, 0, 0, 0,
573 0, 0, 0, 0,
574 0, 0, 0, 0,
575 0, 0, 0, uc6_loaducode,
576 uc1_branch_z, 0, 0, 0,
577 fb_rdphalf_1, 0, 0, 0,
578 uc0_enddl, 0, 0, 0,
579 fb_uc0_moveword, 0, uc2_culldl, 0,
580 // c0-ff: RDP commands
581 0, 0, 0, 0,
582 0, 0, 0, 0,
583 0, 0, 0, 0,
584 0, 0, 0, 0,
585 0, 0, 0, 0,
586 0, 0, 0, 0,
587 0, 0, 0, 0,
588 0, 0, 0, 0,
589 0, 0, 0, 0,
590 fb_rect, fb_rect, 0, 0,
591 0, 0, 0, 0,
592 0, fb_setscissor, 0, 0,
593 0, 0, 0, 0,
594 0, 0, fb_rect, 0,
595 0, 0, 0, 0,
596 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
597 },
598
599 // uCode 2 - F3DEX 2.XX
600 // games: Zelda 64
601 {
602 // 00-3f
603 0, 0, 0, uc2_culldl,
604 uc1_branch_z, 0, 0, 0,
605 0, fb_bg_copy, fb_bg_copy, 0,
606 0, 0, 0, 0,
607 0, 0, 0, 0,
608 0, 0, 0, 0,
609 0, 0, 0, 0,
610 0, 0, 0, 0,
611 0, 0, 0, 0,
612 0, 0, 0, 0,
613 0, 0, 0, 0,
614 0, 0, 0, 0,
615 0, 0, 0, 0,
616 0, 0, 0, 0,
617 0, 0, 0, 0,
618 0, 0, 0, 0,
619
620 // 40-7f: unused
621 0, 0, 0, 0,
622 0, 0, 0, 0,
623 0, 0, 0, 0,
624 0, 0, 0, 0,
625 0, 0, 0, 0,
626 0, 0, 0, 0,
627 0, 0, 0, 0,
628 0, 0, 0, 0,
629 0, 0, 0, 0,
630 0, 0, 0, 0,
631 0, 0, 0, 0,
632 0, 0, 0, 0,
633 0, 0, 0, 0,
634 0, 0, 0, 0,
635 0, 0, 0, 0,
636 0, 0, 0, 0,
637
638 // 80-bf: unused
639 0, 0, 0, 0,
640 0, 0, 0, 0,
641 0, 0, 0, 0,
642 0, 0, 0, 0,
643 0, 0, 0, 0,
644 0, 0, 0, 0,
645 0, 0, 0, 0,
646 0, 0, 0, 0,
647 0, 0, 0, 0,
648 0, 0, 0, 0,
649 0, 0, 0, 0,
650 0, 0, 0, 0,
651 0, 0, 0, 0,
652 0, 0, 0, 0,
653 0, 0, 0, 0,
654 0, 0, 0, 0,
655
656 // c0-ff: RDP commands mixed with uc2 commands
657 0, 0, 0, 0,
658 0, 0, 0, 0,
659 0, 0, 0, 0,
660 0, 0, 0, 0,
661 0, 0, 0, 0,
662 0, uc2_dlist_cnt, 0, 0,
663 0, 0, 0, fb_uc2_moveword,
664 fb_uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl,
665 0, fb_rdphalf_1, 0, 0,
666 fb_rect, fb_rect, 0, 0,
667 0, 0, 0, 0,
668 0, fb_setscissor, 0, 0,
669 0, 0, 0, 0,
670 0, 0, fb_rect, 0,
671 0, 0, 0, 0,
672 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
673 },
674
675 // uCode 3 - "RSP SW 2.0D", but not really
676 // 00-3f
677 // games: Wave Race
678 // ** Added by Gonetz **
679 {
680 0, 0, 0, 0,
681 0, 0, uc0_displaylist, 0,
682 0, 0, 0, 0,
683 0, 0, 0, 0,
684 0, 0, 0, 0,
685 0, 0, 0, 0,
686 0, 0, 0, 0,
687 0, 0, 0, 0,
688 0, 0, 0, 0,
689 0, 0, 0, 0,
690 0, 0, 0, 0,
691 0, 0, 0, 0,
692 0, 0, 0, 0,
693 0, 0, 0, 0,
694 0, 0, 0, 0,
695 0, 0, 0, 0,
696 // 40-7f: unused
697 0, 0, 0, 0,
698 0, 0, 0, 0,
699 0, 0, 0, 0,
700 0, 0, 0, 0,
701 0, 0, 0, 0,
702 0, 0, 0, 0,
703 0, 0, 0, 0,
704 0, 0, 0, 0,
705 0, 0, 0, 0,
706 0, 0, 0, 0,
707 0, 0, 0, 0,
708 0, 0, 0, 0,
709 0, 0, 0, 0,
710 0, 0, 0, 0,
711 0, 0, 0, 0,
712 0, 0, 0, 0,
713 // 80-bf: Immediate commands
714 0, 0, 0, 0,
715 0, 0, 0, 0,
716 0, 0, 0, 0,
717 0, 0, 0, 0,
718 0, 0, 0, 0,
719 0, 0, 0, 0,
720 0, 0, 0, 0,
721 0, 0, 0, 0,
722 0, 0, 0, 0,
723 0, 0, 0, 0,
724 0, 0, 0, 0,
725 0, 0, 0, 0,
726 0, 0, 0, 0,
727 0, 0, 0, 0,
728 uc0_enddl, 0, 0, 0,
729 fb_uc0_moveword, 0, uc0_culldl, 0,
730 // c0-ff: RDP commands
731 0, 0, 0, 0,
732 0, 0, 0, 0,
733 0, 0, 0, 0,
734 0, 0, 0, 0,
735 0, 0, 0, 0,
736 0, 0, 0, 0,
737 0, 0, 0, 0,
738 0, 0, 0, 0,
739 0, 0, 0, 0,
740 fb_rect, fb_rect, 0, 0,
741 0, 0, 0, 0,
742 0, fb_setscissor, 0, 0,
743 0, 0, 0, 0,
744 0, 0, fb_rect, 0,
745 0, 0, 0, 0,
746 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
747 },
748
749 {
750 // uCode 4 - RSP SW 2.0D EXT
751 // 00-3f
752 // games: Star Wars: Shadows of the Empire
753 0, 0, 0, 0,
754 0, 0, uc0_displaylist, 0,
755 0, 0, 0, 0,
756 0, 0, 0, 0,
757 0, 0, 0, 0,
758 0, 0, 0, 0,
759 0, 0, 0, 0,
760 0, 0, 0, 0,
761 0, 0, 0, 0,
762 0, 0, 0, 0,
763 0, 0, 0, 0,
764 0, 0, 0, 0,
765 0, 0, 0, 0,
766 0, 0, 0, 0,
767 0, 0, 0, 0,
768 0, 0, 0, 0,
769 // 40-7f: Unused
770 0, 0, 0, 0,
771 0, 0, 0, 0,
772 0, 0, 0, 0,
773 0, 0, 0, 0,
774 0, 0, 0, 0,
775 0, 0, 0, 0,
776 0, 0, 0, 0,
777 0, 0, 0, 0,
778 0, 0, 0, 0,
779 0, 0, 0, 0,
780 0, 0, 0, 0,
781 0, 0, 0, 0,
782 0, 0, 0, 0,
783 0, 0, 0, 0,
784 0, 0, 0, 0,
785 0, 0, 0, 0,
786 // 80-bf: Immediate commands
787 0, 0, 0, 0,
788 0, 0, 0, 0,
789 0, 0, 0, 0,
790 0, 0, 0, 0,
791 0, 0, 0, 0,
792 0, 0, 0, 0,
793 0, 0, 0, 0,
794 0, 0, 0, 0,
795 0, 0, 0, 0,
796 0, 0, 0, 0,
797 0, 0, 0, 0,
798 0, 0, 0, 0,
799 0, 0, 0, 0,
800 0, 0, 0, 0,
801 uc0_enddl, 0, 0, 0,
802 fb_uc0_moveword, 0, uc0_culldl, 0,
803 // c0-ff: RDP commands
804 rdp_noop, 0, 0, 0,
805 0, 0, 0, 0,
806 0, 0, 0, 0,
807 0, 0, 0, 0,
808 0, 0, 0, 0,
809 0, 0, 0, 0,
810 0, 0, 0, 0,
811 0, 0, 0, 0,
812 0, 0, 0, 0,
813 fb_rect, fb_rect, 0, 0,
814 0, 0, 0, 0,
815 0, fb_setscissor, 0, 0,
816 0, 0, 0, 0,
817 0, 0, fb_rect, 0,
818 0, 0, 0, 0,
819 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
820 },
821
822 {
823 // uCode 5 - RSP SW 2.0 Diddy
824 // 00-3f
825 // games: Diddy Kong Racing
826 0, 0, 0, 0,
827 0, 0, uc0_displaylist, uc5_dl_in_mem,
828 0, 0, 0, 0,
829 0, 0, 0, 0,
830 0, 0, 0, 0,
831 0, 0, 0, 0,
832 0, 0, 0, 0,
833 0, 0, 0, 0,
834 0, 0, 0, 0,
835 0, 0, 0, 0,
836 0, 0, 0, 0,
837 0, 0, 0, 0,
838 0, 0, 0, 0,
839 0, 0, 0, 0,
840 0, 0, 0, 0,
841 0, 0, 0, 0,
842 // 40-7f: Unused
843 0, 0, 0, 0,
844 0, 0, 0, 0,
845 0, 0, 0, 0,
846 0, 0, 0, 0,
847 0, 0, 0, 0,
848 0, 0, 0, 0,
849 0, 0, 0, 0,
850 0, 0, 0, 0,
851 0, 0, 0, 0,
852 0, 0, 0, 0,
853 0, 0, 0, 0,
854 0, 0, 0, 0,
855 0, 0, 0, 0,
856 0, 0, 0, 0,
857 0, 0, 0, 0,
858 0, 0, 0, 0,
859 // 80-bf: Immediate commands
860 0, 0, 0, 0,
861 0, 0, 0, 0,
862 0, 0, 0, 0,
863 0, 0, 0, 0,
864 0, 0, 0, 0,
865 0, 0, 0, 0,
866 0, 0, 0, 0,
867 0, 0, 0, 0,
868 0, 0, 0, 0,
869 0, 0, 0, 0,
870 0, 0, 0, 0,
871 0, 0, 0, 0,
872 0, 0, 0, 0,
873 0, 0, 0, 0,
874 uc0_enddl, 0, 0, 0,
875 fb_uc0_moveword, 0, uc0_culldl, 0,
876 // c0-ff: RDP commands
877 0, 0, 0, 0,
878 0, 0, 0, 0,
879 0, 0, 0, 0,
880 0, 0, 0, 0,
881 0, 0, 0, 0,
882 0, 0, 0, 0,
883 0, 0, 0, 0,
884 0, 0, 0, 0,
885 0, 0, 0, 0,
886 fb_rect, fb_rect, 0, 0,
887 0, 0, 0, 0,
888 0, fb_setscissor, 0, 0,
889 0, 0, 0, 0,
890 0, 0, fb_rect, 0,
891 0, 0, 0, 0,
892 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
893 },
894
895 // uCode 6 - S2DEX 1.XX
896 // games: Yoshi's Story
897 {
898 0, 0, 0, 0,
899 0, 0, uc0_displaylist, 0,
900 0, 0, 0, 0,
901 0, 0, 0, 0,
902 0, 0, 0, 0,
903 0, 0, 0, 0,
904 0, 0, 0, 0,
905 0, 0, 0, 0,
906 0, 0, 0, 0,
907 0, 0, 0, 0,
908 0, 0, 0, 0,
909 0, 0, 0, 0,
910 0, 0, 0, 0,
911 0, 0, 0, 0,
912 0, 0, 0, 0,
913 0, 0, 0, 0,
914 // 40-7f: unused
915 0, 0, 0, 0,
916 0, 0, 0, 0,
917 0, 0, 0, 0,
918 0, 0, 0, 0,
919 0, 0, 0, 0,
920 0, 0, 0, 0,
921 0, 0, 0, 0,
922 0, 0, 0, 0,
923 0, 0, 0, 0,
924 0, 0, 0, 0,
925 0, 0, 0, 0,
926 0, 0, 0, 0,
927 0, 0, 0, 0,
928 0, 0, 0, 0,
929 0, 0, 0, 0,
930 0, 0, 0, 0,
931 // 80-bf: Immediate commands
932 0, 0, 0, 0,
933 0, 0, 0, 0,
934 0, 0, 0, 0,
935 0, 0, 0, 0,
936 0, 0, 0, 0,
937 0, 0, 0, 0,
938 0, 0, 0, 0,
939 0, 0, 0, 0,
940 0, 0, 0, 0,
941 0, 0, 0, 0,
942 0, 0, 0, 0,
943 0, 0, 0, uc6_loaducode,
944 uc6_select_dl, 0, 0, 0,
945 0, 0, 0, 0,
946 uc0_enddl, 0, 0, 0,
947 fb_uc0_moveword, 0, uc2_culldl, 0,
948 // c0-ff: RDP commands
949 0, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr,
950 fb_loadtxtr, 0, 0, 0,
951 0, 0, 0, 0,
952 0, 0, 0, 0,
953 0, 0, 0, 0,
954 0, 0, 0, 0,
955 0, 0, 0, 0,
956 0, 0, 0, 0,
957 0, 0, 0, 0,
958 fb_rect, fb_rect, 0, 0,
959 0, 0, 0, 0,
960 0, fb_setscissor, 0, 0,
961 0, 0, 0, 0,
962 0, 0, fb_rect, 0,
963 0, 0, 0, 0,
964 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
965 },
966
967 {
968 0, 0, 0, 0,
969 0, 0, uc0_displaylist, 0,
970 0, 0, 0, 0,
971 0, 0, 0, 0,
972 0, 0, 0, 0,
973 0, 0, 0, 0,
974 0, 0, 0, 0,
975 0, 0, 0, 0,
976 0, 0, 0, 0,
977 0, 0, 0, 0,
978 0, 0, 0, 0,
979 0, 0, 0, 0,
980 0, 0, 0, 0,
981 0, 0, 0, 0,
982 0, 0, 0, 0,
983 0, 0, 0, 0,
984 // 40-7f: unused
985 0, 0, 0, 0,
986 0, 0, 0, 0,
987 0, 0, 0, 0,
988 0, 0, 0, 0,
989 0, 0, 0, 0,
990 0, 0, 0, 0,
991 0, 0, 0, 0,
992 0, 0, 0, 0,
993 0, 0, 0, 0,
994 0, 0, 0, 0,
995 0, 0, 0, 0,
996 0, 0, 0, 0,
997 0, 0, 0, 0,
998 0, 0, 0, 0,
999 0, 0, 0, 0,
1000 0, 0, 0, 0,
1001 // 80-bf: Immediate commands
1002 0, 0, 0, 0,
1003 0, 0, 0, 0,
1004 0, 0, 0, 0,
1005 0, 0, 0, 0,
1006 0, 0, 0, 0,
1007 0, 0, 0, 0,
1008 0, 0, 0, 0,
1009 0, 0, 0, 0,
1010 0, 0, 0, 0,
1011 0, 0, 0, 0,
1012 0, 0, 0, 0,
1013 0, 0, 0, 0,
1014 0, 0, 0, 0,
1015 0, 0, 0, 0,
1016 uc0_enddl, 0, 0, 0,
1017 fb_uc0_moveword, 0, uc0_culldl, 0,
1018 // c0-ff: RDP commands
1019 0, 0, 0, 0,
1020 0, 0, 0, 0,
1021 0, 0, 0, 0,
1022 0, 0, 0, 0,
1023 0, 0, 0, 0,
1024 0, 0, 0, 0,
1025 0, 0, 0, 0,
1026 0, 0, 0, 0,
1027 0, 0, 0, 0,
1028 fb_rect, fb_rect, 0, 0,
1029 0, 0, 0, 0,
1030 0, fb_setscissor, 0, 0,
1031 0, 0, 0, 0,
1032 0, 0, fb_rect, 0,
1033 0, 0, 0, 0,
1034 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
1035 },
1036
1037 {
1038 // 00-3f
1039 0, 0, 0, uc2_culldl,
1040 uc1_branch_z, 0, 0, 0,
1041 0, fb_bg_copy, fb_bg_copy, 0,
1042 0, 0, 0, 0,
1043 0, 0, 0, 0,
1044 0, 0, 0, 0,
1045 0, 0, 0, 0,
1046 0, 0, 0, 0,
1047 0, 0, 0, 0,
1048 0, 0, 0, 0,
1049 0, 0, 0, 0,
1050 0, 0, 0, 0,
1051 0, 0, 0, 0,
1052 0, 0, 0, 0,
1053 0, 0, 0, 0,
1054 0, 0, 0, 0,
1055
1056 // 40-7f: unused
1057 0, 0, 0, 0,
1058 0, 0, 0, 0,
1059 0, 0, 0, 0,
1060 0, 0, 0, 0,
1061 0, 0, 0, 0,
1062 0, 0, 0, 0,
1063 0, 0, 0, 0,
1064 0, 0, 0, 0,
1065 0, 0, 0, 0,
1066 0, 0, 0, 0,
1067 0, 0, 0, 0,
1068 0, 0, 0, 0,
1069 0, 0, 0, 0,
1070 0, 0, 0, 0,
1071 0, 0, 0, 0,
1072 0, 0, 0, 0,
1073
1074 // 80-bf: unused
1075 0, 0, 0, 0,
1076 0, 0, 0, 0,
1077 0, 0, 0, 0,
1078 0, 0, 0, 0,
1079 0, 0, 0, 0,
1080 0, 0, 0, 0,
1081 0, 0, 0, 0,
1082 0, 0, 0, 0,
1083 0, 0, 0, 0,
1084 0, 0, 0, 0,
1085 0, 0, 0, 0,
1086 0, 0, 0, 0,
1087 0, 0, 0, 0,
1088 0, 0, 0, 0,
1089 0, 0, 0, 0,
1090 0, 0, 0, 0,
1091
1092 // c0-ff: RDP commands mixed with uc2 commands
1093 0, 0, 0, 0,
1094 0, 0, 0, 0,
1095 0, 0, 0, 0,
1096 0, 0, 0, 0,
1097 0, 0, 0, 0,
1098 0, uc2_dlist_cnt, 0, 0,
1099 0, 0, 0, fb_uc2_moveword,
1100 0, uc2_load_ucode, uc0_displaylist, uc0_enddl,
1101 0, 0, 0, 0,
1102 fb_rect, fb_rect, 0, 0,
1103 0, 0, 0, 0,
1104 0, fb_setscissor, 0, 0,
1105 0, 0, 0, 0,
1106 0, 0, fb_rect, 0,
1107 0, 0, 0, 0,
1108 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage
1109 }
1110};