diff --git a/Source/Glide64/turbo3D.h b/Source/Glide64/turbo3D.h index 3ed6daf62..36d378145 100644 --- a/Source/Glide64/turbo3D.h +++ b/Source/Glide64/turbo3D.h @@ -44,22 +44,22 @@ /******************Turbo3D microcode*************************/ struct t3dGlobState { - uint16_t pad0; - uint16_t perspNorm; - uint32_t flag; - uint32_t othermode0; - uint32_t othermode1; - uint32_t segBases[16]; - /* the viewport to use */ - short vsacle1; - short vsacle0; - short vsacle3; - short vsacle2; - short vtrans1; - short vtrans0; - short vtrans3; - short vtrans2; - uint32_t rdpCmds; + uint16_t pad0; + uint16_t perspNorm; + uint32_t flag; + uint32_t othermode0; + uint32_t othermode1; + uint32_t segBases[16]; + /* the viewport to use */ + short vsacle1; + short vsacle0; + short vsacle3; + short vsacle2; + short vtrans1; + short vtrans0; + short vtrans3; + short vtrans2; + uint32_t rdpCmds; }; struct t3dState { @@ -74,65 +74,63 @@ struct t3dState { uint32_t othermode1; }; - struct t3dTriN{ - uint8_t flag, v2, v1, v0; /* flag is which one for flat shade */ + uint8_t flag, v2, v1, v0; /* flag is which one for flat shade */ }; - static void t3dProcessRDP(uint32_t a) { - if (a) - { - rdp.LLE = 1; - rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; - rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; - while (rdp.cmd0 + rdp.cmd1) { - gfx_instruction[0][rdp.cmd0>>24] (); - rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; - rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; - uint32_t cmd = rdp.cmd0>>24; - if (cmd == 0xE4 || cmd == 0xE5) - { - rdp.cmd2 = ((uint32_t*)gfx.RDRAM)[a++]; - rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a++]; - } + if (a) + { + rdp.LLE = 1; + rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; + rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; + while (rdp.cmd0 + rdp.cmd1) { + gfx_instruction[0][rdp.cmd0 >> 24](); + rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; + rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; + uint32_t cmd = rdp.cmd0 >> 24; + if (cmd == 0xE4 || cmd == 0xE5) + { + rdp.cmd2 = ((uint32_t*)gfx.RDRAM)[a++]; + rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a++]; + } + } + rdp.LLE = 0; } - rdp.LLE = 0; - } } static void t3dLoadGlobState(uint32_t pgstate) { - t3dGlobState *gstate = (t3dGlobState*)&gfx.RDRAM[segoffset(pgstate)]; - FRDP ("Global state. pad0: %04lx, perspNorm: %04lx, flag: %08lx\n", gstate->pad0, gstate->perspNorm, gstate->flag); - rdp.cmd0 = gstate->othermode0; - rdp.cmd1 = gstate->othermode1; - rdp_setothermode(); + t3dGlobState *gstate = (t3dGlobState*)&gfx.RDRAM[segoffset(pgstate)]; + FRDP("Global state. pad0: %04lx, perspNorm: %04lx, flag: %08lx\n", gstate->pad0, gstate->perspNorm, gstate->flag); + rdp.cmd0 = gstate->othermode0; + rdp.cmd1 = gstate->othermode1; + rdp_setothermode(); - for (int s = 0; s < 16; s++) - { - rdp.segment[s] = gstate->segBases[s]; - FRDP ("segment: %08lx -> seg%d\n", rdp.segment[s], s); - } + for (int s = 0; s < 16; s++) + { + rdp.segment[s] = gstate->segBases[s]; + FRDP("segment: %08lx -> seg%d\n", rdp.segment[s], s); + } - short scale_x = gstate->vsacle0 / 4; - short scale_y = gstate->vsacle1 / 4;; - short scale_z = gstate->vsacle2; - short trans_x = gstate->vtrans0 / 4; - short trans_y = gstate->vtrans1 / 4; - short trans_z = gstate->vtrans2; - 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; - rdp.update |= UPDATE_VIEWPORT; - FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d)\n", scale_x, scale_y, scale_z, - trans_x, trans_y, trans_z); + short scale_x = gstate->vsacle0 / 4; + short scale_y = gstate->vsacle1 / 4;; + short scale_z = gstate->vsacle2; + short trans_x = gstate->vtrans0 / 4; + short trans_y = gstate->vtrans1 / 4; + short trans_z = gstate->vtrans2; + 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; + rdp.update |= UPDATE_VIEWPORT; + FRDP("viewport scale(%d, %d, %d), trans(%d, %d, %d)\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z); - t3dProcessRDP(segoffset(gstate->rdpCmds) >> 2); + t3dProcessRDP(segoffset(gstate->rdpCmds) >> 2); } static void t3d_vertex(uint32_t addr, uint32_t v0, uint32_t n) @@ -143,134 +141,134 @@ static void t3d_vertex(uint32_t addr, uint32_t v0, uint32_t n) rdp.vn = n; // Number of vertices to copy n <<= 4; - for (uint32_t i=0; i < n; i+=16) + for (uint32_t i = 0; i < n; i += 16) { - VERTEX *v = &rdp.vtx[v0 + (i>>4)]; - x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; - y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; - z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; - v->flags = ((uint16_t*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; - v->ou = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; - v->ov = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; - v->uv_scaled = 0; - v->r = ((uint8_t*)gfx.RDRAM)[(addr+i + 12)^3]; - v->g = ((uint8_t*)gfx.RDRAM)[(addr+i + 13)^3]; - v->b = ((uint8_t*)gfx.RDRAM)[(addr+i + 14)^3]; - v->a = ((uint8_t*)gfx.RDRAM)[(addr+i + 15)^3]; + VERTEX *v = &rdp.vtx[v0 + (i >> 4)]; + x = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 0) ^ 1]; + y = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 1) ^ 1]; + z = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 2) ^ 1]; + v->flags = ((uint16_t*)gfx.RDRAM)[(((addr + i) >> 1) + 3) ^ 1]; + v->ou = 2.0f * (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 4) ^ 1]; + v->ov = 2.0f * (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 5) ^ 1]; + v->uv_scaled = 0; + v->r = ((uint8_t*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->g = ((uint8_t*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->b = ((uint8_t*)gfx.RDRAM)[(addr + i + 14) ^ 3]; + v->a = ((uint8_t*)gfx.RDRAM)[(addr + i + 15) ^ 3]; - v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; - v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; - v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; - v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; - if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - v->shade_mod = 0; + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; #ifdef EXTREME_LOGGING - FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); #endif } } static void t3dLoadObject(uint32_t pstate, uint32_t pvtx, uint32_t ptri) { - LRDP("Loading Turbo3D object\n"); - t3dState *ostate = (t3dState*)&gfx.RDRAM[segoffset(pstate)]; - rdp.cur_tile = (ostate->textureState)&7; - FRDP("tile: %d\n", rdp.cur_tile); - if (rdp.tiles[rdp.cur_tile].s_scale < 0.001f) - rdp.tiles[rdp.cur_tile].s_scale = 0.015625; - if (rdp.tiles[rdp.cur_tile].t_scale < 0.001f) - rdp.tiles[rdp.cur_tile].t_scale = 0.015625; + LRDP("Loading Turbo3D object\n"); + t3dState *ostate = (t3dState*)&gfx.RDRAM[segoffset(pstate)]; + rdp.cur_tile = (ostate->textureState) & 7; + FRDP("tile: %d\n", rdp.cur_tile); + if (rdp.tiles[rdp.cur_tile].s_scale < 0.001f) + rdp.tiles[rdp.cur_tile].s_scale = 0.015625; + if (rdp.tiles[rdp.cur_tile].t_scale < 0.001f) + rdp.tiles[rdp.cur_tile].t_scale = 0.015625; #ifdef EXTREME_LOGGING - FRDP("renderState: %08lx, textureState: %08lx, othermode0: %08lx, othermode1: %08lx, rdpCmds: %08lx, triCount : %d, v0: %d, vn: %d\n", ostate->renderState, ostate->textureState, - ostate->othermode0, ostate->othermode1, ostate->rdpCmds, ostate->triCount, ostate->vtxV0, ostate->vtxCount); + FRDP("renderState: %08lx, textureState: %08lx, othermode0: %08lx, othermode1: %08lx, rdpCmds: %08lx, triCount : %d, v0: %d, vn: %d\n", ostate->renderState, ostate->textureState, + ostate->othermode0, ostate->othermode1, ostate->rdpCmds, ostate->triCount, ostate->vtxV0, ostate->vtxCount); #endif - rdp.cmd0 = ostate->othermode0; - rdp.cmd1 = ostate->othermode1; - rdp_setothermode(); + rdp.cmd0 = ostate->othermode0; + rdp.cmd1 = ostate->othermode1; + rdp_setothermode(); - rdp.cmd1 = ostate->renderState; - uc0_setgeometrymode(); + rdp.cmd1 = ostate->renderState; + uc0_setgeometrymode(); - if (!(ostate->flag&1)) //load matrix - { - uint32_t addr = segoffset(pstate+sizeof(t3dState)) & BMASK; - load_matrix(rdp.combined, addr); -#ifdef EXTREME_LOGGING - FRDP ("{%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 - } - - rdp.geom_mode &= ~0x00020000; - rdp.geom_mode |= 0x00000200; - if (pvtx) //load vtx - t3d_vertex(segoffset(pvtx) & BMASK, ostate->vtxV0, ostate->vtxCount); - - t3dProcessRDP(segoffset(ostate->rdpCmds) >> 2); - - if (ptri) - { - update (); - uint32_t a = segoffset(ptri); - for (int t=0; t < ostate->triCount; t++) + if (!(ostate->flag & 1)) //load matrix { - t3dTriN * tri = (t3dTriN*)&gfx.RDRAM[a]; - a += 4; - FRDP("tri #%d - %d, %d, %d\n", t, tri->v0, tri->v1, tri->v2); - VERTEX *v[3] = { &rdp.vtx[tri->v0], &rdp.vtx[tri->v1], &rdp.vtx[tri->v2] }; - if (cull_tri(v)) - rdp.tri_n ++; - else - { - draw_tri (v); - rdp.tri_n ++; - } + uint32_t addr = segoffset(pstate + sizeof(t3dState)) & BMASK; + load_matrix(rdp.combined, addr); +#ifdef EXTREME_LOGGING + FRDP ("{%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 + } + + rdp.geom_mode &= ~0x00020000; + rdp.geom_mode |= 0x00000200; + if (pvtx) //load vtx + t3d_vertex(segoffset(pvtx) & BMASK, ostate->vtxV0, ostate->vtxCount); + + t3dProcessRDP(segoffset(ostate->rdpCmds) >> 2); + + if (ptri) + { + update(); + uint32_t a = segoffset(ptri); + for (int t = 0; t < ostate->triCount; t++) + { + t3dTriN * tri = (t3dTriN*)&gfx.RDRAM[a]; + a += 4; + FRDP("tri #%d - %d, %d, %d\n", t, tri->v0, tri->v1, tri->v2); + VERTEX *v[3] = { &rdp.vtx[tri->v0], &rdp.vtx[tri->v1], &rdp.vtx[tri->v2] }; + if (cull_tri(v)) + rdp.tri_n++; + else + { + draw_tri(v); + rdp.tri_n++; + } + } } - } } static void Turbo3D() { - LRDP("Start Turbo3D microcode\n"); - settings.ucode = ucode_Fast3D; - uint32_t a = 0, pgstate = 0, pstate = 0, pvtx = 0, ptri = 0; - do { - a = rdp.pc[rdp.pc_i] & BMASK; - pgstate = ((uint32_t*)gfx.RDRAM)[a>>2]; - pstate = ((uint32_t*)gfx.RDRAM)[(a>>2)+1]; - pvtx = ((uint32_t*)gfx.RDRAM)[(a>>2)+2]; - ptri = ((uint32_t*)gfx.RDRAM)[(a>>2)+3]; - FRDP("GlobalState: %08lx, Object: %08lx, Vertices: %08lx, Triangles: %08lx\n", pgstate, pstate, pvtx, ptri); - if (!pstate) - { - rdp.halt = 1; - break; - } - if (pgstate) - t3dLoadGlobState(pgstate); - t3dLoadObject(pstate, pvtx, ptri); - // Go to the next instruction - rdp.pc[rdp.pc_i] += 16; - } while (pstate); -// rdp_fullsync(); - settings.ucode = ucode_Turbo3d; + LRDP("Start Turbo3D microcode\n"); + settings.ucode = ucode_Fast3D; + uint32_t a = 0, pgstate = 0, pstate = 0, pvtx = 0, ptri = 0; + do { + a = rdp.pc[rdp.pc_i] & BMASK; + pgstate = ((uint32_t*)gfx.RDRAM)[a >> 2]; + pstate = ((uint32_t*)gfx.RDRAM)[(a >> 2) + 1]; + pvtx = ((uint32_t*)gfx.RDRAM)[(a >> 2) + 2]; + ptri = ((uint32_t*)gfx.RDRAM)[(a >> 2) + 3]; + FRDP("GlobalState: %08lx, Object: %08lx, Vertices: %08lx, Triangles: %08lx\n", pgstate, pstate, pvtx, ptri); + if (!pstate) + { + rdp.halt = 1; + break; + } + if (pgstate) + t3dLoadGlobState(pgstate); + t3dLoadObject(pstate, pvtx, ptri); + // Go to the next instruction + rdp.pc[rdp.pc_i] += 16; + } while (pstate); + // rdp_fullsync(); + settings.ucode = ucode_Turbo3d; } diff --git a/Source/Glide64/ucode.h b/Source/Glide64/ucode.h index 05bdda7dc..a78057f03 100644 --- a/Source/Glide64/ucode.h +++ b/Source/Glide64/ucode.h @@ -37,7 +37,7 @@ // //**************************************************************** -typedef void (*rdp_instr)(); +typedef void(*rdp_instr)(); // RDP graphic instructions pointer table @@ -47,746 +47,746 @@ static rdp_instr gfx_instruction[10][256] = // uCode 0 - RSP SW 2.0X // 00-3f // games: Super Mario 64, Tetrisphere, Demos - spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, - uc0_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, - rsp_reserved3, uc6_sprite2d, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: Unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, uc0_tri4, rdphalf_cont, rdphalf_2, - rdphalf_1, uc0_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, - - // uCode 1 - F3DEX 1.XX - // 00-3f - // games: Mario Kart, Star Fox - { - spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, - uc1_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, - rsp_reserved3, uc6_sprite2d, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, uc6_loaducode, - uc1_branch_z, uc1_tri2, uc2_modifyvtx, rdphalf_2, - uc1_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc0_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc0_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, - // uCode 2 - F3DEX 2.XX - // games: Zelda 64 - { - // 00-3f - spnoop, uc2_vertex, uc2_modifyvtx, uc2_culldl, - uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, - uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, - undef, undef, undef, undef, - uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, - uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, - uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, - uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // uCode 1 - F3DEX 1.XX + // 00-3f + // games: Mario Kart, Star Fox + { + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc1_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, uc6_loaducode, + uc1_branch_z, uc1_tri2, uc2_modifyvtx, rdphalf_2, + uc1_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - - // 80-bf: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - - // c0-ff: RDP commands mixed with uc2 commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, uc2_special3, - uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, - uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc2_moveword, - uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, - spnoop, uc1_rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, - - // uCode 3 - "RSP SW 2.0D", but not really + // uCode 2 - F3DEX 2.XX + // games: Zelda 64 + { // 00-3f - // games: Wave Race - // ** Added by Gonetz ** - { - spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, - uc3_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, - rsp_reserved3, uc6_sprite2d, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, uc3_tri2, rdphalf_cont, rdphalf_2, - rdphalf_1, uc3_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc0_culldl, uc3_tri1, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, + spnoop, uc2_vertex, uc2_modifyvtx, uc2_culldl, + uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, + uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, + undef, undef, undef, undef, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - { + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, uc2_special3, + uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, + uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc2_moveword, + uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + spnoop, uc1_rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 3 - "RSP SW 2.0D", but not really + // 00-3f + // games: Wave Race + // ** Added by Gonetz ** + { + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc3_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc3_tri2, rdphalf_cont, rdphalf_2, + rdphalf_1, uc3_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc3_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + { // uCode 4 - RSP SW 2.0D EXT // 00-3f // games: Star Wars: Shadows of the Empire - spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, - uc4_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, - rsp_reserved3, uc6_sprite2d, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: Unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, uc0_tri4, rdphalf_cont, rdphalf_2, - rdphalf_1, uc4_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc0_culldl, uc4_tri1, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc4_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc4_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc4_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, { // uCode 5 - RSP SW 2.0 Diddy // 00-3f // games: Diddy Kong Racing - spnoop, uc5_matrix, rsp_reserved0, uc0_movemem, - uc5_vertex, uc5_tridma, uc0_displaylist, uc5_dl_in_mem, - rsp_reserved3, uc6_sprite2d, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: Unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, uc0_tri4, rdphalf_cont, rdphalf_2, - rdphalf_1, uc0_line3d, uc5_cleargeometrymode, uc5_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc5_moveword, uc0_popmatrix, uc0_culldl, uc5_dma_offsets, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, - - // uCode 6 - S2DEX 1.XX - // games: Yoshi's Story - { - spnoop, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rectangle, - uc6_obj_sprite, uc6_obj_movemem, uc0_displaylist, rsp_reserved2, - rsp_reserved3, undef/*uc6_sprite2d*/, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, uc6_loaducode, - uc6_select_dl, uc6_obj_rendermode, uc6_obj_rectangle_r, rdphalf_2, - rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, - // c0-ff: RDP commands - rdp_noop, uc6_obj_loadtxtr, uc6_obj_ldtx_sprite, uc6_obj_ldtx_rect, - uc6_ldtx_rect_r, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + spnoop, uc5_matrix, rsp_reserved0, uc0_movemem, + uc5_vertex, uc5_tridma, uc0_displaylist, uc5_dl_in_mem, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc0_line3d, uc5_cleargeometrymode, uc5_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc5_moveword, uc0_popmatrix, uc0_culldl, uc5_dma_offsets, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage }, - // uCode 7 - unknown - // games: Perfect Dark - { - // 00-3f - spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, - uc7_vertex, rsp_reserved1, uc0_displaylist, uc7_colorbase, - rsp_reserved3, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // uCode 6 - S2DEX 1.XX + // games: Yoshi's Story + { + spnoop, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rectangle, + uc6_obj_sprite, uc6_obj_movemem, uc0_displaylist, rsp_reserved2, + rsp_reserved3, undef/*uc6_sprite2d*/, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, uc6_loaducode, + uc6_select_dl, uc6_obj_rendermode, uc6_obj_rectangle_r, rdphalf_2, + rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, + // c0-ff: RDP commands + rdp_noop, uc6_obj_loadtxtr, uc6_obj_ldtx_sprite, uc6_obj_ldtx_rect, + uc6_ldtx_rect_r, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + // uCode 7 - unknown + // games: Perfect Dark + { + // 00-3f + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc7_vertex, rsp_reserved1, uc0_displaylist, uc7_colorbase, + rsp_reserved3, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - // 80-bf: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - undef, uc0_tri4, rdphalf_cont, rdphalf_2, - rdphalf_1, uc1_tri2, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - // c0-ff: RDP commands mixed with uc2 commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc1_tri2, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, undef, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - - rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - // uCode 8 - unknown - // games: Conker's Bad Fur Day - { - // 00-3f - spnoop, uc8_vertex, uc2_modifyvtx, uc2_culldl, - uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, - uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, - undef, undef, undef, undef, - uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, - uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, - uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, - uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - // 40-7f: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, - // 80-bf: unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, + // uCode 8 - unknown + // games: Conker's Bad Fur Day + { + // 00-3f + spnoop, uc8_vertex, uc2_modifyvtx, uc2_culldl, + uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, + uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, + undef, undef, undef, undef, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - // c0-ff: RDP commands mixed with uc2 commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - undef, undef, undef, uc2_special3, - uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, - uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc8_moveword, - uc8_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, - spnoop, rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, - { + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, uc2_special3, + uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, + uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc8_moveword, + uc8_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + spnoop, rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + { // uCode 9 - gzsort // games: Telefoot Soccer // 00-3f - spnoop, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 40-7f: Unused - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - // 80-bf: Immediate commands - uc9_object, uc9_rpdcmd, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - undef, undef, undef, undef, - rdphalf_1, undef, uc0_cleargeometrymode, uc0_setgeometrymode, - uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, - uc0_moveword, undef, uc0_culldl, undef, - // c0-ff: RDP commands - rdp_noop, undef, undef, undef, - undef, undef, undef, undef, - rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, - rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + spnoop, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + uc9_object, uc9_rpdcmd, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdphalf_1, undef, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, undef, uc0_culldl, undef, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, - uc9_mix, uc9_fmlight, uc9_light, undef, - uc9_mtxtrnsp, uc9_mtxcat, uc9_mult_mpmtx, uc9_link_subdl, - uc9_set_subdl, uc9_wait_signal, uc9_send_signal, uc0_moveword, - uc9_movemem, undef, uc0_displaylist, uc0_enddl, + uc9_mix, uc9_fmlight, uc9_light, undef, + uc9_mtxtrnsp, uc9_mtxcat, uc9_mult_mpmtx, uc9_link_subdl, + uc9_set_subdl, uc9_wait_signal, uc9_send_signal, uc0_moveword, + uc9_movemem, undef, uc0_displaylist, uc0_enddl, - undef, undef, uc0_setothermode_l, uc0_setothermode_h, - rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, - rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, - rdp_setconvert, uc9_setscissor, rdp_setprimdepth, rdp_setothermode, + undef, undef, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, uc9_setscissor, rdp_setprimdepth, rdp_setothermode, - rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, - rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, - rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, - rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage - }, + rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, }; diff --git a/Source/Glide64/ucode00.h b/Source/Glide64/ucode00.h index f72dd30d2..977b6c473 100644 --- a/Source/Glide64/ucode00.h +++ b/Source/Glide64/ucode00.h @@ -51,140 +51,138 @@ static void rsp_vertex(int v0, int n) { - uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; - int i; - float x, y, z; + uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + int i; + float x, y, z; - rdp.v0 = v0; // Current vertex - rdp.vn = n; // Number to copy + rdp.v0 = v0; // Current vertex + rdp.vn = n; // Number to copy - // This is special, not handled in update(), but here - // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) - if (rdp.update & UPDATE_MULT_MAT) - { - rdp.update ^= UPDATE_MULT_MAT; - MulMatrices(rdp.model, rdp.proj, rdp.combined); - } - // * - - // This is special, not handled in update() - if (rdp.update & UPDATE_LIGHTS) - { - rdp.update ^= UPDATE_LIGHTS; - - // Calculate light vectors - for (uint32_t l=0; l>4)]; - x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; - y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; - z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; - v->flags = ((uint16_t*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; - v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; - v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; - v->uv_scaled = 0; - v->a = ((uint8_t*)gfx.RDRAM)[(addr+i + 15)^3]; - - v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; - v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; - v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; - v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; - - - if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; - CalculateFog (v); - - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - v->shade_mod = 0; - - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; -// if (v->z_w > 1.0f) v->scr_off |= 32; - - if (rdp.geom_mode & 0x00020000) + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) { - v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3]; - v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3]; - v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3]; - if (rdp.geom_mode & 0x40000) - { - if (rdp.geom_mode & 0x80000) - calc_linear (v); + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (uint32_t l = 0; l < rdp.num_lights; l++) + { + InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model); + NormalizeVector(rdp.light_vector[l]); + } + } + + FRDP("rsp:vertex v0:%d, n:%d, from: %08lx\n", v0, n, addr); + + for (i = 0; i < (n << 4); i += 16) + { + VERTEX *v = &rdp.vtx[v0 + (i >> 4)]; + x = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 0) ^ 1]; + y = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 1) ^ 1]; + z = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 2) ^ 1]; + v->flags = ((uint16_t*)gfx.RDRAM)[(((addr + i) >> 1) + 3) ^ 1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 4) ^ 1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 5) ^ 1]; + v->uv_scaled = 0; + v->a = ((uint8_t*)gfx.RDRAM)[(addr + i + 15) ^ 3]; + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + CalculateFog(v); + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + // if (v->z_w > 1.0f) v->scr_off |= 32; + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = ((char*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->vec[1] = ((char*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->vec[2] = ((char*)gfx.RDRAM)[(addr + i + 14) ^ 3]; + if (rdp.geom_mode & 0x40000) + { + if (rdp.geom_mode & 0x80000) + calc_linear(v); + else + calc_sphere(v); + } + NormalizeVector(v->vec); + + calc_light(v); + } else - calc_sphere (v); - } - NormalizeVector (v->vec); - - calc_light (v); - } - else - { - v->r = ((uint8_t*)gfx.RDRAM)[(addr+i + 12)^3]; - v->g = ((uint8_t*)gfx.RDRAM)[(addr+i + 13)^3]; - v->b = ((uint8_t*)gfx.RDRAM)[(addr+i + 14)^3]; - } + { + v->r = ((uint8_t*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->g = ((uint8_t*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->b = ((uint8_t*)gfx.RDRAM)[(addr + i + 14) ^ 3]; + } #ifdef EXTREME_LOGGING - FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); #endif - - } + } } static void rsp_tri1(VERTEX **v, uint16_t linew = 0) { - if (cull_tri(v)) - rdp.tri_n ++; - else - { - update (); - draw_tri (v, linew); - rdp.tri_n ++; - } + if (cull_tri(v)) + rdp.tri_n++; + else + { + update(); + draw_tri(v, linew); + rdp.tri_n++; + } } -static void rsp_tri2 (VERTEX **v) +static void rsp_tri2(VERTEX **v) { - int updated = 0; + int updated = 0; - if (cull_tri(v)) - rdp.tri_n ++; - else - { - updated = 1; - update (); + if (cull_tri(v)) + rdp.tri_n++; + else + { + updated = 1; + update(); - draw_tri (v); - rdp.tri_n ++; - } + draw_tri(v); + rdp.tri_n++; + } - if (cull_tri(v+3)) - rdp.tri_n ++; - else - { - if (!updated) - update (); + if (cull_tri(v + 3)) + rdp.tri_n++; + else + { + if (!updated) + update(); - draw_tri (v+3); - rdp.tri_n ++; - } + draw_tri(v + 3); + rdp.tri_n++; + } } // @@ -192,98 +190,98 @@ static void rsp_tri2 (VERTEX **v) // static void uc0_vertex() { - int v0 = (rdp.cmd0 >> 16) & 0xF; // Current vertex - int n = ((rdp.cmd0 >> 20) & 0xF) + 1; // Number of vertices to copy - rsp_vertex(v0, n); + int v0 = (rdp.cmd0 >> 16) & 0xF; // Current vertex + int n = ((rdp.cmd0 >> 20) & 0xF) + 1; // Number of vertices to copy + rsp_vertex(v0, n); } // ** Definitions ** -void modelview_load (float m[4][4]) +void modelview_load(float m[4][4]) { - memcpy (rdp.model, m, 64); // 4*4*4(float) + memcpy(rdp.model, m, 64); // 4*4*4(float) - rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; } -void modelview_mul (float m[4][4]) +void modelview_mul(float m[4][4]) { - DECLAREALIGN16VAR(m_src[4][4]); - memcpy (m_src, rdp.model, 64); - MulMatrices(m, m_src, rdp.model); - rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; + DECLAREALIGN16VAR(m_src[4][4]); + memcpy(m_src, rdp.model, 64); + MulMatrices(m, m_src, rdp.model); + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; } -void modelview_push () +void modelview_push() { - if (rdp.model_i == rdp.model_stack_size) - { - RDP_E ("** Model matrix stack overflow ** too many pushes\n"); - LRDP("** Model matrix stack overflow ** too many pushes\n"); - return; - } - - memcpy (rdp.model_stack[rdp.model_i], rdp.model, 64); - rdp.model_i ++; -} - -void modelview_pop (int num = 1) -{ - if (rdp.model_i > num - 1) - { - rdp.model_i -= num; - } - else - { - RDP_E ("** Model matrix stack error ** too many pops\n"); - LRDP("** Model matrix stack error ** too many pops\n"); - return; - } - memcpy (rdp.model, rdp.model_stack[rdp.model_i], 64); - rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; -} - -void modelview_load_push (float m[4][4]) -{ - modelview_push (); - modelview_load (m); -} - -void modelview_mul_push (float m[4][4]) -{ - modelview_push (); - modelview_mul (m); -} - -void projection_load (float m[4][4]) -{ - memcpy (rdp.proj, m, 64); // 4*4*4(float) - - rdp.update |= UPDATE_MULT_MAT; -} - -void projection_mul (float m[4][4]) -{ - DECLAREALIGN16VAR(m_src[4][4]); - memcpy (m_src, rdp.proj, 64); - MulMatrices(m, m_src, rdp.proj); - rdp.update |= UPDATE_MULT_MAT; -} - -void load_matrix (float m[4][4], uint32_t addr) -{ - FRDP ("matrix - addr: %08lx\n", addr); - int x,y; // matrix index - addr >>= 1; - uint16_t * src = (uint16_t*)gfx.RDRAM; - for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later - for (y=0; y<4; y++) { - m[x>>2][y] = (float)( - (((int32_t)src[(addr+x+y)^1]) << 16) | - src[(addr+x+y+16)^1] - ) / 65536.0f; + if (rdp.model_i == rdp.model_stack_size) + { + RDP_E("** Model matrix stack overflow ** too many pushes\n"); + LRDP("** Model matrix stack overflow ** too many pushes\n"); + return; + } + + memcpy(rdp.model_stack[rdp.model_i], rdp.model, 64); + rdp.model_i++; +} + +void modelview_pop(int num = 1) +{ + if (rdp.model_i > num - 1) + { + rdp.model_i -= num; + } + else + { + RDP_E("** Model matrix stack error ** too many pops\n"); + LRDP("** Model matrix stack error ** too many pops\n"); + return; + } + memcpy(rdp.model, rdp.model_stack[rdp.model_i], 64); + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; +} + +void modelview_load_push(float m[4][4]) +{ + modelview_push(); + modelview_load(m); +} + +void modelview_mul_push(float m[4][4]) +{ + modelview_push(); + modelview_mul(m); +} + +void projection_load(float m[4][4]) +{ + memcpy(rdp.proj, m, 64); // 4*4*4(float) + + rdp.update |= UPDATE_MULT_MAT; +} + +void projection_mul(float m[4][4]) +{ + DECLAREALIGN16VAR(m_src[4][4]); + memcpy(m_src, rdp.proj, 64); + MulMatrices(m, m_src, rdp.proj); + rdp.update |= UPDATE_MULT_MAT; +} + +void load_matrix(float m[4][4], uint32_t addr) +{ + FRDP("matrix - addr: %08lx\n", addr); + int x, y; // matrix index + addr >>= 1; + uint16_t * src = (uint16_t*)gfx.RDRAM; + for (x = 0; x < 16; x += 4) { // Adding 4 instead of one, just to remove mult. later + for (y = 0; y < 4; y++) { + m[x >> 2][y] = (float)( + (((int32_t)src[(addr + x + y) ^ 1]) << 16) | + src[(addr + x + y + 16) ^ 1] + ) / 65536.0f; + } } - } } // @@ -291,68 +289,68 @@ void load_matrix (float m[4][4], uint32_t addr) // static void uc0_matrix() { - LRDP("uc0:matrix "); + LRDP("uc0:matrix "); - // Use segment offset to get the address - uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; - uint8_t command = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); + // Use segment offset to get the address + uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + uint8_t command = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); - DECLAREALIGN16VAR(m[4][4]); - load_matrix(m, addr); + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); - switch (command) - { - case 0: // modelview mul nopush - LRDP("modelview mul\n"); - modelview_mul (m); - break; + switch (command) + { + case 0: // modelview mul nopush + LRDP("modelview mul\n"); + modelview_mul(m); + break; - case 1: // projection mul nopush - case 5: // projection mul push, can't push projection - LRDP("projection mul\n"); - projection_mul (m); - break; + case 1: // projection mul nopush + case 5: // projection mul push, can't push projection + LRDP("projection mul\n"); + projection_mul(m); + break; - case 2: // modelview load nopush - LRDP("modelview load\n"); - modelview_load (m); - break; + case 2: // modelview load nopush + LRDP("modelview load\n"); + modelview_load(m); + break; - case 3: // projection load nopush - case 7: // projection load push, can't push projection - LRDP("projection load\n"); - projection_load (m); + case 3: // projection load nopush + case 7: // projection load push, can't push projection + LRDP("projection load\n"); + projection_load(m); - break; + break; - case 4: // modelview mul push - LRDP("modelview mul push\n"); - modelview_mul_push (m); - break; + case 4: // modelview mul push + LRDP("modelview mul push\n"); + modelview_mul_push(m); + break; - case 6: // modelview load push - LRDP("modelview load push\n"); - modelview_load_push (m); - break; + case 6: // modelview load push + LRDP("modelview load push\n"); + modelview_load_push(m); + break; - default: - FRDP_E ("Unknown matrix command, %02lx", command); - FRDP ("Unknown matrix command, %02lx", command); - } + default: + FRDP_E("Unknown matrix command, %02lx", command); + FRDP("Unknown matrix command, %02lx", command); + } #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]); + 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 } @@ -361,179 +359,178 @@ static void uc0_matrix() // static void uc0_movemem() { - LRDP("uc0:movemem "); + LRDP("uc0:movemem "); - uint32_t i,a; + uint32_t i, a; - // Check the command - switch ((rdp.cmd0 >> 16) & 0xFF) - { - case 0x80: + // Check the command + switch ((rdp.cmd0 >> 16) & 0xFF) { - a = (segoffset(rdp.cmd1) & 0xFFFFFF) >> 1; + case 0x80: + { + a = (segoffset(rdp.cmd1) & 0xFFFFFF) >> 1; - short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] / 4; - short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] / 4; - short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; - short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] / 4; - short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] / 4; - short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; - if (settings.correct_viewport) - { - scale_x = abs(scale_x); - scale_y = abs(scale_y); - } - 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; + short scale_x = ((short*)gfx.RDRAM)[(a + 0) ^ 1] / 4; + short scale_y = ((short*)gfx.RDRAM)[(a + 1) ^ 1] / 4; + short scale_z = ((short*)gfx.RDRAM)[(a + 2) ^ 1]; + short trans_x = ((short*)gfx.RDRAM)[(a + 4) ^ 1] / 4; + short trans_y = ((short*)gfx.RDRAM)[(a + 5) ^ 1] / 4; + short trans_z = ((short*)gfx.RDRAM)[(a + 6) ^ 1]; + if (settings.correct_viewport) + { + scale_x = abs(scale_x); + scale_y = abs(scale_y); + } + 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; - // there are other values than x and y, but I don't know what they do + // there are other values than x and y, but I don't know what they do - rdp.update |= UPDATE_VIEWPORT; + rdp.update |= UPDATE_VIEWPORT; - 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, rdp.cmd1); + 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, rdp.cmd1); } break; - case 0x82: + case 0x82: { - a = segoffset(rdp.cmd1) & 0x00ffffff; - char dir_x = ((char*)gfx.RDRAM)[(a+8)^3]; - rdp.lookat[1][0] = (float)(dir_x) / 127.0f; - char dir_y = ((char*)gfx.RDRAM)[(a+9)^3]; - rdp.lookat[1][1] = (float)(dir_y) / 127.0f; - char dir_z = ((char*)gfx.RDRAM)[(a+10)^3]; - rdp.lookat[1][2] = (float)(dir_z) / 127.0f; - if (!dir_x && !dir_y) - rdp.use_lookat = FALSE; - else + a = segoffset(rdp.cmd1) & 0x00ffffff; + char dir_x = ((char*)gfx.RDRAM)[(a + 8) ^ 3]; + rdp.lookat[1][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(a + 9) ^ 3]; + rdp.lookat[1][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(a + 10) ^ 3]; + rdp.lookat[1][2] = (float)(dir_z) / 127.0f; + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + else + rdp.use_lookat = TRUE; + FRDP("lookat_y (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); + } + break; + + case 0x84: + a = segoffset(rdp.cmd1) & 0x00ffffff; + rdp.lookat[0][0] = (float)(((char*)gfx.RDRAM)[(a + 8) ^ 3]) / 127.0f; + rdp.lookat[0][1] = (float)(((char*)gfx.RDRAM)[(a + 9) ^ 3]) / 127.0f; + rdp.lookat[0][2] = (float)(((char*)gfx.RDRAM)[(a + 10) ^ 3]) / 127.0f; rdp.use_lookat = TRUE; - FRDP("lookat_y (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); - } - break; + FRDP("lookat_x (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); + break; - case 0x84: - a = segoffset(rdp.cmd1) & 0x00ffffff; - rdp.lookat[0][0] = (float)(((char*)gfx.RDRAM)[(a+8)^3]) / 127.0f; - rdp.lookat[0][1] = (float)(((char*)gfx.RDRAM)[(a+9)^3]) / 127.0f; - rdp.lookat[0][2] = (float)(((char*)gfx.RDRAM)[(a+10)^3]) / 127.0f; - rdp.use_lookat = TRUE; - FRDP("lookat_x (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); - break; + case 0x86: + case 0x88: + case 0x8a: + case 0x8c: + case 0x8e: + case 0x90: + case 0x92: + case 0x94: + // Get the light # + i = (((rdp.cmd0 >> 16) & 0xff) - 0x86) >> 1; + a = segoffset(rdp.cmd1) & 0x00ffffff; - case 0x86: - case 0x88: - case 0x8a: - case 0x8c: - case 0x8e: - case 0x90: - case 0x92: - case 0x94: - // Get the light # - i = (((rdp.cmd0 >> 16) & 0xff) - 0x86) >> 1; - a = segoffset(rdp.cmd1) & 0x00ffffff; + // Get the data + rdp.light[i].r = (float)(((uint8_t*)gfx.RDRAM)[(a + 0) ^ 3]) / 255.0f; + rdp.light[i].g = (float)(((uint8_t*)gfx.RDRAM)[(a + 1) ^ 3]) / 255.0f; + rdp.light[i].b = (float)(((uint8_t*)gfx.RDRAM)[(a + 2) ^ 3]) / 255.0f; + rdp.light[i].a = 1.0f; + // ** Thanks to Icepir8 for pointing this out ** + // Lighting must be signed byte instead of byte + rdp.light[i].dir_x = (float)(((char*)gfx.RDRAM)[(a + 8) ^ 3]) / 127.0f; + rdp.light[i].dir_y = (float)(((char*)gfx.RDRAM)[(a + 9) ^ 3]) / 127.0f; + rdp.light[i].dir_z = (float)(((char*)gfx.RDRAM)[(a + 10) ^ 3]) / 127.0f; + // ** - // Get the data - rdp.light[i].r = (float)(((uint8_t*)gfx.RDRAM)[(a+0)^3]) / 255.0f; - rdp.light[i].g = (float)(((uint8_t*)gfx.RDRAM)[(a+1)^3]) / 255.0f; - rdp.light[i].b = (float)(((uint8_t*)gfx.RDRAM)[(a+2)^3]) / 255.0f; - rdp.light[i].a = 1.0f; - // ** Thanks to Icepir8 for pointing this out ** - // Lighting must be signed byte instead of byte - rdp.light[i].dir_x = (float)(((char*)gfx.RDRAM)[(a+8)^3]) / 127.0f; - rdp.light[i].dir_y = (float)(((char*)gfx.RDRAM)[(a+9)^3]) / 127.0f; - rdp.light[i].dir_z = (float)(((char*)gfx.RDRAM)[(a+10)^3]) / 127.0f; - // ** + //rdp.update |= UPDATE_LIGHTS; - //rdp.update |= UPDATE_LIGHTS; + 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_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); + break; - 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_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); - break; - - - case 0x9E: //gSPForceMatrix command. Modification of uc2_movemem:matrix. Gonetz. + case 0x9E: //gSPForceMatrix command. Modification of uc2_movemem:matrix. Gonetz. { - // do not update the combined matrix! - rdp.update &= ~UPDATE_MULT_MAT; + // do not update the combined matrix! + rdp.update &= ~UPDATE_MULT_MAT; - uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; - load_matrix(rdp.combined, addr); + uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + load_matrix(rdp.combined, addr); - addr = rdp.pc[rdp.pc_i] & BMASK; - rdp.pc[rdp.pc_i] = (addr+24) & BMASK; //skip next 3 command, b/c they all are part of gSPForceMatrix + addr = rdp.pc[rdp.pc_i] & BMASK; + rdp.pc[rdp.pc_i] = (addr + 24) & BMASK; //skip next 3 command, b/c they all are part of gSPForceMatrix #ifdef EXTREME_LOGGING - FRDP ("{%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]); + FRDP("{%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 } break; //next 3 command should never appear since they will be skipped in previous command - case 0x98: - RDP_E ("uc0:movemem matrix 0 - ERROR!\n"); - LRDP("matrix 0 - IGNORED\n"); - break; + case 0x98: + RDP_E("uc0:movemem matrix 0 - ERROR!\n"); + LRDP("matrix 0 - IGNORED\n"); + break; - case 0x9A: - RDP_E ("uc0:movemem matrix 1 - ERROR!\n"); - LRDP("matrix 1 - IGNORED\n"); - break; + case 0x9A: + RDP_E("uc0:movemem matrix 1 - ERROR!\n"); + LRDP("matrix 1 - IGNORED\n"); + break; - case 0x9C: - RDP_E ("uc0:movemem matrix 2 - ERROR!\n"); - LRDP("matrix 2 - IGNORED\n"); - break; + case 0x9C: + RDP_E("uc0:movemem matrix 2 - ERROR!\n"); + LRDP("matrix 2 - IGNORED\n"); + break; - default: - FRDP_E ("uc0:movemem unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); - FRDP ("unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); - } -} + default: + FRDP_E("uc0:movemem unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); + FRDP("unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); + } + } // // uc0:displaylist - makes a call to another section of code // static void uc0_displaylist() { - uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + uint32_t addr = segoffset(rdp.cmd1) & 0x00FFFFFF; - // This fixes partially Gauntlet: Legends - if (addr == rdp.pc[rdp.pc_i] - 8) { LRDP("display list not executed!\n"); return; } + // This fixes partially Gauntlet: Legends + if (addr == rdp.pc[rdp.pc_i] - 8) { LRDP("display list not executed!\n"); return; } - uint32_t push = (rdp.cmd0 >> 16) & 0xFF; // push the old location? + uint32_t push = (rdp.cmd0 >> 16) & 0xFF; // push the old location? - FRDP("uc0:displaylist: %08lx, push:%s", addr, push?"no":"yes"); - FRDP(" (seg %d, offset %08lx)\n", (rdp.cmd1>>24)&0x0F, rdp.cmd1&0x00FFFFFF); + FRDP("uc0:displaylist: %08lx, push:%s", addr, push ? "no" : "yes"); + FRDP(" (seg %d, offset %08lx)\n", (rdp.cmd1 >> 24) & 0x0F, rdp.cmd1 & 0x00FFFFFF); - switch (push) - { - case 0: // push - if (rdp.pc_i >= 9) { - RDP_E ("** DL stack overflow **"); - LRDP("** DL stack overflow **\n"); - return; + switch (push) + { + case 0: // push + if (rdp.pc_i >= 9) { + RDP_E("** DL stack overflow **"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + break; + + case 1: // no push + rdp.pc[rdp.pc_i] = addr; // just jump to the address + break; + + default: + RDP_E("Unknown displaylist operation\n"); + LRDP("Unknown displaylist operation\n"); } - rdp.pc_i ++; // go to the next PC in the stack - rdp.pc[rdp.pc_i] = addr; // jump to the address - break; - - case 1: // no push - rdp.pc[rdp.pc_i] = addr; // just jump to the address - break; - - default: - RDP_E("Unknown displaylist operation\n"); - LRDP("Unknown displaylist operation\n"); - } } // @@ -541,29 +538,29 @@ static void uc0_displaylist() // static void uc0_tri1() { - FRDP("uc0:tri1 #%d - %d, %d, %d\n", rdp.tri_n, - ((rdp.cmd1>>16) & 0xFF) / 10, - ((rdp.cmd1>>8) & 0xFF) / 10, - (rdp.cmd1 & 0xFF) / 10); + FRDP("uc0:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + ((rdp.cmd1 >> 16) & 0xFF) / 10, + ((rdp.cmd1 >> 8) & 0xFF) / 10, + (rdp.cmd1 & 0xFF) / 10); - VERTEX *v[3] = { - &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 10], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 10], - &rdp.vtx[(rdp.cmd1 & 0xFF) / 10] - }; - if (settings.hacks & hack_Makers) - { - rdp.force_wrap = FALSE; - for (int i = 0; i < 3; i++) + VERTEX *v[3] = { + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 10], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 10], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 10] + }; + if (settings.hacks & hack_Makers) { - if (v[i]->ou < 0.0f || v[i]->ov < 0.0f) - { - rdp.force_wrap = TRUE; - break; - } + rdp.force_wrap = FALSE; + for (int i = 0; i < 3; i++) + { + if (v[i]->ou < 0.0f || v[i]->ov < 0.0f) + { + rdp.force_wrap = TRUE; + break; + } + } } - } - rsp_tri1(v); + rsp_tri1(v); } // @@ -571,146 +568,146 @@ static void uc0_tri1() // static void uc0_enddl() { - LRDP("uc0:enddl\n"); + LRDP("uc0:enddl\n"); - if (rdp.pc_i == 0) - { - LRDP("RDP end\n"); + if (rdp.pc_i == 0) + { + LRDP("RDP end\n"); - // Halt execution here - rdp.halt = 1; - } + // Halt execution here + rdp.halt = 1; + } - rdp.pc_i --; + rdp.pc_i--; } static void uc0_culldl() { - uint8_t vStart = (uint8_t)((rdp.cmd0 & 0x00FFFFFF) / 40) & 0xF; - uint8_t vEnd = (uint8_t)(rdp.cmd1 / 40) & 0x0F; - uint32_t cond = 0; - VERTEX *v; + uint8_t vStart = (uint8_t)((rdp.cmd0 & 0x00FFFFFF) / 40) & 0xF; + uint8_t vEnd = (uint8_t)(rdp.cmd1 / 40) & 0x0F; + uint32_t cond = 0; + VERTEX *v; - FRDP("uc0:culldl start: %d, end: %d\n", vStart, vEnd); + FRDP("uc0:culldl start: %d, end: %d\n", vStart, vEnd); - if (vEnd < vStart) return; - for (uint16_t i=vStart; i<=vEnd; i++) - { - v = &rdp.vtx[i]; - // Check if completely off the screen (quick frustrum clipping for 90 FOV) - if (v->x >= -v->w) - cond |= 0x01; - if (v->x <= v->w) - cond |= 0x02; - if (v->y >= -v->w) - cond |= 0x04; - if (v->y <= v->w) - cond |= 0x08; - if (v->w >= 0.1f) - cond |= 0x10; + if (vEnd < vStart) return; + for (uint16_t i = vStart; i <= vEnd; i++) + { + v = &rdp.vtx[i]; + // Check if completely off the screen (quick frustrum clipping for 90 FOV) + if (v->x >= -v->w) + cond |= 0x01; + if (v->x <= v->w) + cond |= 0x02; + if (v->y >= -v->w) + cond |= 0x04; + if (v->y <= v->w) + cond |= 0x08; + if (v->w >= 0.1f) + cond |= 0x10; - if (cond == 0x1F) - return; - } + if (cond == 0x1F) + return; + } - LRDP(" - "); // specify that the enddl is not a real command - uc0_enddl (); + LRDP(" - "); // specify that the enddl is not a real command + uc0_enddl(); } static void uc0_popmatrix() { - LRDP("uc0:popmatrix\n"); + LRDP("uc0:popmatrix\n"); - uint32_t param = rdp.cmd1; + uint32_t param = rdp.cmd1; - switch (param) - { - case 0: // modelview - modelview_pop (); - break; + switch (param) + { + case 0: // modelview + modelview_pop(); + break; - case 1: // projection, can't - break; + case 1: // projection, can't + break; - default: - FRDP_E ("Unknown uc0:popmatrix command: 0x%08lx\n", param); - FRDP ("Unknown uc0:popmatrix command: 0x%08lx\n", param); - } + default: + FRDP_E("Unknown uc0:popmatrix command: 0x%08lx\n", param); + FRDP("Unknown uc0:popmatrix command: 0x%08lx\n", param); + } } -static void uc6_obj_sprite (); +static void uc6_obj_sprite(); static void uc0_modifyvtx(uint8_t where, uint16_t vtx, uint32_t val) { - VERTEX *v = &rdp.vtx[vtx]; + VERTEX *v = &rdp.vtx[vtx]; - switch (where) - { - case 0: - uc6_obj_sprite (); - break; - - case 0x10: // RGBA - v->r = (uint8_t)(val >> 24); - v->g = (uint8_t)((val >> 16) & 0xFF); - v->b = (uint8_t)((val >> 8) & 0xFF); - v->a = (uint8_t)(val & 0xFF); - v->shade_mod = 0; - - FRDP ("RGBA: %d, %d, %d, %d\n", v->r, v->g, v->b, v->a); - break; - - case 0x14: // ST + switch (where) { - float scale = rdp.Persp_en ? 0.03125f : 0.015625f; - v->ou = (float)((short)(val>>16)) * scale; - v->ov = (float)((short)(val&0xFFFF)) * scale; - v->uv_calculated = 0xFFFFFFFF; - v->uv_scaled = 1; + case 0: + uc6_obj_sprite(); + break; + + case 0x10: // RGBA + v->r = (uint8_t)(val >> 24); + v->g = (uint8_t)((val >> 16) & 0xFF); + v->b = (uint8_t)((val >> 8) & 0xFF); + v->a = (uint8_t)(val & 0xFF); + v->shade_mod = 0; + + FRDP("RGBA: %d, %d, %d, %d\n", v->r, v->g, v->b, v->a); + break; + + case 0x14: // ST + { + float scale = rdp.Persp_en ? 0.03125f : 0.015625f; + v->ou = (float)((short)(val >> 16)) * scale; + v->ov = (float)((short)(val & 0xFFFF)) * scale; + v->uv_calculated = 0xFFFFFFFF; + v->uv_scaled = 1; } - FRDP ("u/v: (%04lx, %04lx), (%f, %f)\n", (short)(val>>16), (short)(val&0xFFFF), - v->ou, v->ov); + FRDP("u/v: (%04lx, %04lx), (%f, %f)\n", (short)(val >> 16), (short)(val & 0xFFFF), + v->ou, v->ov); break; - case 0x18: // XY screen + case 0x18: // XY screen { - float scr_x = (float)((short)(val>>16)) / 4.0f; - float scr_y = (float)((short)(val&0xFFFF)) / 4.0f; - v->screen_translated = 2; - v->sx = scr_x * rdp.scale_x + rdp.offset_x; - v->sy = scr_y * rdp.scale_y + rdp.offset_y; - if (v->w < 0.01f) - { - v->w = 1.0f; - v->oow = 1.0f; - v->z_w = 1.0f; - } - v->sz = rdp.view_trans[2] + v->z_w * rdp.view_scale[2]; + float scr_x = (float)((short)(val >> 16)) / 4.0f; + float scr_y = (float)((short)(val & 0xFFFF)) / 4.0f; + v->screen_translated = 2; + v->sx = scr_x * rdp.scale_x + rdp.offset_x; + v->sy = scr_y * rdp.scale_y + rdp.offset_y; + if (v->w < 0.01f) + { + v->w = 1.0f; + v->oow = 1.0f; + v->z_w = 1.0f; + } + v->sz = rdp.view_trans[2] + v->z_w * rdp.view_scale[2]; - v->scr_off = 0; - if (scr_x < 0) v->scr_off |= 1; - if (scr_x > rdp.vi_width) v->scr_off |= 2; - if (scr_y < 0) v->scr_off |= 4; - if (scr_y > rdp.vi_height) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; + v->scr_off = 0; + if (scr_x < 0) v->scr_off |= 1; + if (scr_x > rdp.vi_width) v->scr_off |= 2; + if (scr_y < 0) v->scr_off |= 4; + if (scr_y > rdp.vi_height) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; - FRDP ("x/y: (%f, %f)\n", scr_x, scr_y); + FRDP("x/y: (%f, %f)\n", scr_x, scr_y); } break; - case 0x1C: // Z screen + case 0x1C: // Z screen { - float scr_z = (float)((short)(val>>16)); - v->z_w = (scr_z - rdp.view_trans[2]) / rdp.view_scale[2]; - v->z = v->z_w * v->w; - FRDP ("z: %f\n", scr_z); + float scr_z = (float)((short)(val >> 16)); + v->z_w = (scr_z - rdp.view_trans[2]) / rdp.view_scale[2]; + v->z = v->z_w * v->w; + FRDP("z: %f\n", scr_z); } break; - default: - LRDP("UNKNOWN\n"); - break; - } + default: + LRDP("UNKNOWN\n"); + break; + } } // @@ -718,439 +715,438 @@ static void uc0_modifyvtx(uint8_t where, uint16_t vtx, uint32_t val) // static void uc0_moveword() { - LRDP("uc0:moveword "); + LRDP("uc0:moveword "); - // Find which command this is (lowest byte of cmd0) - switch (rdp.cmd0 & 0xFF) - { - case 0x00: - RDP_E ("uc0:moveword matrix - IGNORED\n"); - LRDP("matrix - IGNORED\n"); - break; - - case 0x02: - rdp.num_lights = ((rdp.cmd1 - 0x80000000) >> 5) - 1; // inverse of equation - if (rdp.num_lights > 8) rdp.num_lights = 0; - - rdp.update |= UPDATE_LIGHTS; - FRDP ("numlights: %d\n", rdp.num_lights); - break; - - case 0x04: - if (((rdp.cmd0>>8)&0xFFFF) == 0x04) + // Find which command this is (lowest byte of cmd0) + switch (rdp.cmd0 & 0xFF) { - rdp.clip_ratio = sqrt((float)rdp.cmd1); - rdp.update |= UPDATE_VIEWPORT; - } - FRDP ("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); - break; + case 0x00: + RDP_E("uc0:moveword matrix - IGNORED\n"); + LRDP("matrix - IGNORED\n"); + break; - case 0x06: // segment - FRDP ("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); - if ((rdp.cmd1&BMASK)> 10) & 0x0F] = rdp.cmd1; - break; + case 0x02: + rdp.num_lights = ((rdp.cmd1 - 0x80000000) >> 5) - 1; // inverse of equation + if (rdp.num_lights > 8) rdp.num_lights = 0; - case 0x08: + rdp.update |= UPDATE_LIGHTS; + FRDP("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (((rdp.cmd0 >> 8) & 0xFFFF) == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // segment + FRDP("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); + if ((rdp.cmd1&BMASK) < BMASK) + rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; + break; + + case 0x08: { - rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); - rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); - FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); } break; - case 0x0a: // moveword LIGHTCOL + case 0x0a: // moveword LIGHTCOL { - int n = (rdp.cmd0&0xE000) >> 13; - FRDP ("lightcol light:%d, %08lx\n", n, rdp.cmd1); + int n = (rdp.cmd0 & 0xE000) >> 13; + FRDP("lightcol light:%d, %08lx\n", n, rdp.cmd1); - rdp.light[n].r = (float)((rdp.cmd1 >> 24) & 0xFF) / 255.0f; - rdp.light[n].g = (float)((rdp.cmd1 >> 16) & 0xFF) / 255.0f; - rdp.light[n].b = (float)((rdp.cmd1 >> 8) & 0xFF) / 255.0f; - rdp.light[n].a = 255; + rdp.light[n].r = (float)((rdp.cmd1 >> 24) & 0xFF) / 255.0f; + rdp.light[n].g = (float)((rdp.cmd1 >> 16) & 0xFF) / 255.0f; + rdp.light[n].b = (float)((rdp.cmd1 >> 8) & 0xFF) / 255.0f; + rdp.light[n].a = 255; } break; - case 0x0c: + case 0x0c: { - uint16_t val = (uint16_t)((rdp.cmd0 >> 8) & 0xFFFF); - uint16_t vtx = val / 40; - uint8_t where = val%40; - uc0_modifyvtx(where, vtx, rdp.cmd1); - FRDP ("uc0:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); + uint16_t val = (uint16_t)((rdp.cmd0 >> 8) & 0xFFFF); + uint16_t vtx = val / 40; + uint8_t where = val % 40; + uc0_modifyvtx(where, vtx, rdp.cmd1); + FRDP("uc0:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); } break; - case 0x0e: - LRDP("perspnorm - IGNORED\n"); - break; + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; - default: - FRDP_E ("uc0:moveword unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); - FRDP ("unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); - } + default: + FRDP_E("uc0:moveword unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); + FRDP("unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); + } } static void uc0_texture() { - int tile = (rdp.cmd0 >> 8) & 0x07; - if (tile == 7 && (settings.hacks&hack_Supercross)) tile = 0; //fix for supercross 2000 - rdp.mipmap_level = (rdp.cmd0 >> 11) & 0x07; - uint32_t on = (rdp.cmd0 & 0xFF); - rdp.cur_tile = tile; + int tile = (rdp.cmd0 >> 8) & 0x07; + if (tile == 7 && (settings.hacks&hack_Supercross)) tile = 0; //fix for supercross 2000 + rdp.mipmap_level = (rdp.cmd0 >> 11) & 0x07; + uint32_t on = (rdp.cmd0 & 0xFF); + rdp.cur_tile = tile; - if (on) - { - uint16_t s = (uint16_t)((rdp.cmd1 >> 16) & 0xFFFF); - uint16_t t = (uint16_t)(rdp.cmd1 & 0xFFFF); + if (on) + { + uint16_t s = (uint16_t)((rdp.cmd1 >> 16) & 0xFFFF); + uint16_t t = (uint16_t)(rdp.cmd1 & 0xFFFF); - TILE *tmp_tile = &rdp.tiles[tile]; - tmp_tile->on = 1; - tmp_tile->org_s_scale = s; - tmp_tile->org_t_scale = t; - tmp_tile->s_scale = (float)(s+1)/65536.0f; - tmp_tile->t_scale = (float)(t+1)/65536.0f; - tmp_tile->s_scale /= 32.0f; - tmp_tile->t_scale /= 32.0f; + TILE *tmp_tile = &rdp.tiles[tile]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = s; + tmp_tile->org_t_scale = t; + tmp_tile->s_scale = (float)(s + 1) / 65536.0f; + tmp_tile->t_scale = (float)(t + 1) / 65536.0f; + tmp_tile->s_scale /= 32.0f; + tmp_tile->t_scale /= 32.0f; - rdp.update |= UPDATE_TEXTURE; + rdp.update |= UPDATE_TEXTURE; - FRDP("uc0:texture: tile: %d, mipmap_lvl: %d, on: %d, s_scale: %f, t_scale: %f\n", - tile, rdp.mipmap_level, on, tmp_tile->s_scale, tmp_tile->t_scale); - } - else - { - LRDP("uc0:texture skipped b/c of off\n"); - rdp.tiles[tile].on = 0; - } + FRDP("uc0:texture: tile: %d, mipmap_lvl: %d, on: %d, s_scale: %f, t_scale: %f\n", + tile, rdp.mipmap_level, on, tmp_tile->s_scale, tmp_tile->t_scale); + } + else + { + LRDP("uc0:texture skipped b/c of off\n"); + rdp.tiles[tile].on = 0; + } } - static void uc0_setothermode_h() { - LRDP("uc0:setothermode_h: "); + LRDP("uc0:setothermode_h: "); - int shift, len; - if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) - { - len = (rdp.cmd0 & 0xFF) + 1; - shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; - } - else - { - shift = (rdp.cmd0 >> 8) & 0xFF; - len = rdp.cmd0 & 0xFF; - } + int shift, len; + if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) + { + len = (rdp.cmd0 & 0xFF) + 1; + shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; + } + else + { + shift = (rdp.cmd0 >> 8) & 0xFF; + len = rdp.cmd0 & 0xFF; + } - uint32_t mask = 0; - int i = len; - for (; i; i--) - mask = (mask << 1) | 1; - mask <<= shift; + uint32_t mask = 0; + int i = len; + for (; i; i--) + mask = (mask << 1) | 1; + mask <<= shift; - rdp.cmd1 &= mask; - rdp.othermode_h &= ~mask; - rdp.othermode_h |= rdp.cmd1; + rdp.cmd1 &= mask; + rdp.othermode_h &= ~mask; + rdp.othermode_h |= rdp.cmd1; - if (mask & 0x00000030) // alpha dither mode - { - rdp.alpha_dither_mode = (rdp.othermode_h >> 4) & 0x3; - FRDP ("alpha dither mode: %s\n", str_dither[rdp.alpha_dither_mode]); - } + if (mask & 0x00000030) // alpha dither mode + { + rdp.alpha_dither_mode = (rdp.othermode_h >> 4) & 0x3; + FRDP("alpha dither mode: %s\n", str_dither[rdp.alpha_dither_mode]); + } - if (mask & 0x000000C0) // rgb dither mode - { - uint32_t dither_mode = (rdp.othermode_h >> 6) & 0x3; - FRDP ("rgb dither mode: %s\n", str_dither[dither_mode]); - } + if (mask & 0x000000C0) // rgb dither mode + { + uint32_t dither_mode = (rdp.othermode_h >> 6) & 0x3; + FRDP("rgb dither mode: %s\n", str_dither[dither_mode]); + } - if (mask & 0x00003000) // filter mode - { - rdp.filter_mode = (int)((rdp.othermode_h & 0x00003000) >> 12); - rdp.update |= UPDATE_TEXTURE; - FRDP ("filter mode: %s\n", str_filter[rdp.filter_mode]); - } + if (mask & 0x00003000) // filter mode + { + rdp.filter_mode = (int)((rdp.othermode_h & 0x00003000) >> 12); + rdp.update |= UPDATE_TEXTURE; + FRDP("filter mode: %s\n", str_filter[rdp.filter_mode]); + } - if (mask & 0x0000C000) // tlut mode - { - rdp.tlut_mode = (uint8_t)((rdp.othermode_h & 0x0000C000) >> 14); - FRDP ("tlut mode: %s\n", str_tlut[rdp.tlut_mode]); - } + if (mask & 0x0000C000) // tlut mode + { + rdp.tlut_mode = (uint8_t)((rdp.othermode_h & 0x0000C000) >> 14); + FRDP("tlut mode: %s\n", str_tlut[rdp.tlut_mode]); + } - if (mask & 0x00300000) // cycle type - { - rdp.cycle_mode = (uint8_t)((rdp.othermode_h & 0x00300000) >> 20); - rdp.update |= UPDATE_ZBUF_ENABLED; - FRDP ("cycletype: %d\n", rdp.cycle_mode); - } + if (mask & 0x00300000) // cycle type + { + rdp.cycle_mode = (uint8_t)((rdp.othermode_h & 0x00300000) >> 20); + rdp.update |= UPDATE_ZBUF_ENABLED; + FRDP("cycletype: %d\n", rdp.cycle_mode); + } - if (mask & 0x00010000) // LOD enable - { - rdp.LOD_en = (rdp.othermode_h & 0x00010000) ? TRUE : FALSE; - FRDP ("LOD_en: %d\n", rdp.LOD_en); - } + if (mask & 0x00010000) // LOD enable + { + rdp.LOD_en = (rdp.othermode_h & 0x00010000) ? TRUE : FALSE; + FRDP("LOD_en: %d\n", rdp.LOD_en); + } - if (mask & 0x00080000) // Persp enable - { - if (rdp.persp_supported) - rdp.Persp_en = (rdp.othermode_h & 0x00080000) ? TRUE : FALSE; - FRDP ("Persp_en: %d\n", rdp.Persp_en); - } + if (mask & 0x00080000) // Persp enable + { + if (rdp.persp_supported) + rdp.Persp_en = (rdp.othermode_h & 0x00080000) ? TRUE : FALSE; + FRDP("Persp_en: %d\n", rdp.Persp_en); + } - uint32_t unk = mask & 0x0FFC60F0F; - if (unk) // unknown portions, LARGE - { - FRDP ("UNKNOWN PORTIONS: shift: %d, len: %d, unknowns: %08lx\n", shift, len, unk); - } + uint32_t unk = mask & 0x0FFC60F0F; + if (unk) // unknown portions, LARGE + { + FRDP("UNKNOWN PORTIONS: shift: %d, len: %d, unknowns: %08lx\n", shift, len, unk); + } } static void uc0_setothermode_l() { - LRDP("uc0:setothermode_l "); + LRDP("uc0:setothermode_l "); - int shift, len; - if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) - { - len = (rdp.cmd0 & 0xFF) + 1; - shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; - if (shift < 0) shift = 0; - } - else - { - len = rdp.cmd0 & 0xFF; - shift = (rdp.cmd0 >> 8) & 0xFF; - } + int shift, len; + if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) + { + len = (rdp.cmd0 & 0xFF) + 1; + shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; + if (shift < 0) shift = 0; + } + else + { + len = rdp.cmd0 & 0xFF; + shift = (rdp.cmd0 >> 8) & 0xFF; + } - uint32_t mask = 0; - int i = len; - for (; i; i--) - mask = (mask << 1) | 1; - mask <<= shift; + uint32_t mask = 0; + int i = len; + for (; i; i--) + mask = (mask << 1) | 1; + mask <<= shift; - rdp.cmd1 &= mask; - rdp.othermode_l &= ~mask; - rdp.othermode_l |= rdp.cmd1; + rdp.cmd1 &= mask; + rdp.othermode_l &= ~mask; + rdp.othermode_l |= rdp.cmd1; - if (mask & 0x00000003) // alpha compare - { - rdp.acmp = rdp.othermode_l & 0x00000003; - FRDP ("alpha compare %s\n", ACmp[rdp.acmp]); - rdp.update |= UPDATE_ALPHA_COMPARE; - } + if (mask & 0x00000003) // alpha compare + { + rdp.acmp = rdp.othermode_l & 0x00000003; + FRDP("alpha compare %s\n", ACmp[rdp.acmp]); + rdp.update |= UPDATE_ALPHA_COMPARE; + } - if (mask & 0x00000004) // z-src selection - { - rdp.zsrc = (rdp.othermode_l & 0x00000004) >> 2; - FRDP ("z-src sel: %s\n", str_zs[rdp.zsrc]); - FRDP ("z-src sel: %08lx\n", rdp.zsrc); - rdp.update |= UPDATE_ZBUF_ENABLED; - } + if (mask & 0x00000004) // z-src selection + { + rdp.zsrc = (rdp.othermode_l & 0x00000004) >> 2; + FRDP("z-src sel: %s\n", str_zs[rdp.zsrc]); + FRDP("z-src sel: %08lx\n", rdp.zsrc); + rdp.update |= UPDATE_ZBUF_ENABLED; + } - if (mask & 0xFFFFFFF8) // rendermode / blender bits - { - rdp.update |= UPDATE_FOG_ENABLED; //if blender has no fog bits, fog must be set off - rdp.render_mode_changed |= rdp.rm ^ rdp.othermode_l; - rdp.rm = rdp.othermode_l; - if (settings.flame_corona && (rdp.rm == 0x00504341)) //hack for flame's corona - rdp.othermode_l |= /*0x00000020 |*/ 0x00000010; - FRDP ("rendermode: %08lx\n", rdp.othermode_l); // just output whole othermode_l - } + if (mask & 0xFFFFFFF8) // rendermode / blender bits + { + rdp.update |= UPDATE_FOG_ENABLED; //if blender has no fog bits, fog must be set off + rdp.render_mode_changed |= rdp.rm ^ rdp.othermode_l; + rdp.rm = rdp.othermode_l; + if (settings.flame_corona && (rdp.rm == 0x00504341)) //hack for flame's corona + rdp.othermode_l |= /*0x00000020 |*/ 0x00000010; + FRDP("rendermode: %08lx\n", rdp.othermode_l); // just output whole othermode_l + } - // there is not one setothermode_l that's not handled :) + // there is not one setothermode_l that's not handled :) } static void uc0_setgeometrymode() { - rdp.geom_mode |= rdp.cmd1; - FRDP("uc0:setgeometrymode %08lx; result: %08lx\n", rdp.cmd1, rdp.geom_mode); + rdp.geom_mode |= rdp.cmd1; + FRDP("uc0:setgeometrymode %08lx; result: %08lx\n", rdp.cmd1, rdp.geom_mode); - if (rdp.cmd1 & 0x00000001) // Z-Buffer enable - { - if (!(rdp.flags & ZBUF_ENABLED)) + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable { - rdp.flags |= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } } - } - if (rdp.cmd1 & 0x00001000) // Front culling - { - if (!(rdp.flags & CULL_FRONT)) + if (rdp.cmd1 & 0x00001000) // Front culling { - rdp.flags |= CULL_FRONT; - rdp.update |= UPDATE_CULL_MODE; + if (!(rdp.flags & CULL_FRONT)) + { + rdp.flags |= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } } - } - if (rdp.cmd1 & 0x00002000) // Back culling - { - if (!(rdp.flags & CULL_BACK)) + if (rdp.cmd1 & 0x00002000) // Back culling { - rdp.flags |= CULL_BACK; - rdp.update |= UPDATE_CULL_MODE; + if (!(rdp.flags & CULL_BACK)) + { + rdp.flags |= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } } - } - //Added by Gonetz - if (rdp.cmd1 & 0x00010000) // Fog enable - { - if (!(rdp.flags & FOG_ENABLED)) + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable { - rdp.flags |= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } } - } } static void uc0_cleargeometrymode() { - FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); + FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); - rdp.geom_mode &= (~rdp.cmd1); + rdp.geom_mode &= (~rdp.cmd1); - if (rdp.cmd1 & 0x00000001) // Z-Buffer enable - { - if (rdp.flags & ZBUF_ENABLED) + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable { - rdp.flags ^= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; + if (rdp.flags & ZBUF_ENABLED) + { + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } } - } - if (rdp.cmd1 & 0x00001000) // Front culling - { - if (rdp.flags & CULL_FRONT) + if (rdp.cmd1 & 0x00001000) // Front culling { - rdp.flags ^= CULL_FRONT; - rdp.update |= UPDATE_CULL_MODE; + if (rdp.flags & CULL_FRONT) + { + rdp.flags ^= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } } - } - if (rdp.cmd1 & 0x00002000) // Back culling - { - if (rdp.flags & CULL_BACK) + if (rdp.cmd1 & 0x00002000) // Back culling { - rdp.flags ^= CULL_BACK; - rdp.update |= UPDATE_CULL_MODE; + if (rdp.flags & CULL_BACK) + { + rdp.flags ^= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } } - } - //Added by Gonetz - if (rdp.cmd1 & 0x00010000) // Fog enable - { - if (rdp.flags & FOG_ENABLED) + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable { - rdp.flags ^= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } } - } } static void uc0_line3d() { - uint32_t v0 = ((rdp.cmd1 >> 16) & 0xff) / 10; - uint32_t v1 = ((rdp.cmd1 >> 8) & 0xff) / 10; - uint16_t width = (uint16_t)(rdp.cmd1 & 0xFF) + 3; + uint32_t v0 = ((rdp.cmd1 >> 16) & 0xff) / 10; + uint32_t v1 = ((rdp.cmd1 >> 8) & 0xff) / 10; + uint16_t width = (uint16_t)(rdp.cmd1 & 0xFF) + 3; - VERTEX *v[3] = { - &rdp.vtx[v1], - &rdp.vtx[v0], - &rdp.vtx[v0] - }; - uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; - rdp.flags |= CULLMASK; - rdp.update |= UPDATE_CULL_MODE; - rsp_tri1(v, width); - rdp.flags ^= CULLMASK; - rdp.flags |= cull_mode << CULLSHIFT; - rdp.update |= UPDATE_CULL_MODE; + VERTEX *v[3] = { + &rdp.vtx[v1], + &rdp.vtx[v0], + &rdp.vtx[v0] + }; + uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; - FRDP("uc0:line3d v0:%d, v1:%d, width:%d\n", v0, v1, width); + FRDP("uc0:line3d v0:%d, v1:%d, width:%d\n", v0, v1, width); } -static void uc0_tri4 () +static void uc0_tri4() { - // c0: 0000 0123, c1: 456789ab - // becomes: 405 617 829 a3b + // c0: 0000 0123, c1: 456789ab + // becomes: 405 617 829 a3b - LRDP("uc0:tri4"); - FRDP(" #%d, #%d, #%d, #%d - %d, %d, %d - %d, %d, %d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, rdp.tri_n+2, rdp.tri_n+3, - (rdp.cmd1 >> 28) & 0xF, - (rdp.cmd0 >> 12) & 0xF, - (rdp.cmd1 >> 24) & 0xF, - (rdp.cmd1 >> 20) & 0xF, - (rdp.cmd0 >> 8) & 0xF, - (rdp.cmd1 >> 16) & 0xF, - (rdp.cmd1 >> 12) & 0xF, - (rdp.cmd0 >> 4) & 0xF, - (rdp.cmd1 >> 8) & 0xF, - (rdp.cmd1 >> 4) & 0xF, - (rdp.cmd0 >> 0) & 0xF, - (rdp.cmd1 >> 0) & 0xF); + LRDP("uc0:tri4"); + FRDP(" #%d, #%d, #%d, #%d - %d, %d, %d - %d, %d, %d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n + 1, rdp.tri_n + 2, rdp.tri_n + 3, + (rdp.cmd1 >> 28) & 0xF, + (rdp.cmd0 >> 12) & 0xF, + (rdp.cmd1 >> 24) & 0xF, + (rdp.cmd1 >> 20) & 0xF, + (rdp.cmd0 >> 8) & 0xF, + (rdp.cmd1 >> 16) & 0xF, + (rdp.cmd1 >> 12) & 0xF, + (rdp.cmd0 >> 4) & 0xF, + (rdp.cmd1 >> 8) & 0xF, + (rdp.cmd1 >> 4) & 0xF, + (rdp.cmd0 >> 0) & 0xF, + (rdp.cmd1 >> 0) & 0xF); - VERTEX *v[12] = { - &rdp.vtx[(rdp.cmd1 >> 28) & 0xF], - &rdp.vtx[(rdp.cmd0 >> 12) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 24) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 20) & 0xF], - &rdp.vtx[(rdp.cmd0 >> 8) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 16) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 12) & 0xF], - &rdp.vtx[(rdp.cmd0 >> 4) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 8) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 4) & 0xF], - &rdp.vtx[(rdp.cmd0 >> 0) & 0xF], - &rdp.vtx[(rdp.cmd1 >> 0) & 0xF], - }; + VERTEX *v[12] = { + &rdp.vtx[(rdp.cmd1 >> 28) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 12) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 24) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 20) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 8) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 16) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 12) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 4) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 8) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 4) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 0) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 0) & 0xF], + }; - int updated = 0; + int updated = 0; - if (cull_tri(v)) - rdp.tri_n ++; - else - { - updated = 1; - update (); - - draw_tri (v); - rdp.tri_n ++; - } - - if (cull_tri(v+3)) - rdp.tri_n ++; - else - { - if (!updated) + if (cull_tri(v)) + rdp.tri_n++; + else { - updated = 1; - update (); + updated = 1; + update(); + + draw_tri(v); + rdp.tri_n++; } - draw_tri (v+3); - rdp.tri_n ++; - } - - if (cull_tri(v+6)) - rdp.tri_n ++; - else - { - if (!updated) + if (cull_tri(v + 3)) + rdp.tri_n++; + else { - updated = 1; - update (); + if (!updated) + { + updated = 1; + update(); + } + + draw_tri(v + 3); + rdp.tri_n++; } - draw_tri (v+6); - rdp.tri_n ++; - } - - if (cull_tri(v+9)) - rdp.tri_n ++; - else - { - if (!updated) + if (cull_tri(v + 6)) + rdp.tri_n++; + else { - updated = 1; - update (); + if (!updated) + { + updated = 1; + update(); + } + + draw_tri(v + 6); + rdp.tri_n++; } - draw_tri (v+9); - rdp.tri_n ++; - } + if (cull_tri(v + 9)) + rdp.tri_n++; + else + { + if (!updated) + { + updated = 1; + update(); + } + + draw_tri(v + 9); + rdp.tri_n++; + } } diff --git a/Source/Glide64/ucode01.h b/Source/Glide64/ucode01.h index 819653617..1a61831d4 100644 --- a/Source/Glide64/ucode01.h +++ b/Source/Glide64/ucode01.h @@ -43,9 +43,9 @@ static void uc1_vertex() { - int v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex - int n = (rdp.cmd0 >> 10) & 0x3F; // Number to copy - rsp_vertex(v0, n); + int v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex + int n = (rdp.cmd0 >> 10) & 0x3F; // Number to copy + rsp_vertex(v0, n); } // @@ -54,110 +54,110 @@ static void uc1_vertex() static void uc1_tri1() { - if (rdp.skip_drawing) - { - LRDP("uc1:tri1. skipped\n"); - return; - } - FRDP("uc1:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, - ((rdp.cmd1 >> 17) & 0x7F), - ((rdp.cmd1 >> 9) & 0x7F), - ((rdp.cmd1 >> 1) & 0x7F), rdp.cmd0, rdp.cmd1); - - VERTEX *v[3] = { - &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] - }; - - rsp_tri1(v); + if (rdp.skip_drawing) + { + LRDP("uc1:tri1. skipped\n"); + return; + } + FRDP("uc1:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F), rdp.cmd0, rdp.cmd1); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri1(v); } -static void uc1_tri2 () +static void uc1_tri2() { - if (rdp.skip_drawing) - { - LRDP("uc1:tri2. skipped\n"); - return; - } - LRDP("uc1:tri2"); - - FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, - ((rdp.cmd0 >> 17) & 0x7F), - ((rdp.cmd0 >> 9) & 0x7F), - ((rdp.cmd0 >> 1) & 0x7F), - ((rdp.cmd1 >> 17) & 0x7F), - ((rdp.cmd1 >> 9) & 0x7F), - ((rdp.cmd1 >> 1) & 0x7F)); - - VERTEX *v[6] = { - &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] - }; - - rsp_tri2(v); + if (rdp.skip_drawing) + { + LRDP("uc1:tri2. skipped\n"); + return; + } + LRDP("uc1:tri2"); + + FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n + 1, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F), + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F)); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri2(v); } static void uc1_line3d() { - if (!settings.force_quad3d && ((rdp.cmd1&0xFF000000) == 0) && ((rdp.cmd0&0x00FFFFFF) == 0)) - { - uint16_t width = (uint16_t)(rdp.cmd1&0xFF) + 3; - - FRDP("uc1:line3d width: %d #%d, #%d - %d, %d\n", width, rdp.tri_n, rdp.tri_n+1, - (rdp.cmd1 >> 17) & 0x7F, - (rdp.cmd1 >> 9) & 0x7F); - - VERTEX *v[3] = { - &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] - }; - uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; - rdp.flags |= CULLMASK; - rdp.update |= UPDATE_CULL_MODE; - rsp_tri1(v, width); - rdp.flags ^= CULLMASK; - rdp.flags |= cull_mode << CULLSHIFT; - rdp.update |= UPDATE_CULL_MODE; - } - else - { - FRDP("uc1:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); - - VERTEX *v[6] = { - &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] - }; - - rsp_tri2(v); - } + if (!settings.force_quad3d && ((rdp.cmd1 & 0xFF000000) == 0) && ((rdp.cmd0 & 0x00FFFFFF) == 0)) + { + uint16_t width = (uint16_t)(rdp.cmd1 & 0xFF) + 3; + + FRDP("uc1:line3d width: %d #%d, #%d - %d, %d\n", width, rdp.tri_n, rdp.tri_n + 1, + (rdp.cmd1 >> 17) & 0x7F, + (rdp.cmd1 >> 9) & 0x7F); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] + }; + uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; + } + else + { + FRDP("uc1:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n + 1); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] + }; + + rsp_tri2(v); + } } uint32_t branch_dl = 0; static void uc1_rdphalf_1() { - LRDP("uc1:rdphalf_1\n"); - branch_dl = rdp.cmd1; - rdphalf_1(); + LRDP("uc1:rdphalf_1\n"); + branch_dl = rdp.cmd1; + rdphalf_1(); } static void uc1_branch_z() { - uint32_t addr = segoffset(branch_dl); - FRDP ("uc1:branch_less_z, addr: %08lx\n", addr); - uint32_t vtx = (rdp.cmd0 & 0xFFF) >> 1; - if( fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/) ) - { - rdp.pc[rdp.pc_i] = addr; - } + uint32_t addr = segoffset(branch_dl); + FRDP("uc1:branch_less_z, addr: %08lx\n", addr); + uint32_t vtx = (rdp.cmd0 & 0xFFF) >> 1; + if (fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/)) + { + rdp.pc[rdp.pc_i] = addr; + } } diff --git a/Source/Glide64/ucode02.h b/Source/Glide64/ucode02.h index 6c1887ed2..0210037c0 100644 --- a/Source/Glide64/ucode02.h +++ b/Source/Glide64/ucode02.h @@ -37,776 +37,775 @@ // //**************************************************************** -static void calc_point_light (VERTEX *v, float * vpos) +static void calc_point_light(VERTEX *v, float * vpos) { - float light_intensity = 0.0f; - register float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; - for (uint32_t l=0; l 0.0f) - light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); + float at = rdp.light[l].ca + light_len / 65535.0f*rdp.light[l].la + light_len2 / 65535.0f*rdp.light[l].qa; + if (at > 0.0f) + light_intensity = 1 / at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); + else + light_intensity = 0.0f; + } else - light_intensity = 0.0f; + { + light_intensity = 0.0f; + } + if (light_intensity > 0.0f) + { + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + } } - else - { - light_intensity = 0.0f; - } - if (light_intensity > 0.0f) - { - color[0] += rdp.light[l].r * light_intensity; - color[1] += rdp.light[l].g * light_intensity; - color[2] += rdp.light[l].b * light_intensity; - } - } - if (color[0] > 1.0f) color[0] = 1.0f; - if (color[1] > 1.0f) color[1] = 1.0f; - if (color[2] > 1.0f) color[2] = 1.0f; + if (color[0] > 1.0f) color[0] = 1.0f; + if (color[1] > 1.0f) color[1] = 1.0f; + if (color[2] > 1.0f) color[2] = 1.0f; - v->r = (uint8_t)(color[0]*255.0f); - v->g = (uint8_t)(color[1]*255.0f); - v->b = (uint8_t)(color[2]*255.0f); + v->r = (uint8_t)(color[0] * 255.0f); + v->g = (uint8_t)(color[1] * 255.0f); + v->b = (uint8_t)(color[2] * 255.0f); } static void uc6_obj_rectangle(); -static void uc2_vertex () +static void uc2_vertex() { - if (!(rdp.cmd0 & 0x00FFFFFF)) - { - uc6_obj_rectangle(); - return; - } - - // This is special, not handled in update(), but here - // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) - if (rdp.update & UPDATE_MULT_MAT) - { - rdp.update ^= UPDATE_MULT_MAT; - MulMatrices(rdp.model, rdp.proj, rdp.combined); - } - if (rdp.update & UPDATE_LIGHTS) - { - rdp.update ^= UPDATE_LIGHTS; - - // Calculate light vectors - for (uint32_t l=0; l> 12) & 0xFF; - rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; - - FRDP ("uc2:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); - - if (v0 < 0) - { - RDP_E ("** ERROR: uc2:vertex v0 < 0\n"); - LRDP("** ERROR: uc2:vertex v0 < 0\n"); - return; - } - - uint32_t geom_mode = rdp.geom_mode; - if ((settings.hacks&hack_Fzero) && (rdp.geom_mode & 0x40000)) - { - if (((short*)gfx.RDRAM)[(((addr) >> 1) + 4)^1] || ((short*)gfx.RDRAM)[(((addr) >> 1) + 5)^1]) - rdp.geom_mode ^= 0x40000; - } - for (i=0; i < (n<<4); i+=16) - { - VERTEX *v = &rdp.vtx[v0 + (i>>4)]; - x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; - y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; - z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; - v->flags = ((uint16_t*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; - v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; - v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; - v->uv_scaled = 0; - v->a = ((uint8_t*)gfx.RDRAM)[(addr+i + 15)^3]; - - v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; - v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; - v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; - v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; - - if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; - CalculateFog (v); - - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - v->shade_mod = 0; - - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; -// if (v->z_w > 1.0f) v->scr_off |= 32; - - if (rdp.geom_mode & 0x00020000) + // This is special, not handled in update(), but here + // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) + if (rdp.update & UPDATE_MULT_MAT) { - v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3]; - v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3]; - v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3]; - // FRDP("Calc light. x: %f, y: %f z: %f\n", v->vec[0], v->vec[1], v->vec[2]); - // if (!(rdp.geom_mode & 0x800000)) - { - if (rdp.geom_mode & 0x40000) + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (uint32_t l = 0; l < rdp.num_lights; l++) { - if (rdp.geom_mode & 0x80000) - { - calc_linear (v); -#ifdef EXTREME_LOGGING - FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } - else - { - calc_sphere (v); -#ifdef EXTREME_LOGGING - FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } + InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model); + NormalizeVector(rdp.light_vector[l]); } - } - if (rdp.geom_mode & 0x00400000) - { - float tmpvec[3] = {x, y, z}; - calc_point_light (v, tmpvec); - } - else - { - NormalizeVector (v->vec); - calc_light (v); - } } - else + + uint32_t addr = segoffset(rdp.cmd1); + int v0, i, n; + float x, y, z; + + rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF; + rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; + + FRDP("uc2:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + + if (v0 < 0) { - v->r = ((uint8_t*)gfx.RDRAM)[(addr+i + 12)^3]; - v->g = ((uint8_t*)gfx.RDRAM)[(addr+i + 13)^3]; - v->b = ((uint8_t*)gfx.RDRAM)[(addr+i + 14)^3]; + RDP_E("** ERROR: uc2:vertex v0 < 0\n"); + LRDP("** ERROR: uc2:vertex v0 < 0\n"); + return; } + + uint32_t geom_mode = rdp.geom_mode; + if ((settings.hacks&hack_Fzero) && (rdp.geom_mode & 0x40000)) + { + if (((short*)gfx.RDRAM)[(((addr) >> 1) + 4) ^ 1] || ((short*)gfx.RDRAM)[(((addr) >> 1) + 5) ^ 1]) + rdp.geom_mode ^= 0x40000; + } + for (i = 0; i < (n << 4); i += 16) + { + VERTEX *v = &rdp.vtx[v0 + (i >> 4)]; + x = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 0) ^ 1]; + y = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 1) ^ 1]; + z = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 2) ^ 1]; + v->flags = ((uint16_t*)gfx.RDRAM)[(((addr + i) >> 1) + 3) ^ 1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 4) ^ 1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 5) ^ 1]; + v->uv_scaled = 0; + v->a = ((uint8_t*)gfx.RDRAM)[(addr + i + 15) ^ 3]; + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + CalculateFog(v); + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + // if (v->z_w > 1.0f) v->scr_off |= 32; + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = ((char*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->vec[1] = ((char*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->vec[2] = ((char*)gfx.RDRAM)[(addr + i + 14) ^ 3]; + // FRDP("Calc light. x: %f, y: %f z: %f\n", v->vec[0], v->vec[1], v->vec[2]); + // if (!(rdp.geom_mode & 0x800000)) + { + if (rdp.geom_mode & 0x40000) + { + if (rdp.geom_mode & 0x80000) + { + calc_linear(v); #ifdef EXTREME_LOGGING - FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); + FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); #endif - } - rdp.geom_mode = geom_mode; + } + else + { + calc_sphere(v); +#ifdef EXTREME_LOGGING + FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + } + } + if (rdp.geom_mode & 0x00400000) + { + float tmpvec[3] = { x, y, z }; + calc_point_light(v, tmpvec); + } + else + { + NormalizeVector(v->vec); + calc_light(v); + } + } + else + { + v->r = ((uint8_t*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->g = ((uint8_t*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->b = ((uint8_t*)gfx.RDRAM)[(addr + i + 14) ^ 3]; + } +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); +#endif + } + rdp.geom_mode = geom_mode; } -static void uc2_modifyvtx () +static void uc2_modifyvtx() { - uint8_t where = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); - uint16_t vtx = (uint16_t)((rdp.cmd0 >> 1) & 0xFFFF); + uint8_t where = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); + uint16_t vtx = (uint16_t)((rdp.cmd0 >> 1) & 0xFFFF); - FRDP ("uc2:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); - uc0_modifyvtx(where, vtx, rdp.cmd1); + FRDP("uc2:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); + uc0_modifyvtx(where, vtx, rdp.cmd1); } -static void uc2_culldl () +static void uc2_culldl() { - uint16_t vStart = (uint16_t)(rdp.cmd0 & 0xFFFF) >> 1; - uint16_t vEnd = (uint16_t)(rdp.cmd1 & 0xFFFF) >> 1; - uint32_t cond = 0; - FRDP ("uc2:culldl start: %d, end: %d\n", vStart, vEnd); + uint16_t vStart = (uint16_t)(rdp.cmd0 & 0xFFFF) >> 1; + uint16_t vEnd = (uint16_t)(rdp.cmd1 & 0xFFFF) >> 1; + uint32_t cond = 0; + FRDP("uc2:culldl start: %d, end: %d\n", vStart, vEnd); - if (vEnd < vStart) return; - for (uint16_t i=vStart; i<=vEnd; i++) - { - /* - VERTEX v = &rdp.vtx[i]; - // Check if completely off the screen (quick frustrum clipping for 90 FOV) - if (v->x >= -v->w) - cond |= 0x01; - if (v->x <= v->w) - cond |= 0x02; - if (v->y >= -v->w) - cond |= 0x04; - if (v->y <= v->w) - cond |= 0x08; - if (v->w >= 0.1f) - cond |= 0x10; + if (vEnd < vStart) return; + for (uint16_t i = vStart; i <= vEnd; i++) + { + /* + VERTEX v = &rdp.vtx[i]; + // Check if completely off the screen (quick frustrum clipping for 90 FOV) + if (v->x >= -v->w) + cond |= 0x01; + if (v->x <= v->w) + cond |= 0x02; + if (v->y >= -v->w) + cond |= 0x04; + if (v->y <= v->w) + cond |= 0x08; + if (v->w >= 0.1f) + cond |= 0x10; - if (cond == 0x1F) - return; - //*/ + if (cond == 0x1F) + return; + //*/ #ifdef EXTREME_LOGGING - FRDP (" v[%d] = (%02f, %02f, %02f, 0x%02lx)\n", i, rdp.vtx[i].x, rdp.vtx[i].y, rdp.vtx[i].w, rdp.vtx[i].scr_off); + FRDP (" v[%d] = (%02f, %02f, %02f, 0x%02lx)\n", i, rdp.vtx[i].x, rdp.vtx[i].y, rdp.vtx[i].w, rdp.vtx[i].scr_off); #endif - cond |= (~rdp.vtx[i].scr_off) & 0x1F; - if (cond == 0x1F) - return; - } + cond |= (~rdp.vtx[i].scr_off) & 0x1F; + if (cond == 0x1F) + return; + } - LRDP(" - "); // specify that the enddl is not a real command - uc0_enddl (); + LRDP(" - "); // specify that the enddl is not a real command + uc0_enddl(); } -static void uc6_obj_loadtxtr (); +static void uc6_obj_loadtxtr(); static void uc2_tri1() { - if ((rdp.cmd0 & 0x00FFFFFF) == 0x17) - { - uc6_obj_loadtxtr (); - return; - } - if (rdp.skip_drawing) - { - LRDP("uc2:tri1. skipped\n"); - return; - } - - FRDP("uc2:tri1 #%d - %d, %d, %d\n", rdp.tri_n, - ((rdp.cmd0 >> 17) & 0x7F), - ((rdp.cmd0 >> 9) & 0x7F), - ((rdp.cmd0 >> 1) & 0x7F)); - - VERTEX *v[3] = { - &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F] - }; - - rsp_tri1(v); -} - -static void uc6_obj_ldtx_sprite (); -static void uc6_obj_ldtx_rect (); - -static void uc2_quad () -{ - if ((rdp.cmd0 & 0x00FFFFFF) == 0x2F) - { - uint32_t command = rdp.cmd0>>24; - if (command == 0x6) + if ((rdp.cmd0 & 0x00FFFFFF) == 0x17) { - uc6_obj_ldtx_sprite (); - return; + uc6_obj_loadtxtr(); + return; } - if (command == 0x7) + if (rdp.skip_drawing) { - uc6_obj_ldtx_rect (); - return; + LRDP("uc2:tri1. skipped\n"); + return; } - } - if (rdp.skip_drawing) - { - LRDP("uc2_quad. skipped\n"); - return; - } - - LRDP("uc2:quad"); - - FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, - ((rdp.cmd0 >> 17) & 0x7F), - ((rdp.cmd0 >> 9) & 0x7F), - ((rdp.cmd0 >> 1) & 0x7F), - ((rdp.cmd1 >> 17) & 0x7F), - ((rdp.cmd1 >> 9) & 0x7F), - ((rdp.cmd1 >> 1) & 0x7F)); - - VERTEX *v[6] = { - &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] - }; - - rsp_tri2(v); -} - -static void uc6_ldtx_rect_r (); - -static void uc2_line3d () -{ - if ( (rdp.cmd0&0xFF) == 0x2F ) - uc6_ldtx_rect_r (); - else - { - FRDP("uc2:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n+1, - (rdp.cmd0 >> 17) & 0x7F, - (rdp.cmd0 >> 9) & 0x7F); + FRDP("uc2:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F)); VERTEX *v[3] = { - &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], - &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F] + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F] }; - uint16_t width = (uint16_t)(rdp.cmd0 + 3)&0xFF; - uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; - rdp.flags |= CULLMASK; - rdp.update |= UPDATE_CULL_MODE; - rsp_tri1(v, width); - rdp.flags ^= CULLMASK; - rdp.flags |= cull_mode << CULLSHIFT; - rdp.update |= UPDATE_CULL_MODE; - } + + rsp_tri1(v); } -static void uc2_special3 () +static void uc6_obj_ldtx_sprite(); +static void uc6_obj_ldtx_rect(); + +static void uc2_quad() { - LRDP("uc2:special3\n"); -} - -static void uc2_special2 () -{ - LRDP("uc2:special2\n"); -} - -static void uc2_dma_io () -{ - LRDP("uc2:dma_io\n"); -} - -static void uc2_pop_matrix () -{ - FRDP ("uc2:pop_matrix %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); - - // Just pop the modelview matrix - modelview_pop (rdp.cmd1 >> 6); -} - -static void uc2_geom_mode () -{ - // Switch around some things - uint32_t clr_mode = (rdp.cmd0 & 0x00DFC9FF) | - ((rdp.cmd0 & 0x00000600) << 3) | - ((rdp.cmd0 & 0x00200000) >> 12) | 0xFF000000; - uint32_t set_mode = (rdp.cmd1 & 0xFFDFC9FF) | - ((rdp.cmd1 & 0x00000600) << 3) | - ((rdp.cmd1 & 0x00200000) >> 12); - - FRDP("uc2:geom_mode c:%08lx, s:%08lx ", clr_mode, set_mode); - - rdp.geom_mode &= clr_mode; - rdp.geom_mode |= set_mode; - - FRDP ("result:%08lx\n", rdp.geom_mode); - - if (rdp.geom_mode & 0x00000001) // Z-Buffer enable - { - if (!(rdp.flags & ZBUF_ENABLED)) + if ((rdp.cmd0 & 0x00FFFFFF) == 0x2F) { - rdp.flags |= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; - } - } - else - { - if ((rdp.flags & ZBUF_ENABLED)) - { - if (!settings.flame_corona || (rdp.rm != 0x00504341)) //hack for flame's corona - rdp.flags ^= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; - } - } - if (rdp.geom_mode & 0x00001000) // Front culling - { - if (!(rdp.flags & CULL_FRONT)) - { - rdp.flags |= CULL_FRONT; - rdp.update |= UPDATE_CULL_MODE; - } - } - else - { - if (rdp.flags & CULL_FRONT) - { - rdp.flags ^= CULL_FRONT; - rdp.update |= UPDATE_CULL_MODE; - } - } - if (rdp.geom_mode & 0x00002000) // Back culling - { - if (!(rdp.flags & CULL_BACK)) - { - rdp.flags |= CULL_BACK; - rdp.update |= UPDATE_CULL_MODE; - } - } - else - { - if (rdp.flags & CULL_BACK) - { - rdp.flags ^= CULL_BACK; - rdp.update |= UPDATE_CULL_MODE; - } - } - - //Added by Gonetz - if (rdp.geom_mode & 0x00010000) // Fog enable - { - if (!(rdp.flags & FOG_ENABLED)) - { - rdp.flags |= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; - } - } - else - { - if (rdp.flags & FOG_ENABLED) - { - rdp.flags ^= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; - } - } -} - -static void uc6_obj_rectangle_r (); - -static void uc2_matrix () -{ - if (!(rdp.cmd0 & 0x00FFFFFF)) - { - uc6_obj_rectangle_r(); - return; - } - LRDP("uc2:matrix\n"); - - DECLAREALIGN16VAR(m[4][4]); - load_matrix(m, segoffset(rdp.cmd1)); - - uint8_t command = (uint8_t)((rdp.cmd0 ^ 1) & 0xFF); - switch (command) - { - case 0: // modelview mul nopush - LRDP("modelview mul\n"); - modelview_mul (m); - break; - - case 1: // modelview mul push - LRDP("modelview mul push\n"); - modelview_mul_push (m); - break; - - case 2: // modelview load nopush - LRDP("modelview load\n"); - modelview_load (m); - break; - - case 3: // modelview load push - LRDP("modelview load push\n"); - modelview_load_push (m); - break; - - case 4: // projection mul nopush - case 5: // projection mul push, can't push projection - LRDP("projection mul\n"); - projection_mul (m); - break; - - case 6: // projection load nopush - case 7: // projection load push, can't push projection - LRDP("projection load\n"); - projection_load (m); - break; - - default: - FRDP_E ("Unknown matrix command, %02lx", command); - FRDP ("Unknown matrix command, %02lx", command); - } - -#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 -} - -static void uc2_moveword () -{ - uint8_t index = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); - uint16_t offset = (uint16_t)(rdp.cmd0 & 0xFFFF); - uint32_t data = rdp.cmd1; - - FRDP ("uc2:moveword "); - - switch (index) - { - // NOTE: right now it's assuming that it sets the integer part first. This could - // be easily fixed, but only if i had something to test with. - - case 0x00: // moveword matrix - { - // do matrix pre-mult so it's re-updated next time - if (rdp.update & UPDATE_MULT_MAT) - { - rdp.update ^= UPDATE_MULT_MAT; - MulMatrices(rdp.model, rdp.proj, rdp.combined); - } - - if (rdp.cmd0 & 0x20) // fractional part - { - int index_x = (rdp.cmd0 & 0x1F) >> 1; - int index_y = index_x >> 2; - index_x &= 3; - - float fpart = (rdp.cmd1>>16)/65536.0f; - rdp.combined[index_y][index_x] = (float)(int)rdp.combined[index_y][index_x]; - rdp.combined[index_y][index_x] += fpart; - - fpart = (rdp.cmd1&0xFFFF)/65536.0f; - rdp.combined[index_y][index_x+1] = (float)(int)rdp.combined[index_y][index_x+1]; - rdp.combined[index_y][index_x+1] += fpart; - } - else - { - int index_x = (rdp.cmd0 & 0x1F) >> 1; - int index_y = index_x >> 2; - index_x &= 3; - - rdp.combined[index_y][index_x] = (short)(rdp.cmd1>>16); - rdp.combined[index_y][index_x+1] = (short)(rdp.cmd1&0xFFFF); - } - - LRDP("matrix\n"); - } - break; - - case 0x02: - rdp.num_lights = data / 24; - rdp.update |= UPDATE_LIGHTS; - FRDP ("numlights: %d\n", rdp.num_lights); - break; - - case 0x04: - if (offset == 0x04) - { - rdp.clip_ratio = sqrt((float)rdp.cmd1); - rdp.update |= UPDATE_VIEWPORT; - } - FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); - break; - - case 0x06: // moveword SEGMENT - { - FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2); - if ((data&BMASK)> 2) & 0xF] = data; - } - break; - - - case 0x08: - { - rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); - rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); - FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); - - //offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte - //low-level display list has setothermode commands in this place, so this is obviously not move_fog. - if (offset == 0x04) - rdp.tlut_mode = (data == 0xffffffff) ? 0 : 2; - } - break; - - case 0x0a: // moveword LIGHTCOL - { - int n = offset / 24; - FRDP ("lightcol light:%d, %08lx\n", n, data); - - rdp.light[n].r = (float)((data >> 24) & 0xFF) / 255.0f; - rdp.light[n].g = (float)((data >> 16) & 0xFF) / 255.0f; - rdp.light[n].b = (float)((data >> 8) & 0xFF) / 255.0f; - rdp.light[n].a = 255; - } - break; - - case 0x0c: - RDP_E ("uc2:moveword forcemtx - IGNORED\n"); - LRDP("forcemtx - IGNORED\n"); - break; - - case 0x0e: - LRDP("perspnorm - IGNORED\n"); - break; - - default: - FRDP_E("uc2:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); - FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); - } -} - -static void uc6_obj_movemem (); - -static void uc2_movemem () -{ - int idx = rdp.cmd0 & 0xFF; - uint32_t addr = segoffset(rdp.cmd1); - int ofs = (rdp.cmd0 >> 5) & 0x7F8; - - FRDP ("uc2:movemem ofs:%d ", ofs); - - switch (idx) - { - case 0: - case 2: - uc6_obj_movemem (); - break; - - case 8: // VIEWPORT - { - uint32_t 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]; - 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.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; - - rdp.update |= UPDATE_VIEWPORT; - - 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); - } - break; - - case 10: // LIGHT - { - int n = ofs / 24; - - if (n < 2) - { - char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3]; - rdp.lookat[n][0] = (float)(dir_x) / 127.0f; - char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3]; - rdp.lookat[n][1] = (float)(dir_y) / 127.0f; - char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3]; - rdp.lookat[n][2] = (float)(dir_z) / 127.0f; - rdp.use_lookat = TRUE; - if (n == 1) + uint32_t command = rdp.cmd0 >> 24; + if (command == 0x6) { - if (!dir_x && !dir_y) - rdp.use_lookat = FALSE; + uc6_obj_ldtx_sprite(); + return; + } + if (command == 0x7) + { + uc6_obj_ldtx_rect(); + return; } - FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); - return; - } - n -= 2; - if (n > 7) return; - - // Get the data - uint8_t col = gfx.RDRAM[(addr+0)^3]; - rdp.light[n].r = (float)col / 255.0f; - rdp.light[n].nonblack = col; - col = gfx.RDRAM[(addr+1)^3]; - rdp.light[n].g = (float)col / 255.0f; - rdp.light[n].nonblack += col; - col = gfx.RDRAM[(addr+2)^3]; - rdp.light[n].b = (float)col / 255.0f; - rdp.light[n].nonblack += col; - rdp.light[n].a = 1.0f; - // ** Thanks to Icepir8 for pointing this out ** - // Lighting must be signed byte instead of byte - rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f; - rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f; - rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f; - uint32_t a = addr >> 1; - rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+4)^1]); - rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+5)^1]); - rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+6)^1]); - rdp.light[n].ca = (float)(gfx.RDRAM[(addr+3)^3]) / 16.0f; - rdp.light[n].la = (float)(gfx.RDRAM[(addr+7)^3]); - rdp.light[n].qa = (float)(gfx.RDRAM[(addr+14)^3]) / 8.0f; -#ifdef EXTREME_LOGGING - FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, ca: %f, la:%f, qa: %f\n", - n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].ca, rdp.light[n].la, rdp.light[n].qa); -#endif - FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f. dir: x: %.3f, y: %.3f, z: %.3f\n", - n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, - rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); } - break; - case 14: // matrix + if (rdp.skip_drawing) { - // do not update the combined matrix! - rdp.update &= ~UPDATE_MULT_MAT; - load_matrix(rdp.combined, segoffset(rdp.cmd1)); + LRDP("uc2_quad. skipped\n"); + return; + } + + LRDP("uc2:quad"); + + FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n + 1, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F), + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F)); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri2(v); +} + +static void uc6_ldtx_rect_r(); + +static void uc2_line3d() +{ + if ((rdp.cmd0 & 0xFF) == 0x2F) + uc6_ldtx_rect_r(); + else + { + FRDP("uc2:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n + 1, + (rdp.cmd0 >> 17) & 0x7F, + (rdp.cmd0 >> 9) & 0x7F); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F] + }; + uint16_t width = (uint16_t)(rdp.cmd0 + 3) & 0xFF; + uint32_t cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; + } +} + +static void uc2_special3() +{ + LRDP("uc2:special3\n"); +} + +static void uc2_special2() +{ + LRDP("uc2:special2\n"); +} + +static void uc2_dma_io() +{ + LRDP("uc2:dma_io\n"); +} + +static void uc2_pop_matrix() +{ + FRDP("uc2:pop_matrix %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + + // Just pop the modelview matrix + modelview_pop(rdp.cmd1 >> 6); +} + +static void uc2_geom_mode() +{ + // Switch around some things + uint32_t clr_mode = (rdp.cmd0 & 0x00DFC9FF) | + ((rdp.cmd0 & 0x00000600) << 3) | + ((rdp.cmd0 & 0x00200000) >> 12) | 0xFF000000; + uint32_t set_mode = (rdp.cmd1 & 0xFFDFC9FF) | + ((rdp.cmd1 & 0x00000600) << 3) | + ((rdp.cmd1 & 0x00200000) >> 12); + + FRDP("uc2:geom_mode c:%08lx, s:%08lx ", clr_mode, set_mode); + + rdp.geom_mode &= clr_mode; + rdp.geom_mode |= set_mode; + + FRDP("result:%08lx\n", rdp.geom_mode); + + if (rdp.geom_mode & 0x00000001) // Z-Buffer enable + { + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + else + { + if ((rdp.flags & ZBUF_ENABLED)) + { + if (!settings.flame_corona || (rdp.rm != 0x00504341)) //hack for flame's corona + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + if (rdp.geom_mode & 0x00001000) // Front culling + { + if (!(rdp.flags & CULL_FRONT)) + { + rdp.flags |= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + else + { + if (rdp.flags & CULL_FRONT) + { + rdp.flags ^= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + if (rdp.geom_mode & 0x00002000) // Back culling + { + if (!(rdp.flags & CULL_BACK)) + { + rdp.flags |= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + else + { + if (rdp.flags & CULL_BACK) + { + rdp.flags ^= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + + //Added by Gonetz + if (rdp.geom_mode & 0x00010000) // Fog enable + { + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } + else + { + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} + +static void uc6_obj_rectangle_r(); + +static void uc2_matrix() +{ + if (!(rdp.cmd0 & 0x00FFFFFF)) + { + uc6_obj_rectangle_r(); + return; + } + LRDP("uc2:matrix\n"); + + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, segoffset(rdp.cmd1)); + + uint8_t command = (uint8_t)((rdp.cmd0 ^ 1) & 0xFF); + switch (command) + { + case 0: // modelview mul nopush + LRDP("modelview mul\n"); + modelview_mul(m); + break; + + case 1: // modelview mul push + LRDP("modelview mul push\n"); + modelview_mul_push(m); + break; + + case 2: // modelview load nopush + LRDP("modelview load\n"); + modelview_load(m); + break; + + case 3: // modelview load push + LRDP("modelview load push\n"); + modelview_load_push(m); + break; + + case 4: // projection mul nopush + case 5: // projection mul push, can't push projection + LRDP("projection mul\n"); + projection_mul(m); + break; + + case 6: // projection load nopush + case 7: // projection load push, can't push projection + LRDP("projection load\n"); + projection_load(m); + break; + + default: + FRDP_E("Unknown matrix command, %02lx", command); + FRDP("Unknown matrix command, %02lx", command); + } #ifdef EXTREME_LOGGING - FRDP ("{%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]); + 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 +} + +static void uc2_moveword() +{ + uint8_t index = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); + uint16_t offset = (uint16_t)(rdp.cmd0 & 0xFFFF); + uint32_t data = rdp.cmd1; + + FRDP("uc2:moveword "); + + switch (index) + { + // NOTE: right now it's assuming that it sets the integer part first. This could + // be easily fixed, but only if i had something to test with. + + case 0x00: // moveword matrix + { + // do matrix pre-mult so it's re-updated next time + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + + if (rdp.cmd0 & 0x20) // fractional part + { + int index_x = (rdp.cmd0 & 0x1F) >> 1; + int index_y = index_x >> 2; + index_x &= 3; + + float fpart = (rdp.cmd1 >> 16) / 65536.0f; + rdp.combined[index_y][index_x] = (float)(int)rdp.combined[index_y][index_x]; + rdp.combined[index_y][index_x] += fpart; + + fpart = (rdp.cmd1 & 0xFFFF) / 65536.0f; + rdp.combined[index_y][index_x + 1] = (float)(int)rdp.combined[index_y][index_x + 1]; + rdp.combined[index_y][index_x + 1] += fpart; + } + else + { + int index_x = (rdp.cmd0 & 0x1F) >> 1; + int index_y = index_x >> 2; + index_x &= 3; + + rdp.combined[index_y][index_x] = (short)(rdp.cmd1 >> 16); + rdp.combined[index_y][index_x + 1] = (short)(rdp.cmd1 & 0xFFFF); + } + + LRDP("matrix\n"); + } + break; + + case 0x02: + rdp.num_lights = data / 24; + rdp.update |= UPDATE_LIGHTS; + FRDP("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (offset == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // moveword SEGMENT + { + FRDP("SEGMENT %08lx -> seg%d\n", data, offset >> 2); + if ((data&BMASK) < BMASK) + rdp.segment[(offset >> 2) & 0xF] = data; + } + break; + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + + //offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte + //low-level display list has setothermode commands in this place, so this is obviously not move_fog. + if (offset == 0x04) + rdp.tlut_mode = (data == 0xffffffff) ? 0 : 2; + } + break; + + case 0x0a: // moveword LIGHTCOL + { + int n = offset / 24; + FRDP("lightcol light:%d, %08lx\n", n, data); + + rdp.light[n].r = (float)((data >> 24) & 0xFF) / 255.0f; + rdp.light[n].g = (float)((data >> 16) & 0xFF) / 255.0f; + rdp.light[n].b = (float)((data >> 8) & 0xFF) / 255.0f; + rdp.light[n].a = 255; + } + break; + + case 0x0c: + RDP_E("uc2:moveword forcemtx - IGNORED\n"); + LRDP("forcemtx - IGNORED\n"); + break; + + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; + + default: + FRDP_E("uc2:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + FRDP("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + } +} + +static void uc6_obj_movemem(); + +static void uc2_movemem() +{ + int idx = rdp.cmd0 & 0xFF; + uint32_t addr = segoffset(rdp.cmd1); + int ofs = (rdp.cmd0 >> 5) & 0x7F8; + + FRDP("uc2:movemem ofs:%d ", ofs); + + switch (idx) + { + case 0: + case 2: + uc6_obj_movemem(); + break; + + case 8: // VIEWPORT + { + uint32_t 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]; + 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.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; + + rdp.update |= UPDATE_VIEWPORT; + + 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); + } + break; + + case 10: // LIGHT + { + int n = ofs / 24; + + if (n < 2) + { + char dir_x = ((char*)gfx.RDRAM)[(addr + 8) ^ 3]; + rdp.lookat[n][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(addr + 9) ^ 3]; + rdp.lookat[n][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(addr + 10) ^ 3]; + rdp.lookat[n][2] = (float)(dir_z) / 127.0f; + rdp.use_lookat = TRUE; + if (n == 1) + { + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + } + FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); + return; + } + n -= 2; + if (n > 7) return; + + // Get the data + uint8_t col = gfx.RDRAM[(addr + 0) ^ 3]; + rdp.light[n].r = (float)col / 255.0f; + rdp.light[n].nonblack = col; + col = gfx.RDRAM[(addr + 1) ^ 3]; + rdp.light[n].g = (float)col / 255.0f; + rdp.light[n].nonblack += col; + col = gfx.RDRAM[(addr + 2) ^ 3]; + rdp.light[n].b = (float)col / 255.0f; + rdp.light[n].nonblack += col; + rdp.light[n].a = 1.0f; + // ** Thanks to Icepir8 for pointing this out ** + // Lighting must be signed byte instead of byte + rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr + 8) ^ 3]) / 127.0f; + rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr + 9) ^ 3]) / 127.0f; + rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr + 10) ^ 3]) / 127.0f; + uint32_t a = addr >> 1; + rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a + 4) ^ 1]); + rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a + 5) ^ 1]); + rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a + 6) ^ 1]); + rdp.light[n].ca = (float)(gfx.RDRAM[(addr + 3) ^ 3]) / 16.0f; + rdp.light[n].la = (float)(gfx.RDRAM[(addr + 7) ^ 3]); + rdp.light[n].qa = (float)(gfx.RDRAM[(addr + 14) ^ 3]) / 8.0f; +#ifdef EXTREME_LOGGING + FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, ca: %f, la:%f, qa: %f\n", + n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].ca, rdp.light[n].la, rdp.light[n].qa); +#endif + FRDP("light: n: %d, r: %.3f, g: %.3f, b: %.3f. dir: x: %.3f, y: %.3f, z: %.3f\n", + n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, + rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); + } + break; + + case 14: // matrix + { + // do not update the combined matrix! + rdp.update &= ~UPDATE_MULT_MAT; + load_matrix(rdp.combined, segoffset(rdp.cmd1)); + +#ifdef EXTREME_LOGGING + FRDP ("{%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 } break; - default: - FRDP ("uc2:matrix unknown (%d)\n", idx); - FRDP ("** UNKNOWN %d\n", idx); - } + default: + FRDP("uc2:matrix unknown (%d)\n", idx); + FRDP("** UNKNOWN %d\n", idx); + } } -static void uc2_load_ucode () +static void uc2_load_ucode() { - LRDP("uc2:load_ucode\n"); + LRDP("uc2:load_ucode\n"); } -static void uc2_rdphalf_2 () +static void uc2_rdphalf_2() { - LRDP("uc2:rdphalf_2\n"); + LRDP("uc2:rdphalf_2\n"); } -static void uc2_dlist_cnt () +static void uc2_dlist_cnt() { - uint32_t addr = segoffset(rdp.cmd1) & BMASK; - int count = rdp.cmd0 & 0x000000FF; - FRDP ("dl_count - addr: %08lx, count: %d\n", addr, count); - if (addr == 0) - return; + uint32_t addr = segoffset(rdp.cmd1) & BMASK; + int count = rdp.cmd0 & 0x000000FF; + FRDP("dl_count - addr: %08lx, count: %d\n", addr, count); + if (addr == 0) + return; - if (rdp.pc_i >= 9) { - RDP_E ("** DL stack overflow **\n"); - LRDP("** DL stack overflow **\n"); - return; - } - rdp.pc_i ++; // go to the next PC in the stack - rdp.pc[rdp.pc_i] = addr; // jump to the address - rdp.dl_count = count + 1; + if (rdp.pc_i >= 9) { + RDP_E("** DL stack overflow **\n"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + rdp.dl_count = count + 1; } diff --git a/Source/Glide64/ucode03.h b/Source/Glide64/ucode03.h index 266a29e2a..92c8ebcd3 100644 --- a/Source/Glide64/ucode03.h +++ b/Source/Glide64/ucode03.h @@ -43,16 +43,16 @@ static void uc3_vertex() { - int v0 = ((rdp.cmd0 >> 16) & 0xFF)/5; // Current vertex - int n = (uint16_t)((rdp.cmd0&0xFFFF) + 1)/0x210; // Number to copy + int v0 = ((rdp.cmd0 >> 16) & 0xFF) / 5; // Current vertex + int n = (uint16_t)((rdp.cmd0 & 0xFFFF) + 1) / 0x210; // Number to copy - if (v0 >= 32) - v0 = 31; + if (v0 >= 32) + v0 = 31; - if ((v0 + n) > 32) - n = 32 - v0; + if ((v0 + n) > 32) + n = 32 - v0; - rsp_vertex(v0, n); + rsp_vertex(v0, n); } // @@ -61,54 +61,54 @@ static void uc3_vertex() static void uc3_tri1() { - FRDP("uc3:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, - ((rdp.cmd1 >> 16) & 0xFF)/5, - ((rdp.cmd1 >> 8) & 0xFF)/5, - ((rdp.cmd1 ) & 0xFF)/5, rdp.cmd0, rdp.cmd1); - - VERTEX *v[3] = { - &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], - &rdp.vtx[(rdp.cmd1 & 0xFF)/5] - }; + FRDP("uc3:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, + ((rdp.cmd1 >> 16) & 0xFF) / 5, + ((rdp.cmd1 >> 8) & 0xFF) / 5, + ((rdp.cmd1) & 0xFF) / 5, rdp.cmd0, rdp.cmd1); - rsp_tri1(v); + VERTEX *v[3] = { + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 5] + }; + + rsp_tri1(v); } -static void uc3_tri2 () +static void uc3_tri2() { - FRDP("uc3:tri2 #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, - ((rdp.cmd0 >> 16) & 0xFF)/5, - ((rdp.cmd0 >> 8) & 0xFF)/5, - ((rdp.cmd0 ) & 0xFF)/5, - ((rdp.cmd1 >> 16) & 0xFF)/5, - ((rdp.cmd1 >> 8) & 0xFF)/5, - ((rdp.cmd1 ) & 0xFF)/5); - - VERTEX *v[6] = { - &rdp.vtx[((rdp.cmd0 >> 16) & 0xFF)/5], - &rdp.vtx[((rdp.cmd0 >> 8) & 0xFF)/5], - &rdp.vtx[(rdp.cmd0 & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], - &rdp.vtx[(rdp.cmd1 & 0xFF)/5] - }; + FRDP("uc3:tri2 #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n + 1, + ((rdp.cmd0 >> 16) & 0xFF) / 5, + ((rdp.cmd0 >> 8) & 0xFF) / 5, + ((rdp.cmd0) & 0xFF) / 5, + ((rdp.cmd1 >> 16) & 0xFF) / 5, + ((rdp.cmd1 >> 8) & 0xFF) / 5, + ((rdp.cmd1) & 0xFF) / 5); - rsp_tri2(v); + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd0 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd0 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd0 & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 5] + }; + + rsp_tri2(v); } static void uc3_quad3d() { - FRDP("uc3:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + FRDP("uc3:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n + 1); - VERTEX *v[6] = { - &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], - &rdp.vtx[(rdp.cmd1 & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5] - }; + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5] + }; - rsp_tri2(v); + rsp_tri2(v); } diff --git a/Source/Glide64/ucode04.h b/Source/Glide64/ucode04.h index 30c4c0e61..36398e232 100644 --- a/Source/Glide64/ucode04.h +++ b/Source/Glide64/ucode04.h @@ -43,40 +43,40 @@ static void uc4_vertex() { - int v0 = 0; // Current vertex - int n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy - rsp_vertex(v0, n); + int v0 = 0; // Current vertex + int n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy + rsp_vertex(v0, n); } static void uc4_tri1() { - int v1 = ((rdp.cmd1 >> 16) & 0xFF) / 5; - int v2 = ((rdp.cmd1 >> 8) & 0xFF) / 5; - int v3 = (rdp.cmd1 & 0xFF) / 5; - FRDP("uc4:tri1 #%d - %d, %d, %d\n", rdp.tri_n, - v1, v2, v3); + int v1 = ((rdp.cmd1 >> 16) & 0xFF) / 5; + int v2 = ((rdp.cmd1 >> 8) & 0xFF) / 5; + int v3 = (rdp.cmd1 & 0xFF) / 5; + FRDP("uc4:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + v1, v2, v3); - VERTEX *v[3] = { - &rdp.vtx[v1], - &rdp.vtx[v2], - &rdp.vtx[v3] - }; + VERTEX *v[3] = { + &rdp.vtx[v1], + &rdp.vtx[v2], + &rdp.vtx[v3] + }; - rsp_tri1(v); + rsp_tri1(v); } static void uc4_quad3d() { - FRDP("uc4:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + FRDP("uc4:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n + 1); - VERTEX *v[6] = { - &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], - &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], - &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], - &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], - &rdp.vtx[(rdp.cmd1 & 0xFF) / 5] - }; + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 5] + }; - rsp_tri2(v); + rsp_tri2(v); } diff --git a/Source/Glide64/ucode05.h b/Source/Glide64/ucode05.h index 717ec13d3..d92a7f3f0 100644 --- a/Source/Glide64/ucode05.h +++ b/Source/Glide64/ucode05.h @@ -43,333 +43,333 @@ int vtx_last = 0; uint32_t dma_offset_mtx = 0; uint32_t dma_offset_vtx = 0; -static void uc5_dma_offsets () +static void uc5_dma_offsets() { - dma_offset_mtx = rdp.cmd0 & 0x00FFFFFF; - dma_offset_vtx = rdp.cmd1 & 0x00FFFFFF; - vtx_last = 0; - FRDP("uc5:dma_offsets - mtx: %08lx, vtx: %08lx\n", dma_offset_mtx, dma_offset_vtx); -} - -static void uc5_matrix () -{ - // Use segment offset to get the address - uint32_t addr = dma_offset_mtx + (segoffset(rdp.cmd1) & BMASK); - - uint8_t n = (uint8_t)((rdp.cmd0 >> 16) & 0xF); - uint8_t multiply; - - if (n == 0) //DKR - { - n = (uint8_t)((rdp.cmd0 >> 22) & 0x3); - multiply = 0; - } - else //JF - { - multiply = (uint8_t)((rdp.cmd0 >> 23) & 0x1); - } - - cur_mtx = n; - - FRDP("uc5:matrix - #%d, addr: %08lx\n", n, addr); - - if (multiply) - { - DECLAREALIGN16VAR(m[4][4]); - load_matrix(m, addr); - DECLAREALIGN16VAR(m_src[4][4]); - memcpy (m_src, rdp.dkrproj[0], 64); - MulMatrices(m, m_src, rdp.dkrproj[n]); - } - else - { - load_matrix(rdp.dkrproj[n], addr); - } - rdp.update |= UPDATE_MULT_MAT; - -#ifdef EXTREME_LOGGING - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][0][0], rdp.dkrproj[n][0][1], rdp.dkrproj[n][0][2], rdp.dkrproj[n][0][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][1][0], rdp.dkrproj[n][1][1], rdp.dkrproj[n][1][2], rdp.dkrproj[n][1][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][2][0], rdp.dkrproj[n][2][1], rdp.dkrproj[n][2][2], rdp.dkrproj[n][2][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][3][0], rdp.dkrproj[n][3][1], rdp.dkrproj[n][3][2], rdp.dkrproj[n][3][3]); - - for (int i=0; i<3; i++) - { - FRDP ("proj %d\n", i); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][0][0], rdp.dkrproj[i][0][1], rdp.dkrproj[i][0][2], rdp.dkrproj[i][0][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][1][0], rdp.dkrproj[i][1][1], rdp.dkrproj[i][1][2], rdp.dkrproj[i][1][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][2][0], rdp.dkrproj[i][2][1], rdp.dkrproj[i][2][2], rdp.dkrproj[i][2][3]); - FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][3][0], rdp.dkrproj[i][3][1], rdp.dkrproj[i][3][2], rdp.dkrproj[i][3][3]); - } -#endif -} - -static void uc5_vertex () -{ - uint32_t addr = dma_offset_vtx + (segoffset(rdp.cmd1) & BMASK); - - // | cccc cccc 1111 1??? 0000 0002 2222 2222 | cmd1 = address | - // c = vtx command - // 1 = method #1 of getting count - // 2 = method #2 of getting count - // ? = unknown, but used - // 0 = unused - - int n = ((rdp.cmd0 >> 19) & 0x1F);// + 1; - if (settings.hacks&hack_Diddy) - n++; - - if (rdp.cmd0 & 0x00010000) - { - if (billboarding) - vtx_last = 1; - } - else + dma_offset_mtx = rdp.cmd0 & 0x00FFFFFF; + dma_offset_vtx = rdp.cmd1 & 0x00FFFFFF; vtx_last = 0; - - int first = ((rdp.cmd0 >> 9) & 0x1F) + vtx_last; - FRDP ("uc5:vertex - addr: %08lx, first: %d, count: %d, matrix: %08lx\n", addr, first, n, cur_mtx); - - int prj = cur_mtx; - - int start = 0; - float x, y, z; - for (int i=first; i> 1) + 0)^1]; - y = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 1)^1]; - z = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 2)^1]; - - v->x = x*rdp.dkrproj[prj][0][0] + y*rdp.dkrproj[prj][1][0] + z*rdp.dkrproj[prj][2][0] + rdp.dkrproj[prj][3][0]; - v->y = x*rdp.dkrproj[prj][0][1] + y*rdp.dkrproj[prj][1][1] + z*rdp.dkrproj[prj][2][1] + rdp.dkrproj[prj][3][1]; - v->z = x*rdp.dkrproj[prj][0][2] + y*rdp.dkrproj[prj][1][2] + z*rdp.dkrproj[prj][2][2] + rdp.dkrproj[prj][3][2]; - v->w = x*rdp.dkrproj[prj][0][3] + y*rdp.dkrproj[prj][1][3] + z*rdp.dkrproj[prj][2][3] + rdp.dkrproj[prj][3][3]; - - if (billboarding) - { - v->x += rdp.vtx[0].x; - v->y += rdp.vtx[0].y; - v->z += rdp.vtx[0].z; - v->w += rdp.vtx[0].w; - } - - if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; - - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - v->shade_mod = 0; - - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; - if (fabs(v->z_w) > 1.0) v->scr_off |= 32; - - v->r = ((uint8_t*)gfx.RDRAM)[(addr+start + 6)^3]; - v->g = ((uint8_t*)gfx.RDRAM)[(addr+start + 7)^3]; - v->b = ((uint8_t*)gfx.RDRAM)[(addr+start + 8)^3]; - v->a = ((uint8_t*)gfx.RDRAM)[(addr+start + 9)^3]; - CalculateFog (v); - -#ifdef EXTREME_LOGGING - FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v->x, v->y, v->z, v->w, v->z_w, v->r, v->g, v->b, v->a); -#endif - } - - vtx_last += n; + FRDP("uc5:dma_offsets - mtx: %08lx, vtx: %08lx\n", dma_offset_mtx, dma_offset_vtx); } -static void uc5_tridma () +static void uc5_matrix() { - vtx_last = 0; // we've drawn something, so the vertex index needs resetting - if (rdp.skip_drawing) - return; + // Use segment offset to get the address + uint32_t addr = dma_offset_mtx + (segoffset(rdp.cmd1) & BMASK); - // | cccc cccc 2222 0000 1111 1111 1111 0000 | cmd1 = address | - // c = tridma command - // 1 = method #1 of getting count - // 2 = method #2 of getting count - // 0 = unused + uint8_t n = (uint8_t)((rdp.cmd0 >> 16) & 0xF); + uint8_t multiply; - uint32_t addr = segoffset(rdp.cmd1) & BMASK; - int num = (rdp.cmd0 & 0xFFF0) >> 4; - //int num = ((rdp.cmd0 & 0x00F00000) >> 20) + 1; // same thing! - FRDP("uc5:tridma #%d - addr: %08lx, count: %d\n", rdp.tri_n, addr, num); - - int start, v0, v1, v2, flags; - for (int i=0; i> 22) & 0x3); + multiply = 0; } - else { // front cull - rdp.flags &= ~CULLMASK; - if (rdp.view_scale[0] < 0) { - rdp.flags |= CULL_BACK; // agh, backwards culling - grCullMode (GR_CULL_POSITIVE); - } - else { - rdp.flags |= CULL_FRONT; - grCullMode (GR_CULL_NEGATIVE); - } + else //JF + { + multiply = (uint8_t)((rdp.cmd0 >> 23) & 0x1); } - start += 4; - v[0]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 5] / 32.0f; - v[0]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 4] / 32.0f; - v[1]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 3] / 32.0f; - v[1]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 2] / 32.0f; - v[2]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 1] / 32.0f; - v[2]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 0] / 32.0f; + cur_mtx = n; - v[0]->uv_calculated = 0xFFFFFFFF; - v[1]->uv_calculated = 0xFFFFFFFF; - v[2]->uv_calculated = 0xFFFFFFFF; + FRDP("uc5:matrix - #%d, addr: %08lx\n", n, addr); - if (cull_tri(v)) - rdp.tri_n ++; + if (multiply) + { + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); + DECLAREALIGN16VAR(m_src[4][4]); + memcpy(m_src, rdp.dkrproj[0], 64); + MulMatrices(m, m_src, rdp.dkrproj[n]); + } else { - update (); - - draw_tri (v); - rdp.tri_n ++; + load_matrix(rdp.dkrproj[n], addr); } - } + rdp.update |= UPDATE_MULT_MAT; + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][0][0], rdp.dkrproj[n][0][1], rdp.dkrproj[n][0][2], rdp.dkrproj[n][0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][1][0], rdp.dkrproj[n][1][1], rdp.dkrproj[n][1][2], rdp.dkrproj[n][1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][2][0], rdp.dkrproj[n][2][1], rdp.dkrproj[n][2][2], rdp.dkrproj[n][2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][3][0], rdp.dkrproj[n][3][1], rdp.dkrproj[n][3][2], rdp.dkrproj[n][3][3]); + + for (int i=0; i<3; i++) + { + FRDP ("proj %d\n", i); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][0][0], rdp.dkrproj[i][0][1], rdp.dkrproj[i][0][2], rdp.dkrproj[i][0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][1][0], rdp.dkrproj[i][1][1], rdp.dkrproj[i][1][2], rdp.dkrproj[i][1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][2][0], rdp.dkrproj[i][2][1], rdp.dkrproj[i][2][2], rdp.dkrproj[i][2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][3][0], rdp.dkrproj[i][3][1], rdp.dkrproj[i][3][2], rdp.dkrproj[i][3][3]); + } +#endif } -static void uc5_dl_in_mem () +static void uc5_vertex() { - uint32_t addr = segoffset(rdp.cmd1) & BMASK; - int count = (rdp.cmd0 & 0x00FF0000) >> 16; - FRDP ("uc5:dl_in_mem - addr: %08lx, count: %d\n", addr, count); + uint32_t addr = dma_offset_vtx + (segoffset(rdp.cmd1) & BMASK); - if (rdp.pc_i >= 9) { - RDP_E ("** DL stack overflow **\n"); - LRDP("** DL stack overflow **\n"); - return; - } - rdp.pc_i ++; // go to the next PC in the stack - rdp.pc[rdp.pc_i] = addr; // jump to the address - rdp.dl_count = count + 1; + // | cccc cccc 1111 1??? 0000 0002 2222 2222 | cmd1 = address | + // c = vtx command + // 1 = method #1 of getting count + // 2 = method #2 of getting count + // ? = unknown, but used + // 0 = unused + + int n = ((rdp.cmd0 >> 19) & 0x1F);// + 1; + if (settings.hacks&hack_Diddy) + n++; + + if (rdp.cmd0 & 0x00010000) + { + if (billboarding) + vtx_last = 1; + } + else + vtx_last = 0; + + int first = ((rdp.cmd0 >> 9) & 0x1F) + vtx_last; + FRDP("uc5:vertex - addr: %08lx, first: %d, count: %d, matrix: %08lx\n", addr, first, n, cur_mtx); + + int prj = cur_mtx; + + int start = 0; + float x, y, z; + for (int i = first; i < first + n; i++) + { + start = (i - first) * 10; + VERTEX *v = &rdp.vtx[i]; + x = (float)((short*)gfx.RDRAM)[(((addr + start) >> 1) + 0) ^ 1]; + y = (float)((short*)gfx.RDRAM)[(((addr + start) >> 1) + 1) ^ 1]; + z = (float)((short*)gfx.RDRAM)[(((addr + start) >> 1) + 2) ^ 1]; + + v->x = x*rdp.dkrproj[prj][0][0] + y*rdp.dkrproj[prj][1][0] + z*rdp.dkrproj[prj][2][0] + rdp.dkrproj[prj][3][0]; + v->y = x*rdp.dkrproj[prj][0][1] + y*rdp.dkrproj[prj][1][1] + z*rdp.dkrproj[prj][2][1] + rdp.dkrproj[prj][3][1]; + v->z = x*rdp.dkrproj[prj][0][2] + y*rdp.dkrproj[prj][1][2] + z*rdp.dkrproj[prj][2][2] + rdp.dkrproj[prj][3][2]; + v->w = x*rdp.dkrproj[prj][0][3] + y*rdp.dkrproj[prj][1][3] + z*rdp.dkrproj[prj][2][3] + rdp.dkrproj[prj][3][3]; + + if (billboarding) + { + v->x += rdp.vtx[0].x; + v->y += rdp.vtx[0].y; + v->z += rdp.vtx[0].z; + v->w += rdp.vtx[0].w; + } + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + if (fabs(v->z_w) > 1.0) v->scr_off |= 32; + + v->r = ((uint8_t*)gfx.RDRAM)[(addr + start + 6) ^ 3]; + v->g = ((uint8_t*)gfx.RDRAM)[(addr + start + 7) ^ 3]; + v->b = ((uint8_t*)gfx.RDRAM)[(addr + start + 8) ^ 3]; + v->a = ((uint8_t*)gfx.RDRAM)[(addr + start + 9) ^ 3]; + CalculateFog(v); + +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v->x, v->y, v->z, v->w, v->z_w, v->r, v->g, v->b, v->a); +#endif + } + + vtx_last += n; +} + +static void uc5_tridma() +{ + vtx_last = 0; // we've drawn something, so the vertex index needs resetting + if (rdp.skip_drawing) + return; + + // | cccc cccc 2222 0000 1111 1111 1111 0000 | cmd1 = address | + // c = tridma command + // 1 = method #1 of getting count + // 2 = method #2 of getting count + // 0 = unused + + uint32_t addr = segoffset(rdp.cmd1) & BMASK; + int num = (rdp.cmd0 & 0xFFF0) >> 4; + //int num = ((rdp.cmd0 & 0x00F00000) >> 20) + 1; // same thing! + FRDP("uc5:tridma #%d - addr: %08lx, count: %d\n", rdp.tri_n, addr, num); + + int start, v0, v1, v2, flags; + for (int i = 0; i < num; i++) + { + start = i << 4; + v0 = gfx.RDRAM[addr + start]; + v1 = gfx.RDRAM[addr + start + 1]; + v2 = gfx.RDRAM[addr + start + 2]; + + FRDP("tri #%d - %d, %d, %d\n", rdp.tri_n, v0, v1, v2); + + VERTEX *v[3] = { + &rdp.vtx[v0], + &rdp.vtx[v1], + &rdp.vtx[v2] + }; + + flags = gfx.RDRAM[addr + start + 3]; + + if (flags & 0x40) { // no cull + rdp.flags &= ~CULLMASK; + grCullMode(GR_CULL_DISABLE); + } + else { // front cull + rdp.flags &= ~CULLMASK; + if (rdp.view_scale[0] < 0) { + rdp.flags |= CULL_BACK; // agh, backwards culling + grCullMode(GR_CULL_POSITIVE); + } + else { + rdp.flags |= CULL_FRONT; + grCullMode(GR_CULL_NEGATIVE); + } + } + start += 4; + + v[0]->ou = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 5] / 32.0f; + v[0]->ov = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 4] / 32.0f; + v[1]->ou = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 3] / 32.0f; + v[1]->ov = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 2] / 32.0f; + v[2]->ou = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 1] / 32.0f; + v[2]->ov = (float)((short*)gfx.RDRAM)[((addr + start) >> 1) + 0] / 32.0f; + + v[0]->uv_calculated = 0xFFFFFFFF; + v[1]->uv_calculated = 0xFFFFFFFF; + v[2]->uv_calculated = 0xFFFFFFFF; + + if (cull_tri(v)) + rdp.tri_n++; + else + { + update(); + + draw_tri(v); + rdp.tri_n++; + } + } +} + +static void uc5_dl_in_mem() +{ + uint32_t addr = segoffset(rdp.cmd1) & BMASK; + int count = (rdp.cmd0 & 0x00FF0000) >> 16; + FRDP("uc5:dl_in_mem - addr: %08lx, count: %d\n", addr, count); + + if (rdp.pc_i >= 9) { + RDP_E("** DL stack overflow **\n"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + rdp.dl_count = count + 1; } static void uc5_moveword() { - LRDP("uc5:moveword "); + LRDP("uc5:moveword "); - // Find which command this is (lowest byte of cmd0) - switch (rdp.cmd0 & 0xFF) - { - case 0x02: // moveword matrix 2 billboard - billboarding = (rdp.cmd1 & 1); - FRDP ("matrix billboard - %s\n", str_offon[billboarding]); - break; - - case 0x04: // clip (verified same) - if (((rdp.cmd0>>8)&0xFFFF) == 0x04) + // Find which command this is (lowest byte of cmd0) + switch (rdp.cmd0 & 0xFF) { - rdp.clip_ratio = sqrt((float)rdp.cmd1); - rdp.update |= UPDATE_VIEWPORT; - } - FRDP ("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); - break; + case 0x02: // moveword matrix 2 billboard + billboarding = (rdp.cmd1 & 1); + FRDP("matrix billboard - %s\n", str_offon[billboarding]); + break; - case 0x06: // segment (verified same) - FRDP ("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); - rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; - break; + case 0x04: // clip (verified same) + if (((rdp.cmd0 >> 8) & 0xFFFF) == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; - case 0x08: + case 0x06: // segment (verified same) + FRDP("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); + rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; + break; + + case 0x08: { - rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); - rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); - FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); - // rdp.update |= UPDATE_FOG_ENABLED; + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + // rdp.update |= UPDATE_FOG_ENABLED; } break; - case 0x0a: // moveword matrix select - cur_mtx = (rdp.cmd1 >> 6) & 3; - FRDP ("matrix select - mtx: %d\n", cur_mtx); - break; + case 0x0a: // moveword matrix select + cur_mtx = (rdp.cmd1 >> 6) & 3; + FRDP("matrix select - mtx: %d\n", cur_mtx); + break; - default: - FRDP ("(unknown) %02lx - IGNORED\n", rdp.cmd0&0xFF); - } + default: + FRDP("(unknown) %02lx - IGNORED\n", rdp.cmd0 & 0xFF); + } } static void uc5_setgeometrymode() { - FRDP("uc0:setgeometrymode %08lx\n", rdp.cmd1); + FRDP("uc0:setgeometrymode %08lx\n", rdp.cmd1); - rdp.geom_mode |= rdp.cmd1; + rdp.geom_mode |= rdp.cmd1; - if (rdp.cmd1 & 0x00000001) // Z-Buffer enable - { - if (!(rdp.flags & ZBUF_ENABLED)) + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable { - rdp.flags |= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } } - } - //Added by Gonetz - if (rdp.cmd1 & 0x00010000) // Fog enable - { - if (!(rdp.flags & FOG_ENABLED)) + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable { - rdp.flags |= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } } - } } static void uc5_cleargeometrymode() { - FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); + FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); - rdp.geom_mode &= (~rdp.cmd1); + rdp.geom_mode &= (~rdp.cmd1); - if (rdp.cmd1 & 0x00000001) // Z-Buffer enable - { - if (rdp.flags & ZBUF_ENABLED) + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable { - rdp.flags ^= ZBUF_ENABLED; - rdp.update |= UPDATE_ZBUF_ENABLED; + if (rdp.flags & ZBUF_ENABLED) + { + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } } - } - //Added by Gonetz - if (rdp.cmd1 & 0x00010000) // Fog enable - { - if (rdp.flags & FOG_ENABLED) + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable { - rdp.flags ^= FOG_ENABLED; - rdp.update |= UPDATE_FOG_ENABLED; + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } } - } } diff --git a/Source/Glide64/ucode07.h b/Source/Glide64/ucode07.h index 8657515ec..d52248727 100644 --- a/Source/Glide64/ucode07.h +++ b/Source/Glide64/ucode07.h @@ -45,135 +45,131 @@ uint32_t pd_col_addr = 0; -static void uc7_colorbase () +static void uc7_colorbase() { - LRDP("uc7_colorbase\n"); - pd_col_addr = segoffset(rdp.cmd1); + LRDP("uc7_colorbase\n"); + pd_col_addr = segoffset(rdp.cmd1); } - -typedef struct +typedef struct { - short y; - short x; - uint16_t idx; + short y; + short x; + uint16_t idx; - short z; - - short t; - short s; + short z; + short t; + short s; } vtx_uc7; -static void uc7_vertex () +static void uc7_vertex() { - if (rdp.update & UPDATE_MULT_MAT) - { - rdp.update ^= UPDATE_MULT_MAT; - MulMatrices(rdp.model, rdp.proj, rdp.combined); - } - - // This is special, not handled in update() - if (rdp.update & UPDATE_LIGHTS) - { - rdp.update ^= UPDATE_LIGHTS; - - // Calculate light vectors - for (uint32_t l=0; l> 16; - rdp.vn = n = ((rdp.cmd0 & 0xF00000) >> 20) + 1; - - FRDP ("uc7:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); - - vtx_uc7 *vertex = (vtx_uc7 *)&gfx.RDRAM[addr]; - - for(i = 0; i < n; i++) - { - VERTEX *v = &rdp.vtx[v0 + i]; - x = (float)vertex->x; - y = (float)vertex->y; - z = (float)vertex->z; - v->flags = 0; - v->ou = (float)vertex->s; - v->ov = (float)vertex->t; - v->uv_scaled = 0; - -#ifdef EXTREME_LOGGING -// FRDP ("before: v%d - x: %f, y: %f, z: %f, flags: %04lx, ou: %f, ov: %f\n", i>>4, x, y, z, v->flags, v->ou, v->ov); -#endif - - v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; - v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; - v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; - v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; - - - if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; - - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; - - uint8_t *color = &gfx.RDRAM[pd_col_addr + (vertex->idx & 0xff)]; - - v->a = color[0]; - CalculateFog (v); - - if (rdp.geom_mode & 0x00020000) + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) { - v->vec[0] = (char)color[3]; - v->vec[1] = (char)color[2]; - v->vec[2] = (char)color[1]; + rdp.update ^= UPDATE_LIGHTS; - if (rdp.geom_mode & 0x80000) - { - calc_linear (v); -#ifdef EXTREME_LOGGING - FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } - else if (rdp.geom_mode & 0x40000) - { - calc_sphere (v); -#ifdef EXTREME_LOGGING - FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } - - NormalizeVector (v->vec); - - calc_light (v); + // Calculate light vectors + for (uint32_t l = 0; l < rdp.num_lights; l++) + { + InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model); + NormalizeVector(rdp.light_vector[l]); + } } - else + + uint32_t addr = segoffset(rdp.cmd1); + uint32_t v0, i, n; + float x, y, z; + + rdp.v0 = v0 = (rdp.cmd0 & 0x0F0000) >> 16; + rdp.vn = n = ((rdp.cmd0 & 0xF00000) >> 20) + 1; + + FRDP("uc7:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + + vtx_uc7 *vertex = (vtx_uc7 *)&gfx.RDRAM[addr]; + + for (i = 0; i < n; i++) { - v->r = color[3]; - v->g = color[2]; - v->b = color[1]; - } -#ifdef EXTREME_LOGGING - FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov); -#endif - vertex++; - } -} + VERTEX *v = &rdp.vtx[v0 + i]; + x = (float)vertex->x; + y = (float)vertex->y; + z = (float)vertex->z; + v->flags = 0; + v->ou = (float)vertex->s; + v->ov = (float)vertex->t; + v->uv_scaled = 0; +#ifdef EXTREME_LOGGING + // FRDP ("before: v%d - x: %f, y: %f, z: %f, flags: %04lx, ou: %f, ov: %f\n", i>>4, x, y, z, v->flags, v->ou, v->ov); +#endif + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + + uint8_t *color = &gfx.RDRAM[pd_col_addr + (vertex->idx & 0xff)]; + + v->a = color[0]; + CalculateFog(v); + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = (char)color[3]; + v->vec[1] = (char)color[2]; + v->vec[2] = (char)color[1]; + + if (rdp.geom_mode & 0x80000) + { + calc_linear(v); +#ifdef EXTREME_LOGGING + FRDP("calc linear: v%d - u: %f, v: %f\n", i >> 4, v->ou, v->ov); +#endif + } + else if (rdp.geom_mode & 0x40000) + { + calc_sphere(v); +#ifdef EXTREME_LOGGING + FRDP("calc sphere: v%d - u: %f, v: %f\n", i >> 4, v->ou, v->ov); +#endif + } + + NormalizeVector(v->vec); + + calc_light(v); + } + else + { + v->r = color[3]; + v->g = color[2]; + v->b = color[1]; + } +#ifdef EXTREME_LOGGING + FRDP("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i >> 4, v->x, v->y, v->z, v->w, v->ou, v->ov); +#endif + vertex++; + } + } diff --git a/Source/Glide64/ucode08.h b/Source/Glide64/ucode08.h index 0def9a868..b91f6203a 100644 --- a/Source/Glide64/ucode08.h +++ b/Source/Glide64/ucode08.h @@ -44,503 +44,500 @@ uint32_t uc8_normale_addr = 0; float uc8_coord_mod[16]; -static void uc8_vertex () +static void uc8_vertex() { - if (rdp.update & UPDATE_MULT_MAT) - { - rdp.update ^= UPDATE_MULT_MAT; - MulMatrices(rdp.model, rdp.proj, rdp.combined); - } + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } - uint32_t addr = segoffset(rdp.cmd1); - int v0, i, n; - float x, y, z; + uint32_t addr = segoffset(rdp.cmd1); + int v0, i, n; + float x, y, z; - rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF; - rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; + rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF; + rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; - FRDP ("uc8:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + FRDP("uc8:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); - if (v0 < 0) - { - RDP_E ("** ERROR: uc2:vertex v0 < 0\n"); - LRDP("** ERROR: uc2:vertex v0 < 0\n"); - return; - } - //* - // This is special, not handled in update() - if (rdp.update & UPDATE_LIGHTS) - { - rdp.update ^= UPDATE_LIGHTS; + if (v0 < 0) + { + RDP_E("** ERROR: uc2:vertex v0 < 0\n"); + LRDP("** ERROR: uc2:vertex v0 < 0\n"); + return; + } + //* + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; - // Calculate light vectors - for (uint32_t l=0; l>4)]; - x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; - y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; - z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; - v->flags = ((uint16_t*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; - v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; - v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; + } + } + //*/ + for (i = 0; i < (n << 4); i += 16) + { + VERTEX *v = &rdp.vtx[v0 + (i >> 4)]; + x = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 0) ^ 1]; + y = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 1) ^ 1]; + z = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 2) ^ 1]; + v->flags = ((uint16_t*)gfx.RDRAM)[(((addr + i) >> 1) + 3) ^ 1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 4) ^ 1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr + i) >> 1) + 5) ^ 1]; v->uv_scaled = 0; - v->a = ((uint8_t*)gfx.RDRAM)[(addr+i + 15)^3]; + v->a = ((uint8_t*)gfx.RDRAM)[(addr + i + 15) ^ 3]; #ifdef EXTREME_LOGGING - FRDP ("before v%d - x: %f, y: %f, z: %f\n", i>>4, x, y, z); + FRDP ("before v%d - x: %f, y: %f, z: %f\n", i>>4, x, y, z); #endif - v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; - v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; - v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; - v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; #ifdef EXTREME_LOGGING - 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); + 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); #endif if (fabs(v->w) < 0.001) v->w = 0.001f; - v->oow = 1.0f / v->w; - v->x_w = v->x * v->oow; - v->y_w = v->y * v->oow; - v->z_w = v->z * v->oow; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; - v->uv_calculated = 0xFFFFFFFF; - v->screen_translated = 0; - v->shade_mod = 0; + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; - v->scr_off = 0; - if (v->x < -v->w) v->scr_off |= 1; - if (v->x > v->w) v->scr_off |= 2; - if (v->y < -v->w) v->scr_off |= 4; - if (v->y > v->w) v->scr_off |= 8; - if (v->w < 0.1f) v->scr_off |= 16; - ///* - v->r = ((uint8_t*)gfx.RDRAM)[(addr+i + 12)^3]; - v->g = ((uint8_t*)gfx.RDRAM)[(addr+i + 13)^3]; - v->b = ((uint8_t*)gfx.RDRAM)[(addr+i + 14)^3]; + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + ///* + v->r = ((uint8_t*)gfx.RDRAM)[(addr + i + 12) ^ 3]; + v->g = ((uint8_t*)gfx.RDRAM)[(addr + i + 13) ^ 3]; + v->b = ((uint8_t*)gfx.RDRAM)[(addr + i + 14) ^ 3]; #ifdef EXTREME_LOGGING - FRDP ("r: %02lx, g: %02lx, b: %02lx, a: %02lx\n", v->r, v->g, v->b, v->a); + FRDP ("r: %02lx, g: %02lx, b: %02lx, a: %02lx\n", v->r, v->g, v->b, v->a); #endif - if ((rdp.geom_mode & 0x00020000)) - { - uint32_t shift = v0 << 1; - v->vec[0] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 0)^3]; - v->vec[1] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 1)^3]; - v->vec[2] = (char)(v->flags&0xff); - - if (rdp.geom_mode & 0x80000) - { - calc_linear (v); -#ifdef EXTREME_LOGGING - FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } - else if (rdp.geom_mode & 0x40000) - { - calc_sphere (v); -#ifdef EXTREME_LOGGING - FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); -#endif - } - // 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]); - FRDP("v[%d] calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", i>>4, v->r, v->g, v->b); - float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; - FRDP("ambient light. r: %f, g: %f, b: %f\n", color[0], color[1], color[2]); - float light_intensity = 0.0f; - uint32_t l; - if (rdp.geom_mode & 0x00400000) - { - NormalizeVector (v->vec); - for (l = 0; l < rdp.num_lights-1; l++) + if ((rdp.geom_mode & 0x00020000)) { - if (!rdp.light[l].nonblack) - continue; - light_intensity = DotProduct (rdp.light_vector[l], v->vec); - FRDP("light %d, intensity : %f\n", l, light_intensity); - if (light_intensity < 0.0f) - continue; - //* - if (rdp.light[l].ca > 0.0f) - { - float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; - float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; - float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; - float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; - float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; - float p_i = rdp.light[l].ca / len; - if (p_i > 1.0f) p_i = 1.0f; - light_intensity *= p_i; - FRDP("light %d, len: %f, p_intensity : %f\n", l, len, p_i); - } - //*/ - color[0] += rdp.light[l].r * light_intensity; - color[1] += rdp.light[l].g * light_intensity; - color[2] += rdp.light[l].b * light_intensity; - FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); - } - light_intensity = DotProduct (rdp.light_vector[l], v->vec); - FRDP("light %d, intensity : %f\n", l, light_intensity); - if (light_intensity > 0.0f) - { - color[0] += rdp.light[l].r * light_intensity; - color[1] += rdp.light[l].g * light_intensity; - color[2] += rdp.light[l].b * light_intensity; - } - FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); - } - else - { - for (l = 0; l < rdp.num_lights; l++) - { - if (rdp.light[l].nonblack && rdp.light[l].nonzero) - { - float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; - float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; - float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; - float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; - float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; - light_intensity = rdp.light[l].ca / len; - if (light_intensity > 1.0f) light_intensity = 1.0f; - FRDP("light %d, p_intensity : %f\n", l, light_intensity); - color[0] += rdp.light[l].r * light_intensity; - color[1] += rdp.light[l].g * light_intensity; - color[2] += rdp.light[l].b * light_intensity; - //FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); - } - } - } - if (color[0] > 1.0f) color[0] = 1.0f; - if (color[1] > 1.0f) color[1] = 1.0f; - if (color[2] > 1.0f) color[2] = 1.0f; - v->r = (uint8_t)(((float)v->r)*color[0]); - v->g = (uint8_t)(((float)v->g)*color[1]); - v->b = (uint8_t)(((float)v->b)*color[2]); -#ifdef EXTREME_LOGGING - FRDP("color after light: r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", v->r, v->g, v->b); -#endif - } - } -} + uint32_t shift = v0 << 1; + v->vec[0] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i >> 3) + shift + 0) ^ 3]; + v->vec[1] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i >> 3) + shift + 1) ^ 3]; + v->vec[2] = (char)(v->flags & 0xff); -static void uc8_moveword () -{ - uint8_t index = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); - uint16_t offset = (uint16_t)(rdp.cmd0 & 0xFFFF); - uint32_t data = rdp.cmd1; - - FRDP ("uc8:moveword "); - - switch (index) - { - // NOTE: right now it's assuming that it sets the integer part first. This could - // be easily fixed, but only if i had something to test with. - - case 0x02: - rdp.num_lights = (data / 48); - rdp.update |= UPDATE_LIGHTS; - FRDP ("numlights: %d\n", rdp.num_lights); - break; - - case 0x04: - if (offset == 0x04) - { - rdp.clip_ratio = sqrt((float)rdp.cmd1); - rdp.update |= UPDATE_VIEWPORT; - } - FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); - break; - - case 0x06: // moveword SEGMENT - { - FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2); - rdp.segment[(offset >> 2) & 0xF] = data; - } - break; - - case 0x08: - { - rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); - rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); - FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); - } - break; - - case 0x0c: - RDP_E ("uc8:moveword forcemtx - IGNORED\n"); - LRDP("forcemtx - IGNORED\n"); - break; - - case 0x0e: - LRDP("perspnorm - IGNORED\n"); - break; - - case 0x10: // moveword coord mod - { - uint8_t n = offset >> 2; - - FRDP ("coord mod:%d, %08lx\n", n, data); - if (rdp.cmd0&8) - return; - uint32_t idx = (rdp.cmd0>>1)&3; - uint32_t pos = rdp.cmd0&0x30; - if (pos == 0) - { - uc8_coord_mod[0+idx] = (short)(rdp.cmd1>>16); - uc8_coord_mod[1+idx] = (short)(rdp.cmd1&0xffff); - } - else if (pos == 0x10) - { - uc8_coord_mod[4+idx] = (rdp.cmd1>>16)/65536.0f; - uc8_coord_mod[5+idx] = (rdp.cmd1&0xffff)/65536.0f; - uc8_coord_mod[12+idx] = uc8_coord_mod[0+idx] + uc8_coord_mod[4+idx]; - uc8_coord_mod[13+idx] = uc8_coord_mod[1+idx] + uc8_coord_mod[5+idx]; - - } - else if (pos == 0x20) - { - uc8_coord_mod[8+idx] = (short)(rdp.cmd1>>16); - uc8_coord_mod[9+idx] = (short)(rdp.cmd1&0xffff); -#ifdef EXTREME_LOGGING - if (idx) - { - for (int k = 8; k < 16; k++) - { - FRDP("coord_mod[%d]=%f\n", k, uc8_coord_mod[k]); - } - } -#endif - } - - } - break; - - default: - FRDP_E("uc8:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); - FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); - } -} - -static void uc8_movemem () -{ - int idx = rdp.cmd0 & 0xFF; - uint32_t addr = segoffset(rdp.cmd1); - int ofs = (rdp.cmd0 >> 5) & 0x3FFF; - - FRDP ("uc8:movemem ofs:%d ", ofs); - - switch (idx) - { - case 8: // VIEWPORT - { - uint32_t 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]; - 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.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; - - rdp.update |= UPDATE_VIEWPORT; - - FRDP ("viewport scale(%d, %d), trans(%d, %d), from:%08lx\n", scale_x, scale_y, - trans_x, trans_y, a); - } - break; - - case 10: // LIGHT - { - int n = (ofs / 48); - if (n < 2) + if (rdp.geom_mode & 0x80000) { - char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3]; - rdp.lookat[n][0] = (float)(dir_x) / 127.0f; - char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3]; - rdp.lookat[n][1] = (float)(dir_y) / 127.0f; - char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3]; - rdp.lookat[n][2] = (float)(dir_z) / 127.0f; - rdp.use_lookat = TRUE; - if (n == 1) - { - if (!dir_x && !dir_y) - rdp.use_lookat = FALSE; - } - FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); - return; + calc_linear(v); +#ifdef EXTREME_LOGGING + FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif } - n -= 2; - uint8_t col = gfx.RDRAM[(addr+0)^3]; - rdp.light[n].r = (float)col / 255.0f; - rdp.light[n].nonblack = col; - col = gfx.RDRAM[(addr+1)^3]; - rdp.light[n].g = (float)col / 255.0f; - rdp.light[n].nonblack += col; - col = gfx.RDRAM[(addr+2)^3]; - rdp.light[n].b = (float)col / 255.0f; - rdp.light[n].nonblack += col; - rdp.light[n].a = 1.0f; - rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f; - rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f; - rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f; - // ** - uint32_t a = addr >> 1; - rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+16)^1]); - rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+17)^1]); - rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+18)^1]); - rdp.light[n].w = (float)(((short*)gfx.RDRAM)[(a+19)^1]); - rdp.light[n].nonzero = gfx.RDRAM[(addr+12)^3]; - rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f; - //rdp.light[n].la = rdp.light[n].ca * 1.0f; + else if (rdp.geom_mode & 0x40000) + { + calc_sphere(v); #ifdef EXTREME_LOGGING - FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, w: %f, ca: %f\n", - n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].w, rdp.light[n].ca); + FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); #endif - FRDP ("light: n: %d, r: %f, g: %f, b: %f. dir: x: %.3f, y: %.3f, z: %.3f\n", - n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, - rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); + } + // 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]); + FRDP("v[%d] calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", i >> 4, v->r, v->g, v->b); + float color[3] = { rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b }; + FRDP("ambient light. r: %f, g: %f, b: %f\n", color[0], color[1], color[2]); + float light_intensity = 0.0f; + uint32_t l; + if (rdp.geom_mode & 0x00400000) + { + NormalizeVector(v->vec); + for (l = 0; l < rdp.num_lights - 1; l++) + { + if (!rdp.light[l].nonblack) + continue; + light_intensity = DotProduct(rdp.light_vector[l], v->vec); + FRDP("light %d, intensity : %f\n", l, light_intensity); + if (light_intensity < 0.0f) + continue; + //* + if (rdp.light[l].ca > 0.0f) + { + float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; + float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; + float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; + float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; + float len = (vx*vx + vy*vy + vz*vz + vw*vw) / 65536.0f; + float p_i = rdp.light[l].ca / len; + if (p_i > 1.0f) p_i = 1.0f; + light_intensity *= p_i; + FRDP("light %d, len: %f, p_intensity : %f\n", l, len, p_i); + } + //*/ + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + light_intensity = DotProduct(rdp.light_vector[l], v->vec); + FRDP("light %d, intensity : %f\n", l, light_intensity); + if (light_intensity > 0.0f) + { + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + } + FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + else + { + for (l = 0; l < rdp.num_lights; l++) + { + if (rdp.light[l].nonblack && rdp.light[l].nonzero) + { + float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; + float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; + float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; + float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; + float len = (vx*vx + vy*vy + vz*vz + vw*vw) / 65536.0f; + light_intensity = rdp.light[l].ca / len; + if (light_intensity > 1.0f) light_intensity = 1.0f; + FRDP("light %d, p_intensity : %f\n", l, light_intensity); + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + //FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + } + } + if (color[0] > 1.0f) color[0] = 1.0f; + if (color[1] > 1.0f) color[1] = 1.0f; + if (color[2] > 1.0f) color[2] = 1.0f; + v->r = (uint8_t)(((float)v->r)*color[0]); + v->g = (uint8_t)(((float)v->g)*color[1]); + v->b = (uint8_t)(((float)v->b)*color[2]); #ifdef EXTREME_LOGGING - for (int t=0; t < 24; t++) - { - FRDP ("light[%d] = 0x%04lx \n", t, ((uint16_t*)gfx.RDRAM)[(a+t)^1]); - } + FRDP("color after light: r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", v->r, v->g, v->b); #endif - } - break; - - case 14: //Normales - { - uc8_normale_addr = segoffset(rdp.cmd1); - FRDP ("Normale - addr: %08lx\n", uc8_normale_addr); -#ifdef EXTREME_LOGGING - int i; - for (i = 0; i < 32; i++) - { - char x = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 0)^3]; - char y = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 1)^3]; - FRDP("#%d x = %d, y = %d\n", i, x, y); - } - uint32_t a = uc8_normale_addr >> 1; - for (i = 0; i < 32; i++) - { - FRDP ("n[%d] = 0x%04lx \n", i, ((uint16_t*)gfx.RDRAM)[(a+i)^1]); - } -#endif - } - break; - - default: - FRDP ("uc8:movemem unknown (%d)\n", idx); - } + } + } } +static void uc8_moveword() +{ + uint8_t index = (uint8_t)((rdp.cmd0 >> 16) & 0xFF); + uint16_t offset = (uint16_t)(rdp.cmd0 & 0xFFFF); + uint32_t data = rdp.cmd1; + + FRDP("uc8:moveword "); + + switch (index) + { + // NOTE: right now it's assuming that it sets the integer part first. This could + // be easily fixed, but only if i had something to test with. + + case 0x02: + rdp.num_lights = (data / 48); + rdp.update |= UPDATE_LIGHTS; + FRDP("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (offset == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // moveword SEGMENT + { + FRDP("SEGMENT %08lx -> seg%d\n", data, offset >> 2); + rdp.segment[(offset >> 2) & 0xF] = data; + } + break; + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + } + break; + + case 0x0c: + RDP_E("uc8:moveword forcemtx - IGNORED\n"); + LRDP("forcemtx - IGNORED\n"); + break; + + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; + + case 0x10: // moveword coord mod + { + uint8_t n = offset >> 2; + + FRDP("coord mod:%d, %08lx\n", n, data); + if (rdp.cmd0 & 8) + return; + uint32_t idx = (rdp.cmd0 >> 1) & 3; + uint32_t pos = rdp.cmd0 & 0x30; + if (pos == 0) + { + uc8_coord_mod[0 + idx] = (short)(rdp.cmd1 >> 16); + uc8_coord_mod[1 + idx] = (short)(rdp.cmd1 & 0xffff); + } + else if (pos == 0x10) + { + uc8_coord_mod[4 + idx] = (rdp.cmd1 >> 16) / 65536.0f; + uc8_coord_mod[5 + idx] = (rdp.cmd1 & 0xffff) / 65536.0f; + uc8_coord_mod[12 + idx] = uc8_coord_mod[0 + idx] + uc8_coord_mod[4 + idx]; + uc8_coord_mod[13 + idx] = uc8_coord_mod[1 + idx] + uc8_coord_mod[5 + idx]; + } + else if (pos == 0x20) + { + uc8_coord_mod[8 + idx] = (short)(rdp.cmd1 >> 16); + uc8_coord_mod[9 + idx] = (short)(rdp.cmd1 & 0xffff); +#ifdef EXTREME_LOGGING + if (idx) + { + for (int k = 8; k < 16; k++) + { + FRDP("coord_mod[%d]=%f\n", k, uc8_coord_mod[k]); + } + } +#endif + } + } + break; + + default: + FRDP_E("uc8:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + FRDP("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + } +} + +static void uc8_movemem() +{ + int idx = rdp.cmd0 & 0xFF; + uint32_t addr = segoffset(rdp.cmd1); + int ofs = (rdp.cmd0 >> 5) & 0x3FFF; + + FRDP("uc8:movemem ofs:%d ", ofs); + + switch (idx) + { + case 8: // VIEWPORT + { + uint32_t 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]; + 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.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; + + rdp.update |= UPDATE_VIEWPORT; + + FRDP("viewport scale(%d, %d), trans(%d, %d), from:%08lx\n", scale_x, scale_y, + trans_x, trans_y, a); + } + break; + + case 10: // LIGHT + { + int n = (ofs / 48); + if (n < 2) + { + char dir_x = ((char*)gfx.RDRAM)[(addr + 8) ^ 3]; + rdp.lookat[n][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(addr + 9) ^ 3]; + rdp.lookat[n][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(addr + 10) ^ 3]; + rdp.lookat[n][2] = (float)(dir_z) / 127.0f; + rdp.use_lookat = TRUE; + if (n == 1) + { + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + } + FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); + return; + } + n -= 2; + uint8_t col = gfx.RDRAM[(addr + 0) ^ 3]; + rdp.light[n].r = (float)col / 255.0f; + rdp.light[n].nonblack = col; + col = gfx.RDRAM[(addr + 1) ^ 3]; + rdp.light[n].g = (float)col / 255.0f; + rdp.light[n].nonblack += col; + col = gfx.RDRAM[(addr + 2) ^ 3]; + rdp.light[n].b = (float)col / 255.0f; + rdp.light[n].nonblack += col; + rdp.light[n].a = 1.0f; + rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr + 8) ^ 3]) / 127.0f; + rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr + 9) ^ 3]) / 127.0f; + rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr + 10) ^ 3]) / 127.0f; + // ** + uint32_t a = addr >> 1; + rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a + 16) ^ 1]); + rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a + 17) ^ 1]); + rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a + 18) ^ 1]); + rdp.light[n].w = (float)(((short*)gfx.RDRAM)[(a + 19) ^ 1]); + rdp.light[n].nonzero = gfx.RDRAM[(addr + 12) ^ 3]; + rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f; + //rdp.light[n].la = rdp.light[n].ca * 1.0f; +#ifdef EXTREME_LOGGING + FRDP("light: n: %d, pos: x: %f, y: %f, z: %f, w: %f, ca: %f\n", + n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].w, rdp.light[n].ca); +#endif + FRDP("light: n: %d, r: %f, g: %f, b: %f. dir: x: %.3f, y: %.3f, z: %.3f\n", + n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, + rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); +#ifdef EXTREME_LOGGING + for (int t = 0; t < 24; t++) + { + FRDP ("light[%d] = 0x%04lx \n", t, ((uint16_t*)gfx.RDRAM)[(a+t)^1]); + } +#endif + } + break; + + case 14: //Normales + { + uc8_normale_addr = segoffset(rdp.cmd1); + FRDP("Normale - addr: %08lx\n", uc8_normale_addr); +#ifdef EXTREME_LOGGING + int i; + for (i = 0; i < 32; i++) + { + char x = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 0)^3]; + char y = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 1)^3]; + FRDP("#%d x = %d, y = %d\n", i, x, y); + } + uint32_t a = uc8_normale_addr >> 1; + for (i = 0; i < 32; i++) + { + FRDP ("n[%d] = 0x%04lx \n", i, ((uint16_t*)gfx.RDRAM)[(a+i)^1]); + } +#endif + } + break; + + default: + FRDP("uc8:movemem unknown (%d)\n", idx); + } + } static void uc8_tri4() //by Gugaman Apr 19 2002 { if (rdp.skip_drawing) { - LRDP("uc8:tri4. skipped\n"); - return; + LRDP("uc8:tri4. skipped\n"); + return; } - FRDP("uc8:tri4 (#%d - #%d), %d-%d-%d, %d-%d-%d, %d-%d-%d, %d-%d-%d\n", - rdp.tri_n, - rdp.tri_n+3, - ((rdp.cmd0 >> 23) & 0x1F), - ((rdp.cmd0 >> 18) & 0x1F), - ((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3)), - ((rdp.cmd0 >> 10) & 0x1F), - ((rdp.cmd0 >> 5) & 0x1F), - ((rdp.cmd0 >> 0) & 0x1F), - ((rdp.cmd1 >> 25) & 0x1F), - ((rdp.cmd1 >> 20) & 0x1F), - ((rdp.cmd1 >> 15) & 0x1F), - ((rdp.cmd1 >> 10) & 0x1F), - ((rdp.cmd1 >> 5) & 0x1F), - ((rdp.cmd1 >> 0) & 0x1F)); + FRDP("uc8:tri4 (#%d - #%d), %d-%d-%d, %d-%d-%d, %d-%d-%d, %d-%d-%d\n", + rdp.tri_n, + rdp.tri_n + 3, + ((rdp.cmd0 >> 23) & 0x1F), + ((rdp.cmd0 >> 18) & 0x1F), + ((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) & 0x3)), + ((rdp.cmd0 >> 10) & 0x1F), + ((rdp.cmd0 >> 5) & 0x1F), + ((rdp.cmd0 >> 0) & 0x1F), + ((rdp.cmd1 >> 25) & 0x1F), + ((rdp.cmd1 >> 20) & 0x1F), + ((rdp.cmd1 >> 15) & 0x1F), + ((rdp.cmd1 >> 10) & 0x1F), + ((rdp.cmd1 >> 5) & 0x1F), + ((rdp.cmd1 >> 0) & 0x1F)); - VERTEX *v[12] = { - &rdp.vtx[(rdp.cmd0 >> 23) & 0x1F], - &rdp.vtx[(rdp.cmd0 >> 18) & 0x1F], - &rdp.vtx[((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3))], - &rdp.vtx[(rdp.cmd0 >> 10) & 0x1F], - &rdp.vtx[(rdp.cmd0 >> 5) & 0x1F], - &rdp.vtx[(rdp.cmd0 >> 0) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 25) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 20) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 15) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 10) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 5) & 0x1F], - &rdp.vtx[(rdp.cmd1 >> 0) & 0x1F] - }; + VERTEX *v[12] = { + &rdp.vtx[(rdp.cmd0 >> 23) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 18) & 0x1F], + &rdp.vtx[((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) & 0x3))], + &rdp.vtx[(rdp.cmd0 >> 10) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 5) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 0) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 25) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 20) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 15) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 10) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 5) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 0) & 0x1F] + }; - int updated = 0; + int updated = 0; - if (cull_tri(v)) - rdp.tri_n ++; - else - { - updated = 1; - update (); + if (cull_tri(v)) + rdp.tri_n++; + else + { + updated = 1; + update(); - draw_tri (v); - rdp.tri_n ++; - } + draw_tri(v); + rdp.tri_n++; + } - if (cull_tri(v+3)) - rdp.tri_n ++; - else - { - if (!updated) - { - updated = 1; - update (); - } + if (cull_tri(v + 3)) + rdp.tri_n++; + else + { + if (!updated) + { + updated = 1; + update(); + } - draw_tri (v+3); - rdp.tri_n ++; - } + draw_tri(v + 3); + rdp.tri_n++; + } - if (cull_tri(v+6)) - rdp.tri_n ++; - else - { - if (!updated) - { - updated = 1; - update (); - } + if (cull_tri(v + 6)) + rdp.tri_n++; + else + { + if (!updated) + { + updated = 1; + update(); + } - draw_tri (v+6); - rdp.tri_n ++; - } + draw_tri(v + 6); + rdp.tri_n++; + } - if (cull_tri(v+9)) - rdp.tri_n ++; - else - { - if (!updated) - { - updated = 1; - update (); - } + if (cull_tri(v + 9)) + rdp.tri_n++; + else + { + if (!updated) + { + updated = 1; + update(); + } - draw_tri (v+9); - rdp.tri_n ++; - } + draw_tri(v + 9); + rdp.tri_n++; + } } diff --git a/Source/Glide64/ucode09.h b/Source/Glide64/ucode09.h index de79d8664..5f2aec78b 100644 --- a/Source/Glide64/ucode09.h +++ b/Source/Glide64/ucode09.h @@ -41,663 +41,664 @@ // //**************************************************************** -void uc9_rpdcmd (); +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}; + 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 { - int32_t W; - uint32_t UW; - wxInt16 HW[2]; - uint16_t 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 int Calc_invw(int w) { + int count, neg; + union { + int32_t W; + uint32_t UW; + wxInt16 HW[2]; + uint16_t 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 (uint8_t * addr, uint32_t type) +static void uc9_draw_object(uint8_t * addr, uint32_t type) { - uint32_t textured, vnum, vsize; - switch (type) { + uint32_t textured, vnum, vsize; + switch (type) { case 0: //null - textured = vnum = vsize = 0; - break; + textured = vnum = vsize = 0; + break; case 1: //sh tri - textured = 0; - vnum = 3; - vsize = 8; - break; + textured = 0; + vnum = 3; + vsize = 8; + break; case 2: //tx tri - textured = 1; - vnum = 3; - vsize = 16; - break; + textured = 1; + vnum = 3; + vsize = 16; + break; case 3: //sh quad - textured = 0; - vnum = 4; - vsize = 8; - break; + textured = 0; + vnum = 4; + vsize = 8; + break; case 4: //tx quad - textured = 1; - vnum = 4; - vsize = 16; - break; + textured = 1; + vnum = 4; + vsize = 16; + break; default: - FRDP_E("Unknown geometric primitive type %u.\n", type); - textured = vnum = vsize = 0; - break; - } - VERTEX vtx[4]; - for (uint32_t 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) + FRDP_E("Unknown geometric primitive type %u.\n", type); + textured = vnum = vsize = 0; + break; + } + VERTEX vtx[4]; + for (uint32_t i = 0; i < vnum; i++) { - 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); + 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 { - 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); + 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; } - 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 uint32_t uc9_load_object (uint32_t zHeader, uint32_t * rdpcmds) +static uint32_t uc9_load_object(uint32_t zHeader, uint32_t * rdpcmds) { - uint32_t type = zHeader & 7; - uint8_t * addr = gfx.RDRAM + (zHeader&0xFFFFFFF8); - switch (type) { + uint32_t type = zHeader & 7; + uint8_t * addr = gfx.RDRAM + (zHeader & 0xFFFFFFF8); + switch (type) { case 1: //sh tri case 3: //sh quad - { + { rdp.cmd1 = ((uint32_t*)addr)[1]; if (rdp.cmd1 != rdpcmds[0]) { - rdpcmds[0] = rdp.cmd1; - uc9_rpdcmd (); + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd(); } - update (); + update(); uc9_draw_object(addr + 8, type); - } - break; + } + break; case 0: //null case 2: //tx tri case 4: //tx quad - { + { rdp.cmd1 = ((uint32_t*)addr)[1]; if (rdp.cmd1 != rdpcmds[0]) { - rdpcmds[0] = rdp.cmd1; - uc9_rpdcmd (); + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd(); } rdp.cmd1 = ((uint32_t*)addr)[2]; if (rdp.cmd1 != rdpcmds[1]) { - uc9_rpdcmd (); - rdpcmds[1] = rdp.cmd1; + uc9_rpdcmd(); + rdpcmds[1] = rdp.cmd1; } rdp.cmd1 = ((uint32_t*)addr)[3]; if (rdp.cmd1 != rdpcmds[2]) { - uc9_rpdcmd (); - rdpcmds[2] = rdp.cmd1; + uc9_rpdcmd(); + rdpcmds[2] = rdp.cmd1; } if (type) { - update (); - uc9_draw_object(addr + 16, type); + update(); + uc9_draw_object(addr + 16, type); } - } - break; - } - return segoffset(((uint32_t*)addr)[0]); -} - -static void uc9_object () -{ - LRDP("uc9:object\n"); - uint32_t rdpcmds[3] = {0, 0, 0}; - uint32_t cmd1 = rdp.cmd1; - uint32_t 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); - uint32_t 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; - default: - m = NULL; /* allowing segfaults to debug in case of PJGlide64 bugs */ - FRDP_E("Invalid FM light matrix ID %u.\n", mid); - break; - } - - rdp.light[rdp.num_lights].r = (float)(((uint8_t*)gfx.DMEM)[(a+0)^3]) / 255.0f; - rdp.light[rdp.num_lights].g = (float)(((uint8_t*)gfx.DMEM)[(a+1)^3]) / 255.0f; - rdp.light[rdp.num_lights].b = (float)(((uint8_t*)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; - uint32_t i; - for (i = 0; i < rdp.num_lights; i++) - { - rdp.light[i].r = (float)(((uint8_t*)gfx.DMEM)[(a+0)^3]) / 255.0f; - rdp.light[i].g = (float)(((uint8_t*)gfx.DMEM)[(a+1)^3]) / 255.0f; - rdp.light[i].b = (float)(((uint8_t*)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 () -{ - uint32_t csrs = -1024 + ((rdp.cmd0>>12)&0xFFF); - uint32_t nsrs = -1024 + (rdp.cmd0&0xFFF); - uint32_t num = 1 + ((rdp.cmd1>>24)&0xFF); - uint32_t cdest = -1024 + ((rdp.cmd1>>12)&0xFFF); - uint32_t 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 (uint32_t 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 = (uint8_t)(((uint32_t)v.r * gfx.DMEM[(csrs++)^3])>>8); - v.g = (uint8_t)(((uint32_t)v.g * gfx.DMEM[(csrs++)^3])>>8); - v.b = (uint8_t)(((uint32_t)v.b * gfx.DMEM[(csrs++)^3])>>8); - v.a = gfx.DMEM[(csrs++)^3]; + break; } - 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; - } + return segoffset(((uint32_t*)addr)[0]); } -static void uc9_mtxtrnsp () +static void uc9_object() { - LRDP("uc9:mtxtrnsp - ignored\n"); - /* - LRDP("uc9:mtxtrnsp "); - M44 *s; - switch (rdp.cmd1&0xF) { - case 4: + LRDP("uc9:object\n"); + uint32_t rdpcmds[3] = { 0, 0, 0 }; + uint32_t cmd1 = rdp.cmd1; + uint32_t 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); + uint32_t 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; + default: + m = NULL; /* allowing segfaults to debug in case of PJGlide64 bugs */ + FRDP_E("Invalid FM light matrix ID %u.\n", mid); + break; + } + + rdp.light[rdp.num_lights].r = (float)(((uint8_t*)gfx.DMEM)[(a + 0) ^ 3]) / 255.0f; + rdp.light[rdp.num_lights].g = (float)(((uint8_t*)gfx.DMEM)[(a + 1) ^ 3]) / 255.0f; + rdp.light[rdp.num_lights].b = (float)(((uint8_t*)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; + uint32_t i; + for (i = 0; i < rdp.num_lights; i++) + { + rdp.light[i].r = (float)(((uint8_t*)gfx.DMEM)[(a + 0) ^ 3]) / 255.0f; + rdp.light[i].g = (float)(((uint8_t*)gfx.DMEM)[(a + 1) ^ 3]) / 255.0f; + rdp.light[i].b = (float)(((uint8_t*)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() +{ + uint32_t csrs = -1024 + ((rdp.cmd0 >> 12) & 0xFFF); + uint32_t nsrs = -1024 + (rdp.cmd0 & 0xFFF); + uint32_t num = 1 + ((rdp.cmd1 >> 24) & 0xFF); + uint32_t cdest = -1024 + ((rdp.cmd1 >> 12) & 0xFFF); + uint32_t 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 (uint32_t 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 = (uint8_t)(((uint32_t)v.r * gfx.DMEM[(csrs++) ^ 3]) >> 8); + v.g = (uint8_t)(((uint32_t)v.g * gfx.DMEM[(csrs++) ^ 3]) >> 8); + v.b = (uint8_t)(((uint32_t)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: + case 6: s = (M44*)rdp.proj; LRDP("Proj\n"); break; - case 8: + 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; - */ + } + 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 () +static void uc9_mtxcat() { - LRDP("uc9:mtxcat "); - M44 *s = NULL; - M44 *t = NULL; - uint32_t S = rdp.cmd0&0xF; - uint32_t T = (rdp.cmd1>>16)&0xF; - uint32_t 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; - default: - FRDP_E("Invalid mutex S-coordinate: %u\n", S); - s = NULL; /* intentional segfault to alert for bugs in PJGlide64 (cxd4) */ - 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; - default: - FRDP_E("Invalid mutex T-coordinate: %u\n", T); - t = NULL; /* intentional segfault to alert for bugs in PJGlide64 (cxd4) */ - break; - } - DECLAREALIGN16VAR(m[4][4]); - MulMatrices(*s, *t, m); + LRDP("uc9:mtxcat "); + M44 *s = NULL; + M44 *t = NULL; + uint32_t S = rdp.cmd0 & 0xF; + uint32_t T = (rdp.cmd1 >> 16) & 0xF; + uint32_t 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; + default: + FRDP_E("Invalid mutex S-coordinate: %u\n", S); + s = NULL; /* intentional segfault to alert for bugs in PJGlide64 (cxd4) */ + 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; + default: + FRDP_E("Invalid mutex T-coordinate: %u\n", T); + t = NULL; /* intentional segfault to alert for bugs in PJGlide64 (cxd4) */ + 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; - } + 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]); + 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; - uint8_t fog; - uint8_t cc; + short sy; + short sx; + int invw; + short yi; + short xi; + short wi; + uint8_t fog; + uint8_t cc; } zSortVDest; -static void uc9_mult_mpmtx () +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 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++) { - int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset); - if (fog > 255) - fog = 255; - v.fog = (fog >= 0) ? (uint8_t)fog : 0; + 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) ? (uint8_t)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); } - - 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 () +static void uc9_link_subdl() { - LRDP("uc9:link_subdl IGNORED\n"); + LRDP("uc9:link_subdl IGNORED\n"); } -static void uc9_set_subdl () +static void uc9_set_subdl() { - LRDP("uc9:set_subdl IGNORED\n"); + LRDP("uc9:set_subdl IGNORED\n"); } -static void uc9_wait_signal () +static void uc9_wait_signal() { - LRDP("uc9:wait_signal IGNORED\n"); + LRDP("uc9:wait_signal IGNORED\n"); } -static void uc9_send_signal () +static void uc9_send_signal() { - LRDP("uc9:send_signal IGNORED\n"); + LRDP("uc9:send_signal IGNORED\n"); } -void uc9_movemem () +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; - uint32_t addr = segoffset(rdp.cmd1); - switch (idx) - { - - case 0: //save/load - if (flag == 0) + 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; + uint32_t addr = segoffset(rdp.cmd1); + switch (idx) { - 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 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 + 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; - } + 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]); + 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 10: + LRDP("Othermode - IGNORED\n"); + break; - case 12: // VIEWPORT + case 12: // VIEWPORT { - uint32_t 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; + uint32_t 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.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.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; + 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); + 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); - } - -} + default: + FRDP("** UNKNOWN %d\n", idx); + } + } static void uc9_setscissor() { - rdp_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; + 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.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; - } + rdp.geom_mode |= 0x0200; + } } diff --git a/Source/Glide64/ucode09rdp.h b/Source/Glide64/ucode09rdp.h index 83fcf88ad..27a3e6f67 100644 --- a/Source/Glide64/ucode09rdp.h +++ b/Source/Glide64/ucode09rdp.h @@ -41,30 +41,30 @@ // //**************************************************************** -void uc9_rpdcmd () +void uc9_rpdcmd() { - uint32_t a = segoffset(rdp.cmd1) >> 2; - FRDP ("uc9:rdpcmd addr: %08lx\n", a); - if (a) - { - rdp.LLE = 1; - uint32_t cmd = 0; - while(1) + uint32_t a = segoffset(rdp.cmd1) >> 2; + FRDP("uc9:rdpcmd addr: %08lx\n", a); + if (a) { - rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; - cmd = rdp.cmd0>>24; - if (cmd == 0xDF) - break; - rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; - if (cmd == 0xE4 || cmd == 0xE5) - { - a++; - rdp.cmd2 = ((uint32_t*)gfx.RDRAM)[a++]; - a++; - rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a++]; - } - gfx_instruction[ucode_zSort][cmd] (); - }; - rdp.LLE = 0; - } + rdp.LLE = 1; + uint32_t cmd = 0; + while (1) + { + rdp.cmd0 = ((uint32_t*)gfx.RDRAM)[a++]; + cmd = rdp.cmd0 >> 24; + if (cmd == 0xDF) + break; + rdp.cmd1 = ((uint32_t*)gfx.RDRAM)[a++]; + if (cmd == 0xE4 || cmd == 0xE5) + { + a++; + rdp.cmd2 = ((uint32_t*)gfx.RDRAM)[a++]; + a++; + rdp.cmd3 = ((uint32_t*)gfx.RDRAM)[a++]; + } + gfx_instruction[ucode_zSort][cmd](); + }; + rdp.LLE = 0; + } } diff --git a/Source/Glide64/ucodeFB.h b/Source/Glide64/ucodeFB.h index 39bd6e6e0..be22dea29 100644 --- a/Source/Glide64/ucodeFB.h +++ b/Source/Glide64/ucodeFB.h @@ -43,1068 +43,1066 @@ static void fb_uc0_moveword() { - if ((rdp.cmd0 & 0xFF) == 0x06) // segment - { - rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; - } + if ((rdp.cmd0 & 0xFF) == 0x06) // segment + { + rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; + } } static void fb_uc2_moveword() { - if (((rdp.cmd0 >> 16) & 0xFF) == 0x06) // segment - { - rdp.segment[((rdp.cmd0 & 0xFFFF) >> 2)&0xF] = rdp.cmd1; - } + if (((rdp.cmd0 >> 16) & 0xFF) == 0x06) // segment + { + rdp.segment[((rdp.cmd0 & 0xFFFF) >> 2) & 0xF] = rdp.cmd1; + } } -static void fb_bg_copy () +static void fb_bg_copy() { - if (rdp.main_ci == 0) - return; - CI_STATUS status = rdp.frame_buffers[rdp.ci_count-1].status; - if ( (status == ci_copy) ) - return; + if (rdp.main_ci == 0) + return; + CI_STATUS status = rdp.frame_buffers[rdp.ci_count - 1].status; + if ((status == ci_copy)) + return; - uint32_t addr = segoffset(rdp.cmd1) >> 1; - uint8_t imageFmt = ((uint8_t *)gfx.RDRAM)[(((addr+11)<<1)+0)^3]; - uint8_t imageSiz = ((uint8_t *)gfx.RDRAM)[(((addr+11)<<1)+1)^3]; - uint32_t imagePtr = segoffset(((uint32_t*)gfx.RDRAM)[(addr+8)>>1]); - 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); + uint32_t addr = segoffset(rdp.cmd1) >> 1; + uint8_t imageFmt = ((uint8_t *)gfx.RDRAM)[(((addr + 11) << 1) + 0) ^ 3]; + uint8_t imageSiz = ((uint8_t *)gfx.RDRAM)[(((addr + 11) << 1) + 1) ^ 3]; + uint32_t imagePtr = segoffset(((uint32_t*)gfx.RDRAM)[(addr + 8) >> 1]); + 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); - if (status == ci_main) - { - uint16_t frameW = ((uint16_t *)gfx.RDRAM)[(addr+3)^1] >> 2; - uint16_t frameH = ((uint16_t *)gfx.RDRAM)[(addr+7)^1] >> 2; - if ( (frameW == rdp.frame_buffers[rdp.ci_count-1].width) && (frameH == rdp.frame_buffers[rdp.ci_count-1].height) ) - rdp.main_ci_bg = imagePtr; - } - else if (imagePtr >= rdp.main_ci && imagePtr < rdp.main_ci_end) //addr within main frame buffer - { - rdp.copy_ci_index = rdp.ci_count-1; - rdp.frame_buffers[rdp.copy_ci_index].status = ci_copy; - FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); - - if (rdp.frame_buffers[rdp.copy_ci_index].addr != rdp.main_ci_bg) + if (status == ci_main) { - rdp.scale_x = 1.0f; - rdp.scale_y = 1.0f; + uint16_t frameW = ((uint16_t *)gfx.RDRAM)[(addr + 3) ^ 1] >> 2; + uint16_t frameH = ((uint16_t *)gfx.RDRAM)[(addr + 7) ^ 1] >> 2; + if ((frameW == rdp.frame_buffers[rdp.ci_count - 1].width) && (frameH == rdp.frame_buffers[rdp.ci_count - 1].height)) + rdp.main_ci_bg = imagePtr; } - else + else if (imagePtr >= rdp.main_ci && imagePtr < rdp.main_ci_end) //addr within main frame buffer { - LRDP("motion blur!\n"); - rdp.motionblur = TRUE; - } + rdp.copy_ci_index = rdp.ci_count - 1; + rdp.frame_buffers[rdp.copy_ci_index].status = ci_copy; + FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); - FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", imagePtr, rdp.main_ci); - } - else if (imagePtr == rdp.zimg) - { - if (status == ci_unknown) - { - rdp.frame_buffers[rdp.ci_count-1].status = ci_zcopy; - rdp.tmpzimg = rdp.frame_buffers[rdp.ci_count-1].addr; - if (!rdp.copy_zi_index) - rdp.copy_zi_index = rdp.ci_count-1; - FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.copy_ci_index); + if (rdp.frame_buffers[rdp.copy_ci_index].addr != rdp.main_ci_bg) + { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + else + { + LRDP("motion blur!\n"); + rdp.motionblur = TRUE; + } + + FRDP("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", imagePtr, rdp.main_ci); + } + else if (imagePtr == rdp.zimg) + { + if (status == ci_unknown) + { + rdp.frame_buffers[rdp.ci_count - 1].status = ci_zcopy; + rdp.tmpzimg = rdp.frame_buffers[rdp.ci_count - 1].addr; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count - 1; + FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.copy_ci_index); + } } - } } static void fb_setscissor() { - rdp.scissor_o.lr_y = (uint32_t)(((rdp.cmd1 & 0x00000FFF) >> 2)); - if (rdp.ci_count) - { - rdp.scissor_o.ul_x = (uint32_t)(((rdp.cmd0 & 0x00FFF000) >> 14)); - rdp.scissor_o.lr_x = (uint32_t)(((rdp.cmd1 & 0x00FFF000) >> 14)); - COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; - if (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x > (uint32_t)(cur_fb.width >> 1)) + rdp.scissor_o.lr_y = (uint32_t)(((rdp.cmd1 & 0x00000FFF) >> 2)); + if (rdp.ci_count) { - if (cur_fb.height == 0 || (cur_fb.width >= rdp.scissor_o.lr_x-1 && cur_fb.width <= rdp.scissor_o.lr_x+1)) - cur_fb.height = rdp.scissor_o.lr_y; + rdp.scissor_o.ul_x = (uint32_t)(((rdp.cmd0 & 0x00FFF000) >> 14)); + rdp.scissor_o.lr_x = (uint32_t)(((rdp.cmd1 & 0x00FFF000) >> 14)); + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count - 1]; + if (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x > (uint32_t)(cur_fb.width >> 1)) + { + if (cur_fb.height == 0 || (cur_fb.width >= rdp.scissor_o.lr_x - 1 && cur_fb.width <= rdp.scissor_o.lr_x + 1)) + cur_fb.height = rdp.scissor_o.lr_y; + } + 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); } - 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); - } } static void fb_uc2_movemem() { - if ((rdp.cmd0 & 0xFF) == 8) - { - uint32_t a = segoffset(rdp.cmd1) >> 1; - short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; - short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; - COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; - if ( abs((int)(scale_x + trans_x - cur_fb.width)) < 3) + if ((rdp.cmd0 & 0xFF) == 8) { - short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; - short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; - uint32_t height = scale_y + trans_y; - if (height < rdp.scissor_o.lr_y) - cur_fb.height = height; + uint32_t a = segoffset(rdp.cmd1) >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a + 0) ^ 1] >> 2; + short trans_x = ((short*)gfx.RDRAM)[(a + 4) ^ 1] >> 2; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count - 1]; + if (abs((int)(scale_x + trans_x - cur_fb.width)) < 3) + { + short scale_y = ((short*)gfx.RDRAM)[(a + 1) ^ 1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a + 5) ^ 1] >> 2; + uint32_t height = scale_y + trans_y; + if (height < rdp.scissor_o.lr_y) + cur_fb.height = height; + } } - } } static void fb_rect() { - if (rdp.frame_buffers[rdp.ci_count-1].width == 32) - return; - int ul_x = ((rdp.cmd1 & 0x00FFF000) >> 14); - int lr_x = ((rdp.cmd0 & 0x00FFF000) >> 14); - int width = lr_x-ul_x; - int diff = abs((int)rdp.frame_buffers[rdp.ci_count-1].width - width); - if (diff < 4) - { - uint32_t lr_y = minval(rdp.scissor_o.lr_y, (rdp.cmd0 & 0xFFF) >> 2); - if (rdp.frame_buffers[rdp.ci_count-1].height < lr_y) + if (rdp.frame_buffers[rdp.ci_count - 1].width == 32) + return; + int ul_x = ((rdp.cmd1 & 0x00FFF000) >> 14); + int lr_x = ((rdp.cmd0 & 0x00FFF000) >> 14); + int width = lr_x - ul_x; + int diff = abs((int)rdp.frame_buffers[rdp.ci_count - 1].width - width); + if (diff < 4) { - 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); - rdp.frame_buffers[rdp.ci_count-1].height = lr_y; + uint32_t lr_y = minval(rdp.scissor_o.lr_y, (rdp.cmd0 & 0xFFF) >> 2); + if (rdp.frame_buffers[rdp.ci_count - 1].height < lr_y) + { + 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); + rdp.frame_buffers[rdp.ci_count - 1].height = lr_y; + } } - } } static void fb_rdphalf_1() { - branch_dl = rdp.cmd1; + branch_dl = rdp.cmd1; } - static void fb_settextureimage() { - if (rdp.main_ci == 0) - return; - COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; - if ( cur_fb.status >= ci_copy ) - return; - if (((rdp.cmd0 >> 19) & 0x03) >= 2) //check that texture is 16/32bit - { - int tex_format = ((rdp.cmd0 >> 21) & 0x07); - uint32_t addr = segoffset(rdp.cmd1); - if ( tex_format == 0 ) + if (rdp.main_ci == 0) + return; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count - 1]; + if (cur_fb.status >= ci_copy) + return; + if (((rdp.cmd0 >> 19) & 0x03) >= 2) //check that texture is 16/32bit { - 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); - if (cur_fb.status == ci_main) - { - rdp.main_ci_last_tex_addr = addr; - if (cur_fb.height == 0) + int tex_format = ((rdp.cmd0 >> 21) & 0x07); + uint32_t addr = segoffset(rdp.cmd1); + if (tex_format == 0) { - cur_fb.height = rdp.scissor_o.lr_y; - rdp.main_ci_end = cur_fb.addr + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); - } - } - if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer - { - if (cur_fb.status == ci_main) - { - rdp.copy_ci_index = rdp.ci_count-1; - cur_fb.status = ci_copy_self; - rdp.scale_x = rdp.scale_x_bak; - rdp.scale_y = rdp.scale_y_bak; - FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1); - } - else - { - if (cur_fb.width == rdp.frame_buffers[rdp.main_ci_index].width) - { - rdp.copy_ci_index = rdp.ci_count-1; - cur_fb.status = ci_copy; - FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); - if ((rdp.main_ci_last_tex_addr >= cur_fb.addr) && - (rdp.main_ci_last_tex_addr < (cur_fb.addr + cur_fb.width*cur_fb.height*cur_fb.size))) + 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); + if (cur_fb.status == ci_main) { - LRDP("motion blur!\n"); - rdp.motionblur = TRUE; + rdp.main_ci_last_tex_addr = addr; + if (cur_fb.height == 0) + { + cur_fb.height = rdp.scissor_o.lr_y; + rdp.main_ci_end = cur_fb.addr + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + } } - else + if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer { - rdp.scale_x = 1.0f; - rdp.scale_y = 1.0f; + if (cur_fb.status == ci_main) + { + rdp.copy_ci_index = rdp.ci_count - 1; + cur_fb.status = ci_copy_self; + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count - 1); + } + else + { + if (cur_fb.width == rdp.frame_buffers[rdp.main_ci_index].width) + { + rdp.copy_ci_index = rdp.ci_count - 1; + cur_fb.status = ci_copy; + FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); + if ((rdp.main_ci_last_tex_addr >= cur_fb.addr) && + (rdp.main_ci_last_tex_addr < (cur_fb.addr + cur_fb.width*cur_fb.height*cur_fb.size))) + { + LRDP("motion blur!\n"); + rdp.motionblur = TRUE; + } + else + { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + } + else if (!(settings.frame_buffer & fb_ignore_aux_copy) && cur_fb.width < rdp.frame_buffers[rdp.main_ci_index].width) + { + rdp.copy_ci_index = rdp.ci_count - 1; + cur_fb.status = ci_aux_copy; + FRDP("rdp.frame_buffers[%d].status = ci_aux_copy\n", rdp.copy_ci_index); + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + else + { + cur_fb.status = ci_aux; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.copy_ci_index); + } + } + FRDP("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", addr, rdp.main_ci); + } + ///* + else if ((cur_fb.status != ci_main) && (addr >= rdp.zimg && addr < rdp.zimg_end)) + { + cur_fb.status = ci_zcopy; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count - 1; + FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count - 1); + } + //*/ + 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))) + { + if (cur_fb.status != ci_main) + { + cur_fb.status = ci_old_copy; + FRDP("rdp.frame_buffers[%d].status = ci_old_copy 1, addr:%08lx\n", rdp.ci_count - 1, rdp.last_drawn_ci_addr); + } + rdp.read_previous_ci = TRUE; + LRDP("read_previous_ci = TRUE\n"); + } + else if ((addr >= rdp.last_drawn_ci_addr) && (addr < (rdp.last_drawn_ci_addr + rdp.maincimg[0].width*rdp.maincimg[0].height * 2))) + { + if (cur_fb.status != ci_main) + { + cur_fb.status = ci_old_copy; + FRDP("rdp.frame_buffers[%d].status = ci_old_copy 2, addr:%08lx\n", rdp.ci_count - 1, rdp.last_drawn_ci_addr); + } + rdp.read_previous_ci = TRUE; + LRDP("read_previous_ci = TRUE\n"); } - } - else if (!(settings.frame_buffer & fb_ignore_aux_copy) && cur_fb.width < rdp.frame_buffers[rdp.main_ci_index].width) - { - rdp.copy_ci_index = rdp.ci_count-1; - cur_fb.status = ci_aux_copy; - FRDP("rdp.frame_buffers[%d].status = ci_aux_copy\n", rdp.copy_ci_index); - rdp.scale_x = 1.0f; - rdp.scale_y = 1.0f; - } - else - { - cur_fb.status = ci_aux; - FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.copy_ci_index); - } } - FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", addr, rdp.main_ci); - } - ///* - else if ((cur_fb.status != ci_main) && (addr >= rdp.zimg && addr < rdp.zimg_end)) - { - cur_fb.status = ci_zcopy; - if (!rdp.copy_zi_index) - rdp.copy_zi_index = rdp.ci_count-1; - FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count-1); - } - //*/ - 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))) - { - if (cur_fb.status != ci_main) + else if (fb_hwfbe_enabled && (cur_fb.status == ci_main)) { - cur_fb.status = ci_old_copy; - FRDP("rdp.frame_buffers[%d].status = ci_old_copy 1, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); + if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer + { + rdp.copy_ci_index = rdp.ci_count - 1; + rdp.black_ci_index = rdp.ci_count - 1; + cur_fb.status = ci_copy_self; + FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count - 1); + } } - rdp.read_previous_ci = TRUE; - LRDP("read_previous_ci = TRUE\n"); - } - else if ((addr >= rdp.last_drawn_ci_addr) && (addr < (rdp.last_drawn_ci_addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2))) - { - if (cur_fb.status != ci_main) - { - cur_fb.status = ci_old_copy; - FRDP("rdp.frame_buffers[%d].status = ci_old_copy 2, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); - } - rdp.read_previous_ci = TRUE; - LRDP("read_previous_ci = TRUE\n"); - } } - else if (fb_hwfbe_enabled && (cur_fb.status == ci_main)) + if (cur_fb.status == ci_unknown) { - if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer - { - rdp.copy_ci_index = rdp.ci_count-1; - rdp.black_ci_index = rdp.ci_count-1; - cur_fb.status = ci_copy_self; - FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1); - } + cur_fb.status = ci_aux; + FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count - 1); } - } - if (cur_fb.status == ci_unknown) - { - cur_fb.status = ci_aux; - FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); - } } static void fb_loadtxtr() { - if (rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown) - { - rdp.frame_buffers[rdp.ci_count-1].status = ci_aux; - FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); - } + if (rdp.frame_buffers[rdp.ci_count - 1].status == ci_unknown) + { + rdp.frame_buffers[rdp.ci_count - 1].status = ci_aux; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count - 1); + } } static void fb_setdepthimage() { - rdp.zimg = segoffset(rdp.cmd1) & BMASK; - rdp.zimg_end = rdp.zimg + rdp.ci_width*rdp.ci_height*2; - FRDP ("fb_setdepthimage. addr %08lx - %08lx\n", rdp.zimg, rdp.zimg_end); - if (rdp.zimg == rdp.main_ci) //strange, but can happen - { - rdp.frame_buffers[rdp.main_ci_index].status = ci_unknown; - if (rdp.main_ci_index < rdp.ci_count) + rdp.zimg = segoffset(rdp.cmd1) & BMASK; + rdp.zimg_end = rdp.zimg + rdp.ci_width*rdp.ci_height * 2; + FRDP("fb_setdepthimage. addr %08lx - %08lx\n", rdp.zimg, rdp.zimg_end); + if (rdp.zimg == rdp.main_ci) //strange, but can happen { - rdp.frame_buffers[rdp.main_ci_index].status = ci_zimg; - FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.main_ci_index); - rdp.main_ci_index++; - rdp.frame_buffers[rdp.main_ci_index].status = ci_main; - FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.main_ci_index); - rdp.main_ci = rdp.frame_buffers[rdp.main_ci_index].addr; - 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); - for (int i = rdp.main_ci_index+1; i < rdp.ci_count; i++) - { - COLOR_IMAGE & fb = rdp.frame_buffers[i]; - if (fb.addr == rdp.main_ci) + rdp.frame_buffers[rdp.main_ci_index].status = ci_unknown; + if (rdp.main_ci_index < rdp.ci_count) { - fb.status = ci_main; - FRDP("rdp.frame_buffers[%d].status = ci_main\n", i); + rdp.frame_buffers[rdp.main_ci_index].status = ci_zimg; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.main_ci_index); + rdp.main_ci_index++; + rdp.frame_buffers[rdp.main_ci_index].status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.main_ci_index); + rdp.main_ci = rdp.frame_buffers[rdp.main_ci_index].addr; + 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); + for (int i = rdp.main_ci_index + 1; i < rdp.ci_count; i++) + { + COLOR_IMAGE & fb = rdp.frame_buffers[i]; + if (fb.addr == rdp.main_ci) + { + fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", i); + } + } + } + else + { + rdp.main_ci = 0; } - } } - else + for (int i = 0; i < rdp.ci_count; i++) { - rdp.main_ci = 0; + COLOR_IMAGE & fb = rdp.frame_buffers[i]; + if ((fb.addr == rdp.zimg) && (fb.status == ci_aux || fb.status == ci_useless)) + { + fb.status = ci_zimg; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", i); + } } - } - for (int i = 0; i < rdp.ci_count; i++) - { - COLOR_IMAGE & fb = rdp.frame_buffers[i]; - if ((fb.addr == rdp.zimg) && (fb.status == ci_aux || fb.status == ci_useless)) - { - fb.status = ci_zimg; - FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", i); - } - } } static void fb_setcolorimage() { - rdp.ocimg = rdp.cimg; - rdp.cimg = segoffset(rdp.cmd1) & BMASK; - COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count]; - cur_fb.width = (rdp.cmd0 & 0xFFF) + 1; - if (cur_fb.width == 32 ) - cur_fb.height = 32; - else if (cur_fb.width == 16 ) - cur_fb.height = 16; - else if (rdp.ci_count > 0) - cur_fb.height = rdp.scissor_o.lr_y; - else - cur_fb.height = 0; - cur_fb.format = (rdp.cmd0 >> 21) & 0x7; - cur_fb.size = (rdp.cmd0 >> 19) & 0x3; - cur_fb.addr = rdp.cimg; - cur_fb.changed = 1; - /* - if (rdp.ci_count > 0) - if (rdp.frame_buffers[0].addr == rdp.cimg) - rdp.frame_buffers[0].height = rdp.scissor_o.lr_y; - */ - 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); - if (rdp.cimg == rdp.zimg) - { - cur_fb.status = ci_zimg; - rdp.zimg_end = rdp.zimg + cur_fb.width*rdp.scissor_o.lr_y*2; - FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.ci_count); - } - else if (rdp.cimg == rdp.tmpzimg) - { - cur_fb.status = ci_zcopy; - if (!rdp.copy_zi_index) - rdp.copy_zi_index = rdp.ci_count-1; - FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count); - } - else if (rdp.main_ci != 0) - { - if (rdp.cimg == rdp.main_ci) //switched to main fb again + rdp.ocimg = rdp.cimg; + rdp.cimg = segoffset(rdp.cmd1) & BMASK; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count]; + cur_fb.width = (rdp.cmd0 & 0xFFF) + 1; + if (cur_fb.width == 32) + cur_fb.height = 32; + else if (cur_fb.width == 16) + cur_fb.height = 16; + else if (rdp.ci_count > 0) + cur_fb.height = rdp.scissor_o.lr_y; + else + cur_fb.height = 0; + cur_fb.format = (rdp.cmd0 >> 21) & 0x7; + cur_fb.size = (rdp.cmd0 >> 19) & 0x3; + cur_fb.addr = rdp.cimg; + cur_fb.changed = 1; + /* + if (rdp.ci_count > 0) + if (rdp.frame_buffers[0].addr == rdp.cimg) + rdp.frame_buffers[0].height = rdp.scissor_o.lr_y; + */ + 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); + if (rdp.cimg == rdp.zimg) { - cur_fb.height = maxval(cur_fb.height, rdp.frame_buffers[rdp.main_ci_index].height); - rdp.main_ci_index = rdp.ci_count; - rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); - cur_fb.status = ci_main; - FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + cur_fb.status = ci_zimg; + rdp.zimg_end = rdp.zimg + cur_fb.width*rdp.scissor_o.lr_y * 2; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.ci_count); } - else // status is not known yet + else if (rdp.cimg == rdp.tmpzimg) { - cur_fb.status = ci_unknown; + cur_fb.status = ci_zcopy; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count - 1; + FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count); } - } - else - { - if ((rdp.zimg != rdp.cimg))//&& (rdp.ocimg != rdp.cimg)) + else if (rdp.main_ci != 0) { - rdp.main_ci = rdp.cimg; - rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); - rdp.main_ci_index = rdp.ci_count; - cur_fb.status = ci_main; - FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + if (rdp.cimg == rdp.main_ci) //switched to main fb again + { + cur_fb.height = maxval(cur_fb.height, rdp.frame_buffers[rdp.main_ci_index].height); + rdp.main_ci_index = rdp.ci_count; + rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + cur_fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + } + else // status is not known yet + { + cur_fb.status = ci_unknown; + } } else { - cur_fb.status = ci_unknown; + if ((rdp.zimg != rdp.cimg))//&& (rdp.ocimg != rdp.cimg)) + { + rdp.main_ci = rdp.cimg; + rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + rdp.main_ci_index = rdp.ci_count; + cur_fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + } + else + { + cur_fb.status = ci_unknown; + } } - - } - 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 - { - if (fb_hwfbe_enabled && !(settings.frame_buffer & fb_useless_is_useless)) + 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 { - rdp.frame_buffers[rdp.ci_count-1].status = ci_aux; - rdp.frame_buffers[rdp.ci_count-1].changed = 0; - FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); + if (fb_hwfbe_enabled && !(settings.frame_buffer & fb_useless_is_useless)) + { + rdp.frame_buffers[rdp.ci_count - 1].status = ci_aux; + rdp.frame_buffers[rdp.ci_count - 1].changed = 0; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count - 1); + } + else + { + rdp.frame_buffers[rdp.ci_count - 1].status = ci_useless; + /* + uint32_t addr = rdp.frame_buffers[rdp.ci_count-1].addr; + for (int i = 0; i < rdp.ci_count - 1; i++) + { + if (rdp.frame_buffers[i].addr == addr) + { + rdp.frame_buffers[rdp.ci_count-1].status = rdp.frame_buffers[i].status; + break; + } + } + //*/ + FRDP("rdp.frame_buffers[%d].status = %s\n", rdp.ci_count - 1, CIStatus[rdp.frame_buffers[rdp.ci_count - 1].status]); + } } - else + if (cur_fb.status == ci_main) { - rdp.frame_buffers[rdp.ci_count-1].status = ci_useless; - /* - uint32_t addr = rdp.frame_buffers[rdp.ci_count-1].addr; - for (int i = 0; i < rdp.ci_count - 1; i++) - { - if (rdp.frame_buffers[i].addr == addr) - { - rdp.frame_buffers[rdp.ci_count-1].status = rdp.frame_buffers[i].status; - break; - } - } - //*/ - FRDP("rdp.frame_buffers[%d].status = %s\n", rdp.ci_count-1, CIStatus[rdp.frame_buffers[rdp.ci_count-1].status]); + int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx.VI_ORIGIN_REG)) ? FALSE : TRUE; + if ((rdp.maincimg[0].addr != cur_fb.addr) && SwapOK && viSwapOK) + { + SwapOK = FALSE; + rdp.swap_ci_index = rdp.ci_count; + } } - } - if (cur_fb.status == ci_main) - { - int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx.VI_ORIGIN_REG)) ? FALSE : TRUE; - if ((rdp.maincimg[0].addr != cur_fb.addr) && SwapOK && viSwapOK) - { - SwapOK = FALSE; - rdp.swap_ci_index = rdp.ci_count; - } - } - rdp.ci_count++; - if (rdp.ci_count > NUMTEXBUF) //overflow - rdp.halt = 1; + rdp.ci_count++; + if (rdp.ci_count > NUMTEXBUF) //overflow + rdp.halt = 1; } // RDP graphic instructions pointer table used in DetectFrameBufferUsage static rdp_instr gfx_instruction_lite[9][256] = { - { - // uCode 0 - RSP SW 2.0X - // 00-3f - // games: Super Mario 64, Tetrisphere, Demos - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: Unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc0_culldl, 0, - // c0-ff: RDP commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, - - // uCode 1 - F3DEX 1.XX - // 00-3f - // games: Mario Kart, Star Fox - { - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + { + // uCode 0 - RSP SW 2.0X + // 00-3f + // games: Super Mario 64, Tetrisphere, Demos + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, uc6_loaducode, - uc1_branch_z, 0, 0, 0, - fb_rdphalf_1, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc2_culldl, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, // c0-ff: RDP commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - // uCode 2 - F3DEX 2.XX - // games: Zelda 64 - { + // uCode 1 - F3DEX 1.XX + // 00-3f + // games: Mario Kart, Star Fox + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, uc6_loaducode, + uc1_branch_z, 0, 0, 0, + fb_rdphalf_1, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc2_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + // uCode 2 - F3DEX 2.XX + // games: Zelda 64 + { // 00-3f - 0, 0, 0, uc2_culldl, - uc1_branch_z, 0, 0, 0, - 0, fb_bg_copy, fb_bg_copy, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + 0, 0, 0, uc2_culldl, + uc1_branch_z, 0, 0, 0, + 0, fb_bg_copy, fb_bg_copy, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - // 80-bf: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + // 80-bf: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - // c0-ff: RDP commands mixed with uc2 commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, uc2_dlist_cnt, 0, 0, - 0, 0, 0, fb_uc2_moveword, - fb_uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, - 0, fb_rdphalf_1, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + // c0-ff: RDP commands mixed with uc2 commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, uc2_dlist_cnt, 0, 0, + 0, 0, 0, fb_uc2_moveword, + fb_uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + 0, fb_rdphalf_1, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - // uCode 3 - "RSP SW 2.0D", but not really + // uCode 3 - "RSP SW 2.0D", but not really + // 00-3f + // games: Wave Race + // ** Added by Gonetz ** + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + { + // uCode 4 - RSP SW 2.0D EXT // 00-3f - // games: Wave Race - // ** Added by Gonetz ** - { - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc0_culldl, 0, - // c0-ff: RDP commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + // games: Star Wars: Shadows of the Empire + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + rdp_noop, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - { - // uCode 4 - RSP SW 2.0D EXT - // 00-3f - // games: Star Wars: Shadows of the Empire - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: Unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc0_culldl, 0, - // c0-ff: RDP commands - rdp_noop, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + { + // uCode 5 - RSP SW 2.0 Diddy + // 00-3f + // games: Diddy Kong Racing + 0, 0, 0, 0, + 0, 0, uc0_displaylist, uc5_dl_in_mem, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - { - // uCode 5 - RSP SW 2.0 Diddy - // 00-3f - // games: Diddy Kong Racing - 0, 0, 0, 0, - 0, 0, uc0_displaylist, uc5_dl_in_mem, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: Unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc0_culldl, 0, - // c0-ff: RDP commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + // uCode 6 - S2DEX 1.XX + // games: Yoshi's Story + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, uc6_loaducode, + uc6_select_dl, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc2_culldl, 0, + // c0-ff: RDP commands + 0, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr, + fb_loadtxtr, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - // uCode 6 - S2DEX 1.XX - // games: Yoshi's Story - { - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, uc6_loaducode, - uc6_select_dl, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc2_culldl, 0, - // c0-ff: RDP commands - 0, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr, - fb_loadtxtr, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, - { - 0, 0, 0, 0, - 0, 0, uc0_displaylist, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - // 80-bf: Immediate commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - uc0_enddl, 0, 0, 0, - fb_uc0_moveword, 0, uc0_culldl, 0, - // c0-ff: RDP commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - }, + { + // 00-3f + 0, 0, 0, uc2_culldl, + uc1_branch_z, 0, 0, 0, + 0, fb_bg_copy, fb_bg_copy, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - { - // 00-3f - 0, 0, 0, uc2_culldl, - uc1_branch_z, 0, 0, 0, - 0, fb_bg_copy, fb_bg_copy, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - // 40-7f: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + // 80-bf: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, - // 80-bf: unused - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - - // c0-ff: RDP commands mixed with uc2 commands - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, uc2_dlist_cnt, 0, 0, - 0, 0, 0, fb_uc2_moveword, - 0, uc2_load_ucode, uc0_displaylist, uc0_enddl, - 0, 0, 0, 0, - fb_rect, fb_rect, 0, 0, - 0, 0, 0, 0, - 0, fb_setscissor, 0, 0, - 0, 0, 0, 0, - 0, 0, fb_rect, 0, - 0, 0, 0, 0, - 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage - } + // c0-ff: RDP commands mixed with uc2 commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, uc2_dlist_cnt, 0, 0, + 0, 0, 0, fb_uc2_moveword, + 0, uc2_load_ucode, uc0_displaylist, uc0_enddl, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + } };