X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fgles2glide64%2Fsrc%2FGlide64%2Fucode09.h;fp=source%2Fgles2glide64%2Fsrc%2FGlide64%2Fucode09.h;h=69a4a82d3a7f991d7ca31ef01db20994c866c8ca;hb=98e75f2d18c02c233da543560f76282f04fc796c;hp=0000000000000000000000000000000000000000;hpb=0ced54f867d36e8b324155bef49e8abfebfc3237;p=mupen64plus-pandora.git diff --git a/source/gles2glide64/src/Glide64/ucode09.h b/source/gles2glide64/src/Glide64/ucode09.h new file mode 100755 index 0000000..69a4a82 --- /dev/null +++ b/source/gles2glide64/src/Glide64/ucode09.h @@ -0,0 +1,690 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * 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. +// * 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. +// +//**************************************************************** +// +// December 2008 Created by Gonetz (Gonetz@ngs.ru) +// +//**************************************************************** + +void uc9_rpdcmd (); + +typedef float M44[4][4]; + +struct ZSORTRDP { + float view_scale[2]; + float view_trans[2]; + float scale_x; + float scale_y; +} zSortRdp = {{0, 0}, {0, 0}, 0, 0}; + +//RSP command VRCPL +static int Calc_invw (int w) { + int count, neg; + union { + wxInt32 W; + wxUint32 UW; + wxInt16 HW[2]; + wxUint16 UHW[2]; + } Result; + Result.W = w; + if (Result.UW == 0) { + Result.UW = 0x7FFFFFFF; + } else { + if (Result.W < 0) { + neg = TRUE; + if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) { + Result.W = ~Result.W + 1; + } else { + Result.W = ~Result.W; + } + } else { + neg = FALSE; + } + for (count = 31; count > 0; count--) { + if ((Result.W & (1 << count))) { + Result.W &= (0xFFC00000 >> (31 - count) ); + count = 0; + } + } + Result.W = 0x7FFFFFFF / Result.W; + for (count = 31; count > 0; count--) { + if ((Result.W & (1 << count))) { + Result.W &= (0xFFFF8000 >> (31 - count) ); + count = 0; + } + } + if (neg == TRUE) { + Result.W = ~Result.W; + } + } + return Result.W; +} + +static void uc9_draw_object (wxUint8 * addr, wxUint32 type) +{ +Check_FrameSkip; + + wxUint32 textured, vnum, vsize; + switch (type) { + case 1: //sh tri + textured = 0; + vnum = 3; + vsize = 8; + break; + case 2: //tx tri + textured = 1; + vnum = 3; + vsize = 16; + break; + case 3: //sh quad + textured = 0; + vnum = 4; + vsize = 8; + break; + case 4: //tx quad + textured = 1; + vnum = 4; + vsize = 16; + break; + case 0: //null + default: + textured = vnum = vsize = 0; + break; + } + VERTEX vtx[4]; + for (wxUint32 i = 0; i < vnum; i++) + { + VERTEX &v = vtx[i]; + v.sx = zSortRdp.scale_x * ((short*)addr)[0^1]; + v.sy = zSortRdp.scale_y * ((short*)addr)[1^1]; + v.sz = 1.0f; + v.r = addr[4^3]; + v.g = addr[5^3]; + v.b = addr[6^3]; + v.a = addr[7^3]; + v.flags = 0; + v.uv_scaled = 0; + v.uv_calculated = 0xFFFFFFFF; + v.shade_mod = 0; + v.scr_off = 0; + v.screen_translated = 2; + if (textured) + { + v.ou = ((short*)addr)[4^1]; + v.ov = ((short*)addr)[5^1]; + v.w = Calc_invw(((int*)addr)[3]) / 31.0f; + v.oow = 1.0f / v.w; + 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); + } + else + { + v.oow = v.w = 1.0f; + 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); + } + addr += vsize; + } + //* + VERTEX *pV[4] = { + &vtx[0], + &vtx[1], + &vtx[2], + &vtx[3] + }; + if (vnum == 3) + { + FRDP("uc9:Tri #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + draw_tri (pV, 0); + rdp.tri_n ++; + } + else + { + FRDP("uc9:Quad #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + draw_tri (pV, 0); + draw_tri (pV+1, 0); + rdp.tri_n += 2; + } +} + +static wxUint32 uc9_load_object (wxUint32 zHeader, wxUint32 * rdpcmds) +{ + wxUint32 type = zHeader & 7; + wxUint8 * addr = gfx.RDRAM + (zHeader&0xFFFFFFF8); + switch (type) { + case 1: //sh tri + case 3: //sh quad + { + rdp.cmd1 = ((wxUint32*)addr)[1]; + if (rdp.cmd1 != rdpcmds[0]) + { + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd (); + } + update (); + uc9_draw_object(addr + 8, type); + } + break; + case 0: //null + case 2: //tx tri + case 4: //tx quad + { + rdp.cmd1 = ((wxUint32*)addr)[1]; + if (rdp.cmd1 != rdpcmds[0]) + { + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd (); + } + rdp.cmd1 = ((wxUint32*)addr)[2]; + if (rdp.cmd1 != rdpcmds[1]) + { + uc9_rpdcmd (); + rdpcmds[1] = rdp.cmd1; + } + rdp.cmd1 = ((wxUint32*)addr)[3]; + if (rdp.cmd1 != rdpcmds[2]) + { + uc9_rpdcmd (); + rdpcmds[2] = rdp.cmd1; + } + if (type) + { + update (); + uc9_draw_object(addr + 16, type); + } + } + break; + } + return segoffset(((wxUint32*)addr)[0]); +} + +static void uc9_object () +{ + LRDP("uc9:object\n"); + wxUint32 rdpcmds[3] = {0, 0, 0}; + wxUint32 cmd1 = rdp.cmd1; + wxUint32 zHeader = segoffset(rdp.cmd0); + while (zHeader) + zHeader = uc9_load_object(zHeader, rdpcmds); + zHeader = segoffset(cmd1); + while (zHeader) + zHeader = uc9_load_object(zHeader, rdpcmds); +} + +static void uc9_mix () +{ + LRDP("uc9:mix IGNORED\n"); +} + +static void uc9_fmlight () +{ + int mid = rdp.cmd0&0xFF; + rdp.num_lights = 1 + ((rdp.cmd1>>12)&0xFF); + wxUint32 a = -1024 + (rdp.cmd1&0xFFF); + FRDP ("uc9:fmlight matrix: %d, num: %d, dmem: %04lx\n", mid, rdp.num_lights, a); + + M44 *m = NULL; + switch (mid) { + case 4: + m = (M44*)rdp.model; + break; + case 6: + m = (M44*)rdp.proj; + break; + case 8: + m = (M44*)rdp.combined; + break; + } + + rdp.light[rdp.num_lights].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f; + rdp.light[rdp.num_lights].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f; + rdp.light[rdp.num_lights].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f; + rdp.light[rdp.num_lights].a = 1.0f; + 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); + a += 8; + wxUint32 i; + for (i = 0; i < rdp.num_lights; i++) + { + rdp.light[i].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f; + rdp.light[i].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f; + rdp.light[i].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f; + rdp.light[i].a = 1.0f; + rdp.light[i].dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f; + rdp.light[i].dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f; + rdp.light[i].dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f; + FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n", + i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b, + rdp.light[i].dir_x, rdp.light[i].dir_y, rdp.light[i].dir_z); +// TransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m); + InverseTransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m); + NormalizeVector (rdp.light_vector[i]); + FRDP ("light vector: n: %d, x: %.3f, y: %.3f, z: %.3f\n", + i, rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); + a += 24; + } + for (i = 0; i < 2; i++) + { + float dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f; + float dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f; + float dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f; + if (sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) < 0.98) + { + rdp.use_lookat = FALSE; + return; + } + rdp.lookat[i][0] = dir_x; + rdp.lookat[i][1] = dir_y; + rdp.lookat[i][2] = dir_z; + a += 24; + } + rdp.use_lookat = TRUE; +} + +static void uc9_light () +{ + wxUint32 csrs = -1024 + ((rdp.cmd0>>12)&0xFFF); + wxUint32 nsrs = -1024 + (rdp.cmd0&0xFFF); + wxUint32 num = 1 + ((rdp.cmd1>>24)&0xFF); + wxUint32 cdest = -1024 + ((rdp.cmd1>>12)&0xFFF); + wxUint32 tdest = -1024 + (rdp.cmd1&0xFFF); + int use_material = (csrs != 0x0ff0); + tdest >>= 1; + FRDP ("uc9:light n: %d, colsrs: %04lx, normales: %04lx, coldst: %04lx, texdst: %04lx\n", num, csrs, nsrs, cdest, tdest); + VERTEX v; + for (wxUint32 i = 0; i < num; i++) + { + v.vec[0] = ((char*)gfx.DMEM)[(nsrs++)^3]; + v.vec[1] = ((char*)gfx.DMEM)[(nsrs++)^3]; + v.vec[2] = ((char*)gfx.DMEM)[(nsrs++)^3]; + calc_sphere (&v); +// calc_linear (&v); + NormalizeVector (v.vec); + calc_light (&v); + v.a = 0xFF; + if (use_material) + { + v.r = (wxUint8)(((wxUint32)v.r * gfx.DMEM[(csrs++)^3])>>8); + v.g = (wxUint8)(((wxUint32)v.g * gfx.DMEM[(csrs++)^3])>>8); + v.b = (wxUint8)(((wxUint32)v.b * gfx.DMEM[(csrs++)^3])>>8); + v.a = gfx.DMEM[(csrs++)^3]; + } + gfx.DMEM[(cdest++)^3] = v.r; + gfx.DMEM[(cdest++)^3] = v.g; + gfx.DMEM[(cdest++)^3] = v.b; + gfx.DMEM[(cdest++)^3] = v.a; + ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ou; + ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ov; + } +} + +static void uc9_mtxtrnsp () +{ + LRDP("uc9:mtxtrnsp - ignored\n"); + /* + LRDP("uc9:mtxtrnsp "); + M44 *s; + switch (rdp.cmd1&0xF) { + case 4: + s = (M44*)rdp.model; + LRDP("Model\n"); + break; + case 6: + s = (M44*)rdp.proj; + LRDP("Proj\n"); + break; + case 8: + s = (M44*)rdp.combined; + LRDP("Comb\n"); + break; + } + float m = *s[1][0]; + *s[1][0] = *s[0][1]; + *s[0][1] = m; + m = *s[2][0]; + *s[2][0] = *s[0][2]; + *s[0][2] = m; + m = *s[2][1]; + *s[2][1] = *s[1][2]; + *s[1][2] = m; + */ +} + +static void uc9_mtxcat () +{ + LRDP("uc9:mtxcat "); + M44 *s = NULL; + M44 *t = NULL; + wxUint32 S = rdp.cmd0&0xF; + wxUint32 T = (rdp.cmd1>>16)&0xF; + wxUint32 D = rdp.cmd1&0xF; + switch (S) { + case 4: + s = (M44*)rdp.model; + LRDP("Model * "); + break; + case 6: + s = (M44*)rdp.proj; + LRDP("Proj * "); + break; + case 8: + s = (M44*)rdp.combined; + LRDP("Comb * "); + break; + } + switch (T) { + case 4: + t = (M44*)rdp.model; + LRDP("Model -> "); + break; + case 6: + t = (M44*)rdp.proj; + LRDP("Proj -> "); + break; + case 8: + LRDP("Comb -> "); + t = (M44*)rdp.combined; + break; + } + DECLAREALIGN16VAR(m[4][4]); + MulMatrices(*s, *t, m); + + switch (D) { + case 4: + memcpy (rdp.model, m, 64);; + LRDP("Model\n"); + break; + case 6: + memcpy (rdp.proj, m, 64);; + LRDP("Proj\n"); + break; + case 8: + memcpy (rdp.combined, m, 64);; + LRDP("Comb\n"); + break; + } +#ifdef EXTREME_LOGGING + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); + FRDP ("\ncombined\n{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); +#endif +} + +typedef struct { + short sy; + short sx; + int invw; + short yi; + short xi; + short wi; + wxUint8 fog; + wxUint8 cc; +} zSortVDest; + +static void uc9_mult_mpmtx () +{ + //int id = rdp.cmd0&0xFF; + int num = 1+ ((rdp.cmd1>>24)&0xFF); + int src = -1024 + ((rdp.cmd1>>12)&0xFFF); + int dst = -1024 + (rdp.cmd1&0xFFF); + FRDP ("uc9:mult_mpmtx from: %04lx to: %04lx n: %d\n", src, dst, num); + short * saddr = (short*)(gfx.DMEM+src); + zSortVDest * daddr = (zSortVDest*)(gfx.DMEM+dst); + int idx = 0; + zSortVDest v; + memset(&v, 0, sizeof(zSortVDest)); + //float scale_x = 4.0f/rdp.scale_x; + //float scale_y = 4.0f/rdp.scale_y; + for (int i = 0; i < num; i++) + { + short sx = saddr[(idx++)^1]; + short sy = saddr[(idx++)^1]; + short sz = saddr[(idx++)^1]; + float x = sx*rdp.combined[0][0] + sy*rdp.combined[1][0] + sz*rdp.combined[2][0] + rdp.combined[3][0]; + float y = sx*rdp.combined[0][1] + sy*rdp.combined[1][1] + sz*rdp.combined[2][1] + rdp.combined[3][1]; + float z = sx*rdp.combined[0][2] + sy*rdp.combined[1][2] + sz*rdp.combined[2][2] + rdp.combined[3][2]; + float w = sx*rdp.combined[0][3] + sy*rdp.combined[1][3] + sz*rdp.combined[2][3] + rdp.combined[3][3]; + v.sx = (short)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]); + v.sy = (short)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]); + + v.xi = (short)x; + v.yi = (short)y; + v.wi = (short)w; + v.invw = Calc_invw((int)(w * 31.0)); + + if (w < 0.0f) + v.fog = 0; + else + { + int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset); + if (fog > 255) + fog = 255; + v.fog = (fog >= 0) ? (wxUint8)fog : 0; + } + + v.cc = 0; + if (x < -w) v.cc |= 0x10; + if (x > w) v.cc |= 0x01; + if (y < -w) v.cc |= 0x20; + if (y > w) v.cc |= 0x02; + if (w < 0.1f) v.cc |= 0x04; + + daddr[i] = v; + //memcpy(gfx.DMEM+dst+sizeof(zSortVDest)*i, &v, sizeof(zSortVDest)); +// 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); + 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); + } +} + +static void uc9_link_subdl () +{ + LRDP("uc9:link_subdl IGNORED\n"); +} + +static void uc9_set_subdl () +{ + LRDP("uc9:set_subdl IGNORED\n"); +} + +static void uc9_wait_signal () +{ + LRDP("uc9:wait_signal IGNORED\n"); +} + +static void uc9_send_signal () +{ + LRDP("uc9:send_signal IGNORED\n"); +} + +void uc9_movemem () +{ + LRDP("uc9:movemem\n"); + int idx = rdp.cmd0 & 0x0E; + int ofs = ((rdp.cmd0>>6)&0x1ff)<<3; + int len = (1 + ((rdp.cmd0>>15)&0x1ff))<<3; + FRDP ("uc9:movemem ofs: %d, len: %d. ", ofs, len); + int flag = rdp.cmd0 & 0x01; + wxUint32 addr = segoffset(rdp.cmd1); + switch (idx) + { + + case 0: //save/load + if (flag == 0) + { + int dmem_addr = (idx<<3) + ofs; + FRDP ("Load to DMEM. %08lx -> %08lx\n", addr, dmem_addr); + memcpy(gfx.DMEM + dmem_addr, gfx.RDRAM + addr, len); + } + else + { + int dmem_addr = (idx<<3) + ofs; + FRDP ("Load from DMEM. %08lx -> %08lx\n", dmem_addr, addr); + memcpy(gfx.RDRAM + addr, gfx.DMEM + dmem_addr, len); + } + break; + + case 4: // model matrix + case 6: // projection matrix + case 8: // combined matrix + { + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); + switch (idx) + { + case 4: // model matrix + LRDP("Modelview load\n"); + modelview_load (m); + break; + case 6: // projection matrix + LRDP("Projection load\n"); + projection_load (m); + break; + case 8: // projection matrix + LRDP("Combined load\n"); + rdp.update &= ~UPDATE_MULT_MAT; + memcpy (rdp.combined, m, 64);; + break; + } +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]); + FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]); + FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]); + FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]); + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); +#endif + } + break; + + case 10: + LRDP("Othermode - IGNORED\n"); + break; + + case 12: // VIEWPORT + { + wxUint32 a = addr >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; + short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; + rdp.fog_multiplier = ((short*)gfx.RDRAM)[(a+3)^1]; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; + short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; + rdp.fog_offset = ((short*)gfx.RDRAM)[(a+7)^1]; + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + zSortRdp.view_scale[0] = (float)(scale_x*4); + zSortRdp.view_scale[1] = (float)(scale_y*4); + zSortRdp.view_trans[0] = (float)(trans_x*4); + zSortRdp.view_trans[1] = (float)(trans_y*4); + zSortRdp.scale_x = rdp.scale_x / 4.0f; + zSortRdp.scale_y = rdp.scale_y / 4.0f; + + rdp.update |= UPDATE_VIEWPORT; + + rdp.mipmap_level = 0; + rdp.cur_tile = 0; + TILE *tmp_tile = &rdp.tiles[0]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = 0xFFFF; + tmp_tile->org_t_scale = 0xFFFF; + tmp_tile->s_scale = 0.031250f; + tmp_tile->t_scale = 0.031250f; + + rdp.geom_mode |= 0x0200; + + FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z, a); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + } + break; + + default: + FRDP ("** UNKNOWN %d\n", idx); + } + +} + +static void uc9_setscissor() +{ + rdp_setscissor(); + + if ((rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0])) + { + float w = (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) / 2.0f; + float h = (rdp.scissor_o.lr_y - rdp.scissor_o.ul_y) / 2.0f; + rdp.view_scale[0] = w * rdp.scale_x; + rdp.view_scale[1] = h * rdp.scale_y; + rdp.view_trans[0] = w * rdp.scale_x; + rdp.view_trans[1] = h * rdp.scale_y; + zSortRdp.view_scale[0] = w * 4.0f; + zSortRdp.view_scale[1] = h * 4.0f; + zSortRdp.view_trans[0] = w * 4.0f; + zSortRdp.view_trans[1] = h * 4.0f; + zSortRdp.scale_x = rdp.scale_x / 4.0f; + zSortRdp.scale_y = rdp.scale_y / 4.0f; + rdp.update |= UPDATE_VIEWPORT; + + rdp.mipmap_level = 0; + rdp.cur_tile = 0; + TILE *tmp_tile = &rdp.tiles[0]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = 0xFFFF; + tmp_tile->org_t_scale = 0xFFFF; + tmp_tile->s_scale = 0.031250f; + tmp_tile->t_scale = 0.031250f; + + rdp.geom_mode |= 0x0200; + } +}