/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2009 icepir8 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include //#include #include "3dmath.h" void rsp_uc04_vertex(); void rsp_uc04_modifyvertex(); void rsp_uc04_culldl(); void rsp_uc04_branchz(); void rsp_uc04_tri1(); void rsp_uc04_tri2(); void rsp_uc04_quad(); void rsp_uc04_fastcombine(); void rsp_uc04_rdphalf_cont(); void rsp_uc04_rdphalf_2(); void rsp_uc04_line3d(); void rsp_uc04_texture(); void rsp_uc04_popmatrix(); void rsp_uc04_setgeometrymode(); void rsp_uc04_matrix(); void rsp_uc04_moveword(); void rsp_uc04_movemem(); void rsp_uc04_displaylist(); void rsp_uc04_enddl(); void rsp_uc04_rdphalf_1(); void rsp_uc04_setothermode_l(); void rsp_uc04_setothermode_h(); void rsp_uc04_special_1() { DebugBox("special_1"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SPECIAL_1\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_special_2() { DebugBox("special_2"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SPECIAL_2\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_special_3() { DebugBox("special_3"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SPECIAL_3\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_dma_io() { DebugBox("dma_io"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_DMA_IO\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_load_ucode() { DebugBox("load_ucode"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_LOAD_UCODE\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_noop() { DebugBox("noop"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_NOOP\n", ADDR, CMD0, CMD1); #endif } extern float fScalex; extern float fScaley; ////////////////////////////////////////////////////////////////////////////// // structure is tricky for changing the endians // ////////////////////////////////////////////////////////////////////////////// typedef struct { _s16 y; _s16 x; _u16 flags; _s16 z; _s16 t; _s16 s; _u8 a; _u8 b; _u8 g; _u8 r; } t_vtx_uc4; _u32 bzaddr; ////////////////////////////////////////////////////////////////////////////// // LoadVertex // ////////////////////////////////////////////////////////////////////////////// void rsp_uc04_vertex() { _u32 a = segoffset2addr(rdp_reg.cmd1); int v0, i, n; n = (rdp_reg.cmd0 >> 12) & 0xff; v0 = ((rdp_reg.cmd0 >> 1) & 0x7f) - n; if (refresh_matrix) update_cmbmatrix(); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_LOADVTX vertex %i..%i\n", ADDR, CMD0, CMD1, v0, v0+n-1); #endif for(i = 0; i < n; i++) { // t_vtx_uc4 *vtx = (t_vtx_uc4 *)&pRDRAM[a+(i*sizeof(t_vtx_uc4))]; _u32 ad = a + (i * sizeof(t_vtx_uc4)); rdp_reg.vtx[v0].x = (float)(_s16)doReadMemHalfWord(ad+0); rdp_reg.vtx[v0].y = (float)(_s16)doReadMemHalfWord(ad+2); rdp_reg.vtx[v0].z = (float)(_s16)doReadMemHalfWord(ad+4); rdp_reg.vtx[v0].flags = (_u16)doReadMemHalfWord(ad+6); rdp_reg.vtx[v0].s = (float)(_s16)doReadMemHalfWord(ad+8); rdp_reg.vtx[v0].t = (float)(_s16)doReadMemHalfWord(ad+10); rdp_reg.vtx[v0].r = (_u8)doReadMemByte(ad+12); rdp_reg.vtx[v0].g = (_u8)doReadMemByte(ad+13); rdp_reg.vtx[v0].b = (_u8)doReadMemByte(ad+14); rdp_reg.vtx[v0].a = (_u8)doReadMemByte(ad+15); if( (USE_MM_HACK) && rdp_reg.combine_h == 0x00262a60 && rdp_reg.combine_l == 0x150c937f && rdp_reg.tile == 0 ) { // Hack for Zelda Sun t_tile *t0 = &rdp_reg.td[0]; t_tile *t1 = &rdp_reg.td[1]; if( t0->format == 4 && t0->size == 1 && t0->Width == 64 && t1->format == 4 && t1->size == 1 && t1->Width == 64 && t0->Height == t1->Height ) { rdp_reg.vtx[v0].s /= 2; rdp_reg.vtx[v0].t /= 2; } } { t_vtx *vertex = &rdp_reg.vtx[v0]; float tmpvtx[4]; tmpvtx[0] = vertex->x; tmpvtx[1] = vertex->y; tmpvtx[2] = vertex->z; tmpvtx[3] = 1.0f; // transform_vector(&tmpvtx[0],vertex->x,vertex->y,vertex->z); // project_vector2(&tmpvtx[0]); cmbtrans_vector(&tmpvtx[0]); // if ( // (tmpvtx[2] < 0.001f) // && (tmpvtx[2] >= -0.001f) // ) // tmpvtx[2] = tmpvtx[3]; vertex->x = tmpvtx[0]; vertex->y = tmpvtx[1]; vertex->z = tmpvtx[2]; vertex->w = tmpvtx[3]; tmpvtx[0] = (float)(_s8)vertex->r; tmpvtx[1] = (float)(_s8)vertex->g; tmpvtx[2] = (float)(_s8)vertex->b; //transform_normal(&tmpvtx[0]); NormalizeVector(&tmpvtx[0]); vertex->n1 = tmpvtx[0]; vertex->n2 = tmpvtx[1]; vertex->n3 = tmpvtx[2]; if (0x00020000 & rdp_reg.geometrymode) { if (USE_MM_HACK) math_lightingMM((t_vtx*)(char*)vertex, vertex->lcolor); else math_lightingN((t_vtx*)(char*)vertex, vertex->lcolor); } else { vertex->lcolor[0] = (float)vertex->r / 255.0f; vertex->lcolor[1] = (float)vertex->g / 255.0f; vertex->lcolor[2] = (float)vertex->b / 255.0f; vertex->lcolor[3] = (float)vertex->a / 255.0f; } if (0x00040000 & rdp_reg.geometrymode) { // G_TEXTURE_GEN enable the automatic generation of the texture // coordinates s and t. A spherical mapping is used, based on the normal. float fLenght; tmpvtx[0] = (float)(_s8)vertex->r; tmpvtx[1] = (float)(_s8)vertex->g; tmpvtx[2] = (float)(_s8)vertex->b; cmbtrans_normal(&tmpvtx[0]); vertex->n1 = tmpvtx[0]; vertex->n2 = tmpvtx[1]; vertex->n3 = tmpvtx[2]; fLenght = VectorLength(tmpvtx); vertex->s = (0.5f + (0.5f * vertex->n1 / fLenght)); vertex->t = (0.5f - (0.5f * vertex->n2 / fLenght)); // vertex->s = (0.5f + (0.5f * vertex->n1)); // vertex->t = (0.5f - (0.5f * vertex->n2)); } #ifdef LOG_ON LOG_TO_FILE("\tvtx[%02i]: xyzw -> %12.5f, %12.5f, %12.5f, %12.5f\n" "\ts=%9.4f, t=%9.4f\n\tcolor [%02X,%02X,%02X]\n" "\tnormals [%12.5f,%12.f,%12.5f]\n", v0, rdp_reg.vtx[v0].x, rdp_reg.vtx[v0].y, rdp_reg.vtx[v0].z, rdp_reg.vtx[v0].w, rdp_reg.vtx[v0].s, rdp_reg.vtx[v0].t, rdp_reg.vtx[v0].r, rdp_reg.vtx[v0].g, rdp_reg.vtx[v0].b, rdp_reg.vtx[v0].n1, rdp_reg.vtx[v0].n2, rdp_reg.vtx[v0].n3); #endif } v0++; } } static _u32 tfbuffer[512*256]; extern byte bmpHdr[]; extern int bmpcnt; extern _u32 *Color16_32; void DumpBmp(_u8 *bffr,_u32 width, _u32 height) { int x,y; _u32 *tbffr = (_u32*)bffr; char bmpFileName[128] = ""; FILE *bmpFile; byte tline[1024 * 4]; char EmuPath[128] = ""; GetEmuDir(EmuPath); *(_u32*)&bmpHdr[2] = (_u32) ((width * height * 3) + 0x036); *(_u32*)&bmpHdr[0x12] = width; *(_u32*)&bmpHdr[0x16] = height; *(_u32*)&bmpHdr[0x22] = (_u32) ((width * height * 3)); sprintf(bmpFileName,"%sTiles\\Dump%04i.bmp",EmuPath,bmpcnt++); bmpFile = fopen(bmpFileName,"wb"); fwrite(bmpHdr, 0x36, 1, bmpFile); for ( y = height - 1;y >= 0; y--) { tbffr = (_u32*)bffr; tbffr += (y * width); for (x = 0; x < (int)width; x++) { { tline[x*3+0] = ((_u8*)tbffr)[2]; tline[x*3+1] = ((_u8*)tbffr)[1]; tline[x*3+2] = ((_u8*)tbffr)[0]; tbffr++; } } fwrite(tline, width * 3, 1, bmpFile); } fclose(bmpFile); } typedef struct DRAWIMAGE_t { float frameX; float frameY; float frameW; float frameH; WORD imageX; WORD imageY; WORD imageW; WORD imageH; DWORD imagePtr; BYTE imageFmt; BYTE imageSiz; WORD imagePal; } DRAWIMAGE; void rsp_uc04_fullscreen() { unsigned long i, j; unsigned int width = 256; unsigned int height =256; unsigned int mode = 2; _u32 *add = (_u32*)(&pRDRAM[segoffset2addr(rdp_reg.cmd1)]); t_Fullscreen *fsadd = (t_Fullscreen*)(&pRDRAM[segoffset2addr(rdp_reg.cmd1)]); _u32 Scrwidth = fsadd->imageW >> 2; _u32 Scrheight = fsadd->imageH >> 2; _u32 Dstwidth = fsadd->frameW >> 2; _u32 Dstheight = fsadd->frameH >> 2; _u32 fladd = segoffset2addr(fsadd->imagePtr); _u16 src; _u16 *base_src_ptr; // _u32 *lsrc; _u32 *lbase_src_ptr; _u32 *dest; _u32 tmpTex = 0x0800001; float txl = 0.0f; float tyl = 0.0f; float txh = 319.0f * fScalex; float tyh = 239.0f * fScaley; float color[4]={1.0f,1.0f,1.0f,1.0f}; GLint hadDepthTest, hadBlending, hadAlphaTest; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_FULLSCREEN",ADDR, CMD0, CMD1); LOG_TO_FILE("\tAddress = %08x",segoffset2addr(rdp_reg.cmd1)); LOG_TO_FILE("\tImageAddress = %08x",fladd); LOG_TO_FILE("\tSrcWidth = %i\tSrcHeight = %i",Scrwidth,Scrheight); LOG_TO_FILE("\tDstWidth = %i\tDstHeight = %i\n",Dstwidth,Dstheight); #endif /**/ glGetIntegerv(GL_DEPTH_TEST, &hadDepthTest); //** Should be glGetBooleanv, but glGetIntegerv(GL_BLEND, &hadBlending); //** Should be glGetBooleanv, but glGetIntegerv(GL_ALPHA_TEST, &hadAlphaTest); //** Should be glGetBooleanv, but glPushAttrib(GL_ENABLE_BIT); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); Src_Alpha = GL_SRC_ALPHA; Dst_Alpha = GL_ONE_MINUS_SRC_ALPHA; glBlendFunc(Src_Alpha, Dst_Alpha); glAlphaFunc(GL_GEQUAL,AlphaLevel); glEnable(GL_BLEND); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); SetOrtho(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glEnable(GL_TEXTURE_2D); /**/ base_src_ptr = (_u16*)(&pRDRAM[fladd]); lbase_src_ptr = (_u32*)(&pRDRAM[fladd]); for (i = 0; i<256*512; i++) tfbuffer[i] = 0; for(i=0; i> 1); BYTE where = (BYTE)((CMD0 >> 16) & 0xFF); switch (where) { case F3DEX2_POINT_RGBA: rdp_reg.vtx[vtx].r = (_u8)((CMD1 >> 24) & 0xFF); rdp_reg.vtx[vtx].g = (_u8)((CMD1 >> 16) & 0xFF); rdp_reg.vtx[vtx].b = (_u8)((CMD1 >> 8) & 0xFF); rdp_reg.vtx[vtx].a = (_u8)((CMD1 ) & 0xFF); break; case F3DEX2_POINT_ST: rdp_reg.vtx[vtx].s = (SHORT)((CMD1 >> 16) & 0xFFFF);// * 0.03125f; rdp_reg.vtx[vtx].t = (SHORT)(CMD1 & 0xFFFF);// * 0.03125f; break; case F3DEX2_POINT_XYSCREEN: break; case F3DEX2_POINT_ZSCREEN: break; } //rdp_reg.vtx[vtx].changed = TRUE; //DebugBox("ModifyVertex\n"); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_MODIFYVTX \n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_culldl() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_CULLDL\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_branchz() { rdp_reg.pc_i++; if(rdp_reg.pc_i > RDP_STACK_SIZE - 1) { return; } rdp_reg.pc[rdp_reg.pc_i] = bzaddr; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_BRANCHZ\n", ADDR, CMD0, CMD1); #endif } void rsp_uc04_tri1() { int vn[3]; vn[0] = ((CMD0 >> 16) & 0xff) / 2; vn[1] = ((CMD0 >> 8) & 0xff) / 2; vn[2] = ( CMD0 & 0xff) / 2; DrawVisualTriangle(vn); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_TRI1 (%i,%i,%i)\n", ADDR, CMD0, CMD1, vn[0], vn[1], vn[2]); #endif } // void rsp_uc04_tri1() void rsp_uc04_tri2() { int vn[6]; vn[0] = ((CMD0 >> 16) & 0xff) / 2; vn[1] = ((CMD0 >> 8) & 0xff) / 2; vn[2] = ( CMD0 & 0xff) / 2; vn[3] = ((CMD1 >> 16) & 0xff) / 2; vn[4] = ((CMD1 >> 8) & 0xff) / 2; vn[5] = ( CMD1 & 0xff) / 2; DrawVisualTriangle(vn); DrawVisualTriangle(vn+3); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_TRI2 (%i,%i,%i) (%i,%i,%i)\n", ADDR, CMD0, CMD1, vn[0], vn[1], vn[2], vn[3], vn[4], vn[5]); #endif } // void rsp_uc04_tri2() void rsp_uc04_quad() { int vn[6]; DebugBox("12"); vn[0] = ((rdp_reg.cmd0 >> 16) & 0xff) / 2; vn[1] = ((rdp_reg.cmd0 >> 8) & 0xff) / 2; vn[2] = ( rdp_reg.cmd0 & 0xff) / 2; vn[3] = ((rdp_reg.cmd1 >> 16) & 0xff) / 2; vn[4] = ((rdp_reg.cmd1 >> 8) & 0xff) / 2; vn[5] = ( rdp_reg.cmd1 & 0xff) / 2; DrawVisualTriangle(vn); DrawVisualTriangle(vn+3); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_QUAD (%i,%i,%i) (%i,%i,%i)\n", ADDR, CMD0, CMD1, vn[0], vn[1], vn[2], vn[3], vn[4], vn[5]); #endif } // static void rsp_uc04_quad() void rsp_uc04_fastcombine() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_FAST_COMBINE",ADDR, CMD0, CMD1); #endif } void rsp_uc04_rdphalf_cont() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_RDP_HALF_1\n",ADDR, CMD0, CMD1); #endif } void rsp_uc04_rdphalf_2() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_RDP_HALF_2\n",ADDR, CMD0, CMD1); #endif } void rsp_uc04_line3d() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_LINE_3D\n",ADDR, CMD0, CMD1); #endif } void rsp_uc04_texture() { int idx; int tile = (rdp_reg.cmd0 >> 8) & 0x07; //** tile t0 int tile1 = (tile + 1) & 0x07; //** tile t1 _u32 mipmap_level = (rdp_reg.cmd0 >> 11) & 0x07; //** mipmap_level - not used yet _u32 on = (rdp_reg.cmd0 & 0xff); //** 1: on - 0:off float s = (float)((rdp_reg.cmd1 >> 16) & 0xffff); float t = (float)((rdp_reg.cmd1 ) & 0xffff); float SScale; float TScale; t_tile *tmp_tile = &rdp_reg.td[tile]; t_tile *tmp_tile1 = &rdp_reg.td[tile1]; tmp_tile->Texture_on = (_u8)on; rdp_reg.tile = tile; //if (s<=1) // SScale=1.0f; //else SScale=(float)s/65535.f; //if (t<=1) // TScale=1.0f; //else TScale=(float)t/65535.f; TScale/=32.f; SScale/=32.f; if( (((rdp_reg.cmd1)>>16)&0xFFFF) == 0xFFFF ) { SScale = 1/32.0f; } else if( (((rdp_reg.cmd1)>>16)&0xFFFF) == 0x8000 ) { SScale = 1/64.0f; } if( (((rdp_reg.cmd1) )&0xFFFF) == 0xFFFF ) { TScale = 1/32.0f; } else if( (((rdp_reg.cmd1) )&0xFFFF) == 0x8000 ) { TScale = 1/64.0f; } for (idx=0;idx<7;idx++) { rdp_reg.tile = idx; tmp_tile1 = &rdp_reg.td[idx]; tmp_tile1->SScale=SScale; tmp_tile1->TScale=TScale; rdp_reg.m_CurTile = tmp_tile1; MathTextureScales(); } rdp_reg.tile = tile; rdp_reg.m_CurTile = tmp_tile; // MathTextureScales(); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_TEXTURE",ADDR, CMD0, CMD1); LOG_TO_FILE("\tTile = %i, Mipmap = %i, enambled = %s\n",tile, mipmap_level, (on)?"on":"off"); #endif } void rsp_uc04_popmatrix() { // _u32 param = (CMD1 / 64); _u32 param = (((((CMD0 >> 19) & 0x1f) + 1) * 8)/ 64); switch(CMD1) { case 0x40: pop_matrix(); break; } #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_POPMATRIX\n",ADDR, CMD0, CMD1); #endif } void rsp_uc04_setgeometrymode() { BOOL mode = FALSE; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SETGEOMETRYMODE",ADDR, CMD0, CMD1); LOG_TO_FILE( "\tClear:" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s", (!(rdp_reg.cmd0 & 0x00000001)) ? "\tzbuffer\n" : "", (!(rdp_reg.cmd0 & 0x00000002)) ? "\ttexture\n" : "", (!(rdp_reg.cmd0 & 0x00000004)) ? "\tshade\n" : "", (!(rdp_reg.cmd0 & 0x00000200)) ? "\tshade smooth\n" : "", (!(rdp_reg.cmd0 & 0x00001000)) ? "\tcull front\n" : "", (!(rdp_reg.cmd0 & 0x00002000)) ? "\tcull back\n" : "", (!(rdp_reg.cmd0 & 0x00010000)) ? "\tfog\n" : "", (!(rdp_reg.cmd0 & 0x00020000)) ? "\tlightning\n" : "", (!(rdp_reg.cmd0 & 0x00040000)) ? "\ttexture gen\n" : "", (!(rdp_reg.cmd0 & 0x00080000)) ? "\ttexture gen lin\n" : "", (!(rdp_reg.cmd0 & 0x00100000)) ? "\tlod\n" : "" ); LOG_TO_FILE( "\tSet:\n" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s", (rdp_reg.cmd1 & 0x00000001) ? "\t zbuffer\n" : "", (rdp_reg.cmd1 & 0x00000002) ? "\t texture\n" : "", (rdp_reg.cmd1 & 0x00000004) ? "\t shade\n" : "", (rdp_reg.cmd1 & 0x00000200) ? "\t shade smooth\n" : "", (rdp_reg.cmd1 & 0x00001000) ? "\t cull front\n" : "", (rdp_reg.cmd1 & 0x00002000) ? "\t cull back\n" : "", (rdp_reg.cmd1 & 0x00010000) ? "\t fog\n" : "", (rdp_reg.cmd1 & 0x00020000) ? "\t lightning\n" : "", (rdp_reg.cmd1 & 0x00040000) ? "\t texture gen\n" : "", (rdp_reg.cmd1 & 0x00080000) ? "\t texture gen lin\n" : "", (rdp_reg.cmd1 & 0x00100000) ? "\t lod\n" : "" ); #endif rdp_reg.geometrymode &= (rdp_reg.cmd0 & 0x0ffffff); rdp_reg.geometrymode |= (rdp_reg.cmd1 & 0x0ffffff); if(rdp_reg.cmd1 & 0x00000002) rdp_reg.geometrymode_textures = 1; switch(rdp_reg.geometrymode & 0x00000600) { case 0x0200: Render_geometry_cullfront(1); break; case 0x0400: Render_geometry_cullback(1); break; case 0x0600: Render_geometry_cullfrontback(1); break; default: Render_geometry_cullfrontback(0); break; } //** switch(rdp_reg.geometrymode & 0x00003000) mode = (rdp_reg.geometrymode & 0x00080000) ? FALSE : TRUE; if(mode) // glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); mode = (rdp_reg.geometrymode & 0x00010000) ? FALSE : TRUE; //Render_Fog(mode); // if((rdp_reg.geometrymode & 0x00020000) != 0) // rdp_reg.useLights = 1; } void rsp_uc04_matrix() { static char *mtxop[] = { "modelview mul push", "modelview mul nopush", "modelview load push", "modelview load nopush", "projection mul push", "projection mul nopush", "projection load push", "projection load nopush"}; _u32 a = segoffset2addr(rdp_reg.cmd1); _u8 command =(_u8)(CMD0 & 0xff); float m[4][4]; // int i, j; refresh_lights = TRUE; hleGetMatrix((float*)&m[0,0], &pRDRAM[a]); #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_LOADMTX at %08X\n", ADDR, CMD0, CMD1, a); LOG_TO_FILE( "\t%s\n" "\t\t{ %#+12.5f %#+12.5f %#+12.5f %#+12.5f }\n" "\t\t{ %#+12.5f %#+12.5f %#+12.5f %#+12.5f }\n" "\t\t{ %#+12.5f %#+12.5f %#+12.5f %#+12.5f }\n" "\t\t{ %#+12.5f %#+12.5f %#+12.5f %#+12.5f }\n", mtxop[command], m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3] ); #endif switch(command) { case 0: // modelview mul push push_mult_matrix((GLfloat *)m); break; case 1: // modelview mul nopush mult_matrix((GLfloat *)m); break; case 2: // modelview load push push_load_matrix((GLfloat *)m); break; case 3: // modelview load nopush load_matrix((GLfloat *)m); break; case 4: // projection mul push DebugBox("strange Matrix-CMD"); //glMultMatrixf((GLfloat *)m); mult_prj_matrix((GLfloat *)m); break; case 5: // projection mul nopush //glMultMatrixf((GLfloat *)m); mult_prj_matrix((GLfloat *)m); break; case 6: // projection load push DebugBox("strange Matrix-CMD"); //glLoadMatrixf((GLfloat *)m); load_prj_matrix((GLfloat *)m); break; case 7: // projection load nopush //glLoadMatrixf((GLfloat *)m); load_prj_matrix((GLfloat *)m); break; default: break; } /* switch(command) */ } void rsp_uc04_moveword() { int i; _u16 offset= (_u16)(CMD0 & 0xffff); _u8 index= (_u8)(CMD0>>16)&0xff; _u64 data=rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_MOVEWORD", ADDR, CMD0, CMD1); #endif switch(index) { case G_MW_MATRIX: { // do matrix pre-mult so it's re-updated next time if (refresh_matrix) update_cmbmatrix(); if (CMD0 & 0x20) // fractional part { float fpart; int index_x = (CMD0 & 0x1F) >> 1; int index_y = index_x >> 2; index_x &= 3; fpart = (CMD1>>16)/65536.0f; cmb_mtrx[index_y][index_x] = (float)(int)cmb_mtrx[index_y][index_x]; cmb_mtrx[index_y][index_x] += fpart; fpart = (CMD1&0xFFFF)/65536.0f; cmb_mtrx[index_y][index_x+1] = (float)(int)cmb_mtrx[index_y][index_x+1]; cmb_mtrx[index_y][index_x+1] += fpart; } else { float fpart; int index_x = (CMD0 & 0x1F) >> 1; int index_y = index_x >> 2; index_x &= 3; fpart = (float)fabs(cmb_mtrx[index_y][index_x] - (int)cmb_mtrx[index_y][index_x]); cmb_mtrx[index_y][index_x] = (short)(CMD1>>16); fpart = (float)fabs(cmb_mtrx[index_y][index_x+1] - (int)cmb_mtrx[index_y][index_x+1]); cmb_mtrx[index_y][index_x+1] = (short)(CMD1&0xFFFF); } } break; case G_MW_NUMLIGHT: //rdp_reg.lights = (_u32)((data & 0xff) / 16 - 1); rdp_reg.lights = (_u32)((data & 0xff) / 24); if ((rdp_reg.lights < 0)||(rdp_reg.lights > 15)) rdp_reg.lights = 0; rdp_reg.ambient_light = rdp_reg.lights; break; case G_MW_CLIP: switch((rdp_reg.cmd0 >> 8) & 0xffff) { case 0x0004: rdp_reg.clip.nx = rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tClip nx=%08i", CMD1); #endif break; case 0x000c: rdp_reg.clip.ny = rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tClip ny=%08i", CMD1); #endif break; case 0x0014: rdp_reg.clip.px = rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tClip px=%08i", CMD1); #endif break; case 0x001c: rdp_reg.clip.py = rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tClip py=%08i", CMD1); #endif break; default: break; } /* switch((rdp_reg.cmd0 >> 8) & 0xffff) */ break; case G_MW_SEGMENT: #ifdef LOG_ON LOG_TO_FILE("\tMOVEWORD SEGMENT: $%08lx -> seg#%d\n", CMD1, offset / 4); #endif rdp_reg.segment[offset >> 2] = CMD1 & 0xffffff; break; case G_MW_FOG: { float fo,fm,min,max,rng; fm = (float)(_s16)((CMD1 & 0xffff0000)>> 16); fo = (float)(_s16)((CMD1 & 0xffff)); rng = 128000.0f / fm; min = 500.0f - ((fo * rng) / 256.0f); max = rng + min; rdp_reg.fog_fo = fo; rdp_reg.fog_fm = fm; #ifdef LOG_ON LOG_TO_FILE("\tFog min = %f, max = %f",min,max); #endif } break; case G_MW_LIGHTCOL: i = (rdp_reg.cmd0 & 0x0000e000) >> 13; #ifdef LOG_ON LOG_TO_FILE("\tLight = %i, Color = %08X", i, CMD1); #endif if(rdp_reg.cmd0 & 0x00000400) { rdp_reg.light[i].r = ((float)((rdp_reg.cmd1 >> 24) & 0xff))/255.0f; rdp_reg.light[i].g = ((float)((rdp_reg.cmd1 >> 16) & 0xff))/255.0f; rdp_reg.light[i].b = ((float)((rdp_reg.cmd1 >> 8) & 0xff))/255.0f; rdp_reg.light[i].a = 1.0f; } else { rdp_reg.light[i].r_copy = ((float)((rdp_reg.cmd1 >> 24) & 0xff))/255.0f; rdp_reg.light[i].g_copy = ((float)((rdp_reg.cmd1 >> 16) & 0xff))/255.0f; rdp_reg.light[i].b_copy = ((float)((rdp_reg.cmd1 >> 8) & 0xff))/255.0f; rdp_reg.light[i].a_copy = 1.0f; } break; case G_MW_FORCEMTX: #ifdef LOG_ON LOG_TO_FILE("\tG_MW_FORCEMTX\n"); #endif break; case G_MW_PERSPNORM: rdp_reg.perspnorm = (float)(rdp_reg.cmd1 & 0xFFFF) / 65535.0f; #ifdef LOG_ON LOG_TO_FILE("\tG_MW_PERSPNORM = %3.5f\n",rdp_reg.perspnorm); #endif break; default: ; } /* switch(rdp_reg.cmd0 & 0xff) */ } void rsp_uc04_movemem() { _u32 param; // int i; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_MOVEMEM",ADDR, CMD0, CMD1); #endif param = (CMD0 & 0xff); switch(param) { case G_MV_MMTX: #ifdef LOG_ON LOG_TO_FILE("\tMV_MMTX\n"); #endif break; case G_MV_PMTX: #ifdef LOG_ON LOG_TO_FILE("\tMV_PMTX\n"); #endif break; case G_MV_VIEWPORT: { int a = segoffset2addr(rdp_reg.cmd1) & 0x007fffff; a >>= 1; rdp_reg.vp[0] = ((float)((_s16 *)pRDRAM)[(a+0)^1]) / 4.0f; rdp_reg.vp[1] = ((float)((_s16 *)pRDRAM)[(a+1)^1]) / 4.0f; rdp_reg.vp[2] = ((float)((_s16 *)pRDRAM)[(a+2)^1]) / 4.0f; rdp_reg.vp[3] = ((float)((_s16 *)pRDRAM)[(a+3)^1]) / 4.0f; rdp_reg.vp[4] = ((float)((_s16 *)pRDRAM)[(a+4)^1]) / 4.0f; rdp_reg.vp[5] = ((float)((_s16 *)pRDRAM)[(a+5)^1]) / 4.0f; rdp_reg.vp[6] = ((float)((_s16 *)pRDRAM)[(a+6)^1]) / 4.0f; rdp_reg.vp[7] = ((float)((_s16 *)pRDRAM)[(a+7)^1]) / 4.0f; Render_viewport(); #ifdef LOG_ON LOG_TO_FILE("\tViewPort"); LOG_TO_FILE("\t{%f,%f,%f,%f",rdp_reg.vp[0],rdp_reg.vp[1],rdp_reg.vp[2],rdp_reg.vp[3]); LOG_TO_FILE("\t %f,%f,%f,%f}\n",rdp_reg.vp[4],rdp_reg.vp[5],rdp_reg.vp[6],rdp_reg.vp[7]); #endif } break; case G_MV_LIGHT: { int a = segoffset2addr(rdp_reg.cmd1) & 0x007fffff; int i = ((CMD0 >> 5) & 0x3ff); if (i < G_MVO_L0) break; i = (i - G_MVO_L0) / 24; if (1 > 15) break; rdp_reg.light[i].r = ((float)((_u8 *)pRDRAM)[(a+ 0)^3])/255.0f; rdp_reg.light[i].g = ((float)((_u8 *)pRDRAM)[(a+ 1)^3])/255.0f; rdp_reg.light[i].b = ((float)((_u8 *)pRDRAM)[(a+ 2)^3])/255.0f; rdp_reg.light[i].a = 1.0f; rdp_reg.light[i].r_copy = ((float)((_u8 *)pRDRAM)[(a+ 4)^3])/255.0f; rdp_reg.light[i].g_copy = ((float)((_u8 *)pRDRAM)[(a+ 5)^3])/255.0f; rdp_reg.light[i].b_copy = ((float)((_u8 *)pRDRAM)[(a+ 6)^3])/255.0f; rdp_reg.light[i].a_copy = 1.0f; if (((((_u8 *)pRDRAM)[(a+ 0)]) == 0x08) && ((((_u8 *)pRDRAM)[(a+ 4)]) == 0xff) && USE_MM_HACK) { rdp_reg.light[i].x = (float)(int)doReadMemHalfWord(a + 8);//((float)((_s8 *)pRDRAM)[(a+ 8)^3])/127.0f;doReadMemHalfWord(); rdp_reg.light[i].y = (float)(int)doReadMemHalfWord(a + 10);//((float)((_s8 *)pRDRAM)[(a+ 9)^3])/127.0f; rdp_reg.light[i].z = (float)(int)doReadMemHalfWord(a + 12);//((float)((_s8 *)pRDRAM)[(a+10)^3])/127.0f; rdp_reg.light[i].w = (float)(int)doReadMemHalfWord(a + 14);//1.0f; } else { rdp_reg.light[i].x = ((float)((_s8 *)pRDRAM)[(a+ 8)^3])/127.0f; rdp_reg.light[i].y = ((float)((_s8 *)pRDRAM)[(a+ 9)^3])/127.0f; rdp_reg.light[i].z = ((float)((_s8 *)pRDRAM)[(a+10)^3])/127.0f; rdp_reg.light[i].w = 1.0f; } refresh_lights = TRUE; #ifdef LOG_ON LOG_TO_FILE("\tLight[%i]",i); LOG_TO_FILE("\tRed = %f, Green = %f, Blue = %f, Alpha = %f", rdp_reg.light[i].r, rdp_reg.light[i].g, rdp_reg.light[i].b, rdp_reg.light[i].a); LOG_TO_FILE("\tx = %f, y = %f, z = %f\n", rdp_reg.light[i].x, rdp_reg.light[i].y, rdp_reg.light[i].z); #endif } break; case G_MV_POINT: #ifdef LOG_ON LOG_TO_FILE("\tG_MV_POINT\n"); #endif break; case G_MV_MATRIX: #ifdef LOG_ON LOG_TO_FILE("\tMV_MATRIX\n"); #endif { _u32 a = segoffset2addr(CMD1); refresh_matrix = FALSE; hleGetMatrix((float*)&cmb_mtrx[0,0], &pRDRAM[a]); } break; case G_MVO_LOOKATX: break; case G_MVO_LOOKATY: break; case G_MVO_L0: case G_MVO_L1: case G_MVO_L2: case G_MVO_L3: case G_MVO_L4: case G_MVO_L5: case G_MVO_L6: case G_MVO_L7: break; default: //DebugBox("unknow MoveMem %04x", param); break; } /* switch((rdp_reg.cmd0 >> 8) & 0xffff) */ } void rsp_uc04_displaylist() { _u32 addr = segoffset2addr(CMD1); _u8 push = (_u8)(CMD0 >> 16) & 0xff; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_DISPLAYLIST",ADDR, CMD0, CMD1); LOG_TO_FILE("\tAddress = %08x %s\n",addr, (push)?", Branch":", Push"); #endif switch(push) { case 0: // push: we do a call of the dl rdp_reg.pc_i++; if(rdp_reg.pc_i > RDP_STACK_SIZE-1) { DebugBox("DList Stack overflow"); return; } rdp_reg.pc[rdp_reg.pc_i] = addr; break; case 1: // branch rdp_reg.pc[rdp_reg.pc_i] = addr; break; default: DebugBox("Unknow DList command"); break; } // switch(push) } void rsp_uc04_enddl() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_END_DISPLAYLIST\n",ADDR, CMD0, CMD1); #endif if(rdp_reg.pc_i < 0) { DebugBox("EndDL - Display Stack underrun"); rdp_reg.halt = 1; return; } if(rdp_reg.pc_i == 0) { rdp_reg.halt = 1; } rdp_reg.pc_i--; } void rsp_uc04_enddisplaylist() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_END_DISPLAYLIST?\n",ADDR, CMD0, CMD1); #endif rdp_reg.halt = 1; return; } void rsp_uc04_rdphalf_1() { #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_END_RDP_HALF_1\n",ADDR, CMD0, CMD1); #endif bzaddr = segoffset2addr(rdp_reg.cmd1); } void rsp_uc04_setothermode_l() { static char *ac[] = { "none", "threshold", "?", "diter" }; static char *zs[] = { "pixel", "prim" }; static char *a1[] = { " bl_1ma (1)", " bl_a_mem (1)", " bl_1 (1)", " bl_0 (1)" }; static char *b1[] = { " bl_clr_in (1)", " bl_clr_mem (1)", " bl_clr_bl (1)", " bl_clr_fog (1)" }; static char *c1[] = { " bl_a_in (1)", " bl_a_fog (1)", " bl_a_shade (1)", " bl_0 (1)" }; static char *d1[] = { " bl_1ma (1)", " bl_a_mem (1)", " bl_1 (1)", " bl_0 (1)" }; static char *a2[] = { " bl_1ma (2)", " bl_a_mem (2)", " bl_1 (2)", " bl_0 (2)" }; static char *b2[] = { " bl_clr_in (2)", " bl_clr_mem (2)", " bl_clr_bl (2)", " bl_clr_fog (2)" }; static char *c2[] = { " bl_a_in (2)", " bl_a_fog (2)", " bl_a_shade (2)", " bl_0 (2)" }; static char *d2[] = { " bl_1ma (2)", " bl_a_mem (2)", " bl_1 (2)", " bl_0 (2)" }; int len = ((rdp_reg.cmd0) & 0xff) + 1; int sft = 32 - ((rdp_reg.cmd0 >> 8) & 0xff) - len; #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SETOTHERMODE_L ", ADDR, CMD0, CMD1); #endif switch (sft) //((rdp_reg.cmd0 >> 8) & 0xff) { case 0x00: #ifdef LOG_ON LOG_TO_FILE("\tALPHACOMPARE: %s\n", ac[(rdp_reg.cmd1>>0x00) & 0x3]); #endif rdp_reg.mode_l &= ~0x00000003; rdp_reg.cmd1 &= 0x00000003; rdp_reg.mode_l |= rdp_reg.cmd1; break; case 0x02: #ifdef LOG_ON LOG_TO_FILE("\tZSRCSEL: %s\n", zs[(rdp_reg.cmd1>>0x02) & 0x1]); #endif rdp_reg.mode_l &= ~0x00000004; rdp_reg.cmd1 &= 0x00000004; rdp_reg.mode_l |= rdp_reg.cmd1; break; case 0x03: #ifdef LOG_ON LOG_TO_FILE("\tRENDERMODE: "); LOG_TO_FILE("" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n", (rdp_reg.cmd1 & 0x00000008) ? "\tanti alias on\n" : "\tanti alias off\n", (rdp_reg.cmd1 & 0x00000010) ? "\tz_cmp on\n" : "\tz_cmp off\n", (rdp_reg.cmd1 & 0x00000020) ? "\tz_upd on\n" : "\tz_upd off\n", (rdp_reg.cmd1 & 0x00000040) ? "\tim_rd on\n" : "\tim_rd off\n", (rdp_reg.cmd1 & 0x00000080) ? "\tclr_on_cvg on\n" : "\tclr_on_cvg off\n", (rdp_reg.cmd1 & 0x00000100) ? "\tcvg_dst_warp on\n" : "\tcvg_dst_warp off\n", (rdp_reg.cmd1 & 0x00000200) ? "\tcvg_dst_full on\n" : "\tcvg_dst_full off\n", (rdp_reg.cmd1 & 0x00000400) ? "\tz_inter on\n" : "\tz_inter off\n", (rdp_reg.cmd1 & 0x00000800) ? "\tz_xlu on\n" : "\tz_xlu off\n", (rdp_reg.cmd1 & 0x00001000) ? "\tcvg_x_alpha on\n" : "\tcvg_x_alpha off\n", (rdp_reg.cmd1 & 0x00002000) ? "\talpha_cvg_sel on\n" : "\talpha_cvg_sel off\n", (rdp_reg.cmd1 & 0x00004000) ? "\tforce_bl on\n" : "\tforce_bl off\n", (rdp_reg.cmd1 & 0x00008000) ? "\ttex_edge? on\n" : "\ttex_edge? off\n", a2[(rdp_reg.cmd1>>16) & 0x3], a1[(rdp_reg.cmd1>>18) & 0x3], b2[(rdp_reg.cmd1>>20) & 0x3], b1[(rdp_reg.cmd1>>22) & 0x3], c2[(rdp_reg.cmd1>>24) & 0x3], c1[(rdp_reg.cmd1>>26) & 0x3], d2[(rdp_reg.cmd1>>28) & 0x3], d1[(rdp_reg.cmd1>>30) & 0x3] ); #endif rdp_reg.mode_l &= ~0xfffffff8; rdp_reg.cmd1 &= 0xfffffff8; rdp_reg.mode_l |= rdp_reg.cmd1; break; case 0x10: rdp_reg.mode_l &= ~0xffff0000; rdp_reg.cmd1 &= 0xffff0000; rdp_reg.mode_l |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tBLENDER: "); LOG_TO_FILE("" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n" "%s\n", a2[(rdp_reg.cmd1>>16) & 0x3], a1[(rdp_reg.cmd1>>18) & 0x3], b2[(rdp_reg.cmd1>>20) & 0x3], b1[(rdp_reg.cmd1>>22) & 0x3], c2[(rdp_reg.cmd1>>24) & 0x3], c1[(rdp_reg.cmd1>>26) & 0x3], d2[(rdp_reg.cmd1>>28) & 0x3], d1[(rdp_reg.cmd1>>30) & 0x3] ); #endif break; default: //PRINT_RDP("SETOTHERMODE_L ?\n"); ; } /* switch((rdp_reg.cmd0 >> 8) & 0xff) */ if(rdp_reg.mode_l & 0x00000010) Render_geometry_zbuffer(1); else Render_geometry_zbuffer(0); if ((rdp_reg.mode_l & 0x0c00) != 0xc00) glDepthRange(-1,1.); else glDepthRange(-1,0.9995); if (rdp_reg.mode_l & 0x00000020) Render_geometry_zwrite(1); else Render_geometry_zwrite(0); /* switch (rdp_reg.mode_l & 0x00000003) { case 0: Src_Alpha = GL_ONE; Dst_Alpha = GL_ZERO; break; case 1: case 2: case 3: Src_Alpha = GL_SRC_ALPHA; Dst_Alpha = GL_ONE_MINUS_SRC_ALPHA; break; } */ /* // if ((rdp_reg.mode_l & 0x0f0f0000) != 0x50000) if ((rdp_reg.mode_l & 0x0f000000) != 0x0) { Src_Alpha = GL_SRC_ALPHA; Dst_Alpha = GL_ONE_MINUS_SRC_ALPHA; } else { // Src_Alpha = GL_ONE; // Dst_Alpha = GL_ZERO; } */ } void rsp_uc04_setothermode_h() { static char *ad[] = { "pattern", "notpattern", "noise", "disable" }; static char *rd[] = { "magicsq", "bayer", "noise", "?" }; static char *ck[] = { "none", "key" }; static char *tc[] = { "conv", "?", "?", "?", "?", "filtconv", "filt", "?" }; static char *tf[] = { "point", "?", "bilerp", "average" }; static char *tt[] = { "none", "?", "rgba16", "ia16" }; static char *tl[] = { "tile", "lod" }; static char *td[] = { "clamp", "sharpen", "detail", "?" }; static char *tp[] = { "none", "persp" }; static char *ct[] = { "1cycle", "2cycle", "copy", "fill" }; static char *cd[] = { "disable(hw>1)", "enable(hw>1)", "disable(hw1)", "enable(hw1)" }; static char *pm[] = { "nprimitive", "1primitive" }; int len = (rdp_reg.cmd0 & 0xff) +1; int sft = 32 - ((rdp_reg.cmd0 >> 8) & 0xff) - len; // switch((rdp_reg.cmd0 >> 8) & 0xff) #ifdef LOG_ON LOG_TO_FILE("%08X: %08X %08X CMD UC4_SETOTHERMODE_H\n",ADDR, CMD0, CMD1); #endif switch(sft) { case 0x00: #ifdef LOG_ON LOG_TO_FILE("\tBLENDMASK - ignored\n"); #endif break; case 0x04: rdp_reg.mode_h &= ~0x00000030; rdp_reg.cmd1 &= 0x00000030; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tALPHADITHER: %s\n", ad[(rdp_reg.cmd1>>0x04) & 0x3]); #endif break; case 0x06: rdp_reg.mode_h &= ~0x000000c0; rdp_reg.cmd1 &= 0x000000c0; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tRGBDITHER: %s\n", rd[(rdp_reg.cmd1>>0x06) & 0x3]); #endif break; case 0x08: rdp_reg.mode_h &= ~0x00000100; rdp_reg.cmd1 &= 0x00000100; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tCOMBINEKEY: %s\n", ck[(rdp_reg.cmd1>>0x08) & 0x1]); #endif break; case 0x09: #ifdef LOG_ON LOG_TO_FILE("\tTEXTURECONVERT: %s\n", tc[(rdp_reg.cmd1>>0x09) & 0x7]); #endif rdp_reg.mode_h &= ~0x00000e00; rdp_reg.cmd1 &= 0x00000e00; rdp_reg.mode_h |= rdp_reg.cmd1; break; case 0x0c: rdp_reg.mode_h &= ~0x00003000; rdp_reg.cmd1 &= 0x00003000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tTEXTUREFILTER: %s\n", tf[(rdp_reg.cmd1>>0x0c) & 0x3]); #endif break; case 0x0e: rdp_reg.mode_h &= ~0x0000c000; rdp_reg.cmd1 &= 0x0000c000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tTEXTURELUT: %s\n", tt[(rdp_reg.cmd1>>0x0e) & 0x3]); #endif break; case 0x10: rdp_reg.mode_h &= ~0x00010000; rdp_reg.cmd1 &= 0x00010000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tTEXTURELOD: %s\n", tl[(rdp_reg.cmd1>>0x10) & 0x1]); #endif break; case 0x11: rdp_reg.mode_h &= ~0x00060000; rdp_reg.cmd1 &= 0x00060000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tTEXTUREDETAIL: %s\n", td[(rdp_reg.cmd1>>0x11) & 0x3]); #endif break; case 0x13: rdp_reg.mode_h &= ~0x00080000; rdp_reg.cmd1 &= 0x00080000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tTEXTUREPERSP: %s\n", tp[(rdp_reg.cmd1>>0x13) & 0x1]); #endif break; case 0x14: cycle_mode = (_u8)((rdp_reg.cmd1>>0x14) & 0x3); rdp_reg.mode_h &= ~0x00300000; rdp_reg.cmd1 &= 0x00300000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tCYCLETYPE: %s\n", ct[(rdp_reg.cmd1>>0x14) & 0x3]); #endif break; case 0x16: rdp_reg.mode_h &= ~0x00400000; rdp_reg.cmd1 &= 0x00400000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tCOLORDITHER: %s\n", cd[(rdp_reg.cmd1>>0x16) & 0x1]); #endif break; case 0x17: rdp_reg.mode_h &= ~0x00800000; rdp_reg.cmd1 &= 0x00800000; rdp_reg.mode_h |= rdp_reg.cmd1; #ifdef LOG_ON LOG_TO_FILE("\tPIPELINEMODE: %s\n", pm[(rdp_reg.cmd1>>0x17) & 0x1]); #endif break; default: #ifdef LOG_ON LOG_TO_FILE("\tUNDEFINED\n"); #endif break; } /* switch((rdp_reg.cmd0 >> 8) & 0xff) */ }