diff --git a/plugins/GSdx/GSHwHack.cpp b/plugins/GSdx/GSHwHack.cpp index e69f408261..5b68146092 100644 --- a/plugins/GSdx/GSHwHack.cpp +++ b/plugins/GSdx/GSHwHack.cpp @@ -43,62 +43,12 @@ struct GSFrameInfo typedef bool (*GetSkipCount)(const GSFrameInfo& fi, int& skip); CRC::Region g_crc_region = CRC::NoRegion; -bool GSC_Okami(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32) - { - skip = 1000; - } - } - else - { - if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSM_PSMT4) - { - skip = 0; - } - } - - return true; -} - -bool GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip) -{ - // Game requires sub RT support (texture cache limitation) - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT24) - { - skip = 1000; // 76, 79 - } - else if(fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSM_PSMCT24 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT32) - { - skip = 1000; // 69 - } - } - else - { - if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSM_PSMCT32) - { - skip = 0; - } - else if(!fi.TME && fi.FBP == fi.TBP0 && fi.TBP0 == 0x2000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMCT24) - { - if(g_crc_region == CRC::US || g_crc_region == CRC::JP || g_crc_region == CRC::KO) - { - skip = 119; //ntsc - } - else - { - skip = 136; //pal - } - } - } - - return true; -} +//////////////////////////////////////////////////////////////////////////////// +// Broken on both DirectX and OpenGL +// (note: could potentially work with latest OpenGL) +//////////////////////////////////////////////////////////////////////////////// +// Potentially partially dx only bool GSC_DBZBT2(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -117,6 +67,7 @@ bool GSC_DBZBT2(const GSFrameInfo& fi, int& skip) return true; } +// Potentially partially dx only bool GSC_DBZBT3(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -161,119 +112,7 @@ bool GSC_DBZBT3(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_SFEX3(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSM_PSMCT16) - { - skip = 2; // blur - } - } - - return true; -} - -bool GSC_Bully(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.FPSM == fi.TPSM) - { - return false; // allowed - } - - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x02300 && fi.TPSM == PSM_PSMZ16S) - { - skip = 6; - } - } - else - { - if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSM_PSMCT32) - { - skip = 0; - } - } - - return true; -} - -bool GSC_BullyCC(const GSFrameInfo& fi, int& skip) -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.FPSM == fi.TPSM) - { - return false; // allowed - } - - if(!fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSM_PSMCT24) - { - skip = 9; - } - } - - return true; -} - -bool GSC_SoTC(const GSFrameInfo& fi, int& skip) -{ - // Not needed anymore? What did it fix anyway? (rama) - if(skip == 0) - { - if(Aggresive && fi.TME /*&& fi.FBP == 0x03d80*/ && fi.FPSM == 0 && fi.TBP0 == 0x03fc0 && fi.TPSM == 1) - { - skip = 48; //removes sky bloom - } - /* - if(fi.TME && fi.FBP == 0x02b80 && fi.FPSM == PSM_PSMCT24 && fi.TBP0 == 0x01e80 && fi.TPSM == PSM_PSMCT24) - { - skip = 9; - } - else if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSM_PSMCT32) - { - skip = 8; - } - else if(fi.TME && fi.FBP == 0x01e80 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03880 && fi.TPSM == PSM_PSMCT32) - { - skip = 8; - }*/ - } - - - - - - return true; -} - -bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16) - { - skip = 4; - } - } - - return true; -} - -bool GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16) - { - skip = 4; - } - } - - return true; -} - +// Potentially partially dx only bool GSC_ICO(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -349,7 +188,7 @@ bool GSC_GTConcept(const GSFrameInfo& fi, int& skip) skip = 880; } } - + return true; } @@ -465,27 +304,6 @@ bool GSC_SacredBlaze(const GSFrameInfo& fi, int& skip) return true; } -template -bool GSC_SMTNocturneDDS(const GSFrameInfo& fi, int& skip) -{ - // stop the motion blur on the main character and - // smudge filter from being drawn on USA versions of - // Nocturne, Digital Devil Saga 1 and Digital Devil Saga 2 - - if(Aggresive && g_crc_region == CRC::US && skip == 0 && fi.TBP0 == 0xE00 && fi.TME) - { - // Note: it will crash if the core doesn't allocate the EE mem in 0x2000_0000 (unlikely but possible) - // Aggresive hacks are evil anyway - - // Nocturne: - // -0x5900($gp), ref at 0x100740 - const int state = *(int*)(state_addr); - if (state == 23 || state == 24 || state == 25) - skip = 1; - } - return true; -} - bool GSC_Spartan(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -554,7 +372,7 @@ bool GSC_Tekken5(const GSFrameInfo& fi, int& skip) } } } - + return true; } @@ -582,100 +400,6 @@ bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_GodOfWar(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 1000; - } - else if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32 && fi.FBMSK == 0xff000000) - { - skip = 1; // blur - } - else if(fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8 && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))) - { - skip = 1; // wall of fog - } - else if (fi.TME && (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S)) - { - // Equivalent to the UserHacks_AutoSkipDrawDepth hack but enabled by default - // http://forums.pcsx2.net/Thread-God-of-War-Red-line-rendering-explained - skip = 1; - } - } - else - { - if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16) - { - skip = 3; - } - } - - return true; -} - -bool GSC_GodOfWar2(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME) - { - if( fi.FBP == 0x00100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSM_PSMCT16 // ntsc - || fi.FBP == 0x02100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT16) // pal - { - skip = 1000; // shadows - } - if((fi.FBP == 0x00100 || fi.FBP == 0x02100) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 & 0x03000) == 0x03000 - && (fi.TPSM == PSM_PSMT8 || fi.TPSM == PSM_PSMT4) - && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))) - { - skip = 1; // wall of fog - } - else if(Aggresive && fi.TPSM == PSM_PSMCT24 && fi.TME && (fi.FBP ==0x1300 ) && (fi.TBP0 ==0x0F00 || fi.TBP0 ==0x1300 || fi.TBP0==0x2b00)) // || fi.FBP == 0x0100 - { - skip = 1; // global haze/halo - } - else if(Aggresive && fi.TPSM == PSM_PSMCT24 && fi.TME && (fi.FBP ==0x0100 ) && (fi.TBP0==0x2b00 || fi.TBP0==0x2e80)) //480P 2e80 - { - skip = 1; // water effect and water vertical lines - } - else if (fi.TME && (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S)) - { - // Equivalent to the UserHacks_AutoSkipDrawDepth hack but enabled by default - // http://forums.pcsx2.net/Thread-God-of-War-Red-line-rendering-explained - skip = 1; - } - } - } - else - { - if(fi.TME && (fi.FBP == 0x00100 || fi.FBP == 0x02100) && fi.FPSM == PSM_PSMCT16) - { - skip = 3; - } - } - - return true; -} - -bool GSC_GiTS(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02e40 && fi.TPSM == PSM_PSMCT16) - { - skip = 1315; - } - } - else - { - } - - return true; -} - bool GSC_Onimusha3(const GSFrameInfo& fi, int& skip) { if(fi.TME /*&& (fi.FBP == 0x00000 || fi.FBP == 0x00700)*/ && (fi.TBP0 == 0x01180 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x01000 || fi.TBP0 == 0x01200) && (fi.TPSM == PSM_PSMCT32 || fi.TPSM == PSM_PSMCT24)) @@ -710,46 +434,6 @@ bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16) - { - skip = 1000; // shadow - } - } - else - { - if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TPSM == PSM_PSMCT16S) - { - skip = 2; - } - } - - return true; -} - -bool GSC_SimpsonsGame(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && fi.TBP0 == 0x03000 && fi.TPSM == PSM_PSMCT32) - { - skip = 100; - } - } - else - { - if(fi.TME && fi.FBP == 0x03000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8H) - { - skip = 2; - } - } - - return true; -} - bool GSC_Genji(const GSFrameInfo& fi, int& skip) { if( !skip && fi.TME && (fi.FBP == 0x700 || fi.FBP == 0x0) && fi.TBP0 == 0x1500 && fi.TPSM ) @@ -764,7 +448,7 @@ bool GSC_Genji(const GSFrameInfo& fi, int& skip) skip = 6; else return false; - } + } else if(fi.TPSM == PSM_PSMCT24 && fi.TME ==0x0001 && fi.TBP0==fi.FBP) { skip = 1; @@ -781,94 +465,6 @@ bool GSC_Genji(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_StarOcean3(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - // The game emulate a stencil buffer with the alpha channel of the RT - // The operation of the stencil is selected with the palette - // For example -1 wrap will be [240, 16, 32, 48 ....] - // i.e. p[A>>4] = (A - 16) % 256 - // - // The fastest and accurate solution will be to replace this pseudo stencil - // by a dedicated GPU draw call - // 1/ Use future GPU capabilities to do a "kind" of SW blending - // 2/ Use a real stencil/atomic image, and then compute the RT alpha value - // - // Both of those solutions will increase code complexity (and only avoid upscaling - // glitches) - - if(skip == 0) - { - if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) - { - skip = 1000; // - } - } - else - { - if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) - { - skip = 0; - } - } - - return true; -} - -bool GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - /*if(fi.TME && (fi.FBP == 0x018c0 || fi.FBP == 0x02180) && fi.FPSM == fi.TPSM && fi.TBP0 >= 0x03200 && fi.TPSM == PSM_PSMCT32) //NTSC only, !(fi.TBP0 == 0x03580 || fi.TBP0 == 0x03960) - { - skip = 1; //red garbage in lost forest, removes other effects... - } - if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 1; // //garbage in cutscenes, doesn't remove completely, better use "Alpha Hack" - }*/ - if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) - { - // GH: Hack is quite similar to GSC_StarOcean3. It is potentially the same issue. - skip = 1000; // - } - } - else - { - if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) - { - skip = 0; - } - } - - return true; -} - -bool GSC_RadiataStories(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 1; - } - else if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) - { - // GH: Hack is quite similar to GSC_StarOcean3. It is potentially the same issue. - // Fixed on openGL - skip = 1000; - } - } - else - { - if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) - { - skip = 0; - } - } - - return true; -} - bool GSC_HauntingGround(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -920,20 +516,6 @@ bool GSC_EvangelionJo(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_SuikodenTactics(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if( !fi.TME && fi.TPSM == PSM_PSMT8H && fi.FPSM == 0 && - fi.FBMSK == 0x0FF000000 && fi.TBP0 == 0 && GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) - { - skip = 4; - } - } - - return true; -} - bool GSC_CaptainTsubasa(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -979,7 +561,7 @@ bool GSC_NarutimateAccel(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -1003,7 +585,7 @@ bool GSC_Naruto(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -1020,18 +602,6 @@ bool GSC_EternalPoison(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_LegoBatman(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(Aggresive && skip == 0) - { - if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x00000) - { - skip = 3; - } - } - return true; -} - bool GSC_SakuraTaisen(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -1064,59 +634,6 @@ bool GSC_SakuraTaisen(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_Tenchu(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 3; - } - } - - return true; -} - -bool GSC_Sly3(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00700 || fi.FBP == 0x00a80 || fi.FBP == 0x00e00) && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00700 || fi.TBP0 == 0x00a80 || fi.TBP0 == 0x00e00) && fi.TPSM == PSM_PSMCT16) - { - skip = 1000; - } - } - else - { - if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 3; - } - } - - return true; -} - -bool GSC_Sly2(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00700 || fi.FBP == 0x00800) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 1000; - } - } - else - { - if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 3; - } - } - - return true; -} - bool GSC_ShadowofRome(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -1128,7 +645,7 @@ bool GSC_ShadowofRome(const GSFrameInfo& fi, int& skip) else if(fi.TME ==0x0001 && (fi.TBP0==0x1300 || fi.TBP0==0x0f00) && fi.FBMSK>=0xFFFFFF) { skip = 1; - } + } else if(fi.TME && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 ==0x0160 ||fi.TBP0==0x01e0 || fi.TBP0<=0x0800) && fi.TPSM == PSM_PSMT8) { skip = 1; @@ -1136,96 +653,9 @@ bool GSC_ShadowofRome(const GSFrameInfo& fi, int& skip) else if(fi.TME && (fi.TBP0==0x0700) && (fi.TPSM == PSM_PSMCT32 || fi.TPSM == PSM_PSMCT24)) { skip = 1; - } + } } - - return true; -} -bool GSC_FFXII(const GSFrameInfo& fi, int& skip) -{ - if(Aggresive && skip == 0) - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } - return true; -} - -bool GSC_FFX2(const GSFrameInfo& fi, int& skip) -{ - if(Aggresive && skip == 0) - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } - return true; -} - -bool GSC_FFX(const GSFrameInfo& fi, int& skip) -{ - if(Aggresive && skip == 0) - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } - return true; -} - -bool GSC_DemonStone(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT16) - { - skip = 1000; - } - } - else - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSM_PSMCT32) - { - skip = 2; - } - } - - return true; -} - -bool GSC_BigMuthaTruckers(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16) - { - skip = 3; - } - } - return true; } @@ -1238,31 +668,7 @@ bool GSC_TimeSplitters2(const GSFrameInfo& fi, int& skip) skip = 1; } } - - return true; -} -bool GSC_LordOfTheRingsTwoTowers(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP == 0x01180 || fi.FBP == 0x01400) && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT16) - { - skip = 1000;//shadows - } - else if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.TBP0 == 0x01400 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) - { - skip = 3; //wall of fog - } - } - else - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && (fi.TBP0 == 0x01180 || fi.TBP0 == 0x01400) && fi.FPSM == PSM_PSMCT32) - { - skip = 2; - } - } - return true; } @@ -1282,7 +688,7 @@ bool GSC_LordOfTheRingsThirdAge(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -1343,75 +749,6 @@ bool GSC_BleachBladeBattlers(const GSFrameInfo& fi, int& skip) skip = 1; } } - - return true; -} - -bool GSC_Castlevania(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - // This hack removes the shadows and globally darker image - // I think there are 2 issues on GSdx - // - // 1/ potential not correctly supported colclip. - // - // 2/ use of a 32 bits format to emulate a 16 bit formats - // For example, if you blend 64 time the value 4 on a dark destination pixels - // - // FMT32: 4*64 = 256 <= white pixels - // - // FMT16: output of blending will always be 0 because the 3 lsb of color is dropped. - // Therefore the pixel remains dark !!! - if(fi.TME && fi.FBP == 0 && fi.TBP0 && fi.TPSM == 10 && fi.FBMSK == 0xFFFFFF) - { - skip = 2; - } - } - - return true; -} - -bool GSC_Black(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - // Note: the first part of the hack must be fixed in openGL (texture shuffle). Remains the 2nd part (HasSharedBits) - if(fi.TME /*&& (fi.FBP == 0x00000 || fi.FBP == 0x008c0)*/ && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x01a40 || fi.TBP0 == 0x01b80 || fi.TBP0 == 0x030c0) && fi.TPSM == PSM_PSMZ16 || (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))) - { - skip = 5; - } - } - else - { - if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x008c0 || fi.FBP == 0x0a00 ) && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4) - { - skip = 0; - } - else if(!fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8H) - { - skip = 0; - } - } - - return true; -} - -bool GSC_CrashNburn(const GSFrameInfo& fi, int& skip) -{ - if(skip == 0) - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } return true; } @@ -1422,7 +759,7 @@ bool GSC_TombRaider(const GSFrameInfo& fi, int& skip) { if(fi.TME && fi.FBP == 0x01000 && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT32) { - skip = 1; + skip = 1; } } return true; @@ -1436,12 +773,12 @@ bool GSC_TombRaiderLegend(const GSFrameInfo& fi, int& skip) { skip = 1; } - else if(fi.TPSM == PSM_PSMCT32 && (fi.TPSM | fi.FBP)==0x2fa0 && (fi.TBP0==0x2bc0 ) && fi.FBMSK ==0) + else if(fi.TPSM == PSM_PSMCT32 && (fi.TPSM | fi.FBP)==0x2fa0 && (fi.TBP0==0x2bc0 ) && fi.FBMSK ==0) { skip = 2; } - - + + }// ||fi.TBP0 ==0x2F00 return true; @@ -1455,11 +792,11 @@ bool GSC_TombRaiderUnderWorld(const GSFrameInfo& fi, int& skip) { skip = 1; } - else if(fi.TPSM == PSM_PSMCT32 && (fi.TPSM | fi.FBP)==0x2c00 && (fi.TBP0 ==0x0ee0) && fi.FBMSK ==0) + else if(fi.TPSM == PSM_PSMCT32 && (fi.TPSM | fi.FBP)==0x2c00 && (fi.TBP0 ==0x0ee0) && fi.FBMSK ==0) { skip = 2; } - /*else if(fi.TPSM == PSM_PSMCT16 && (fi.TPSM | fi.FBP)>=0x0 && (fi.TBP0 >=0x0) && fi.FBMSK ==0) + /*else if(fi.TPSM == PSM_PSMCT16 && (fi.TPSM | fi.FBP)>=0x0 && (fi.TBP0 >=0x0) && fi.FBMSK ==0) { skip = 600; }*/ @@ -1468,25 +805,6 @@ bool GSC_TombRaiderUnderWorld(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_SSX3(const GSFrameInfo& fi, int& skip) -{ - if(Aggresive && skip == 0) - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } - - return true; -} - bool GSC_FFVIIDoC(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -1500,7 +818,7 @@ bool GSC_FFVIIDoC(const GSFrameInfo& fi, int& skip) //skip = 1; } } - + return true; } @@ -1522,7 +840,7 @@ bool GSC_DevilMayCry3(const GSFrameInfo& fi, int& skip) skip = 24; } } - + return true; } @@ -1539,11 +857,11 @@ bool GSC_StarWarsForceUnleashed(const GSFrameInfo& fi, int& skip) { if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x034a0 || fi.TBP0 == 0x36e0) && fi.TPSM == PSM_PSMCT16) { - skip = 2; + skip = 2; } } - + return true; } @@ -1556,7 +874,7 @@ bool GSC_StarWarsBattlefront(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -1573,7 +891,7 @@ bool GSC_StarWarsBattlefront2(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -1590,7 +908,7 @@ bool GSC_BlackHawkDown(const GSFrameInfo& fi, int& skip) skip = 5; //night filter } } - + return true; } @@ -1606,7 +924,7 @@ bool GSC_Burnout(const GSFrameInfo& fi, int& skip) { if (!Dx_only) return false; - if(fi.FBP == 0x00a00 && fi.TBP0 == 0x01e00) + if(fi.FBP == 0x00a00 && fi.TBP0 == 0x01e00) { skip = 4; //pal } @@ -1620,7 +938,7 @@ bool GSC_Burnout(const GSFrameInfo& fi, int& skip) skip = 2; //impact screen } } - + return true; } @@ -1633,33 +951,7 @@ bool GSC_MidnightClub3(const GSFrameInfo& fi, int& skip) skip = 1; } } - - return true; -} -bool GSC_SpyroNewBeginning(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && fi.TBP0 == 0x034a0 && fi.TPSM == PSM_PSMCT16) - { - skip = 2; - } - } - - return true; -} - -bool GSC_SpyroEternalNight(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x034a0 ||fi.TBP0 == 0x035a0 || fi.TBP0 == 0x036e0) && fi.TPSM == PSM_PSMCT16) - { - skip = 2; - } - } - return true; } @@ -1678,17 +970,17 @@ bool GSC_TalesOfLegendia(const GSFrameInfo& fi, int& skip) if(fi.TME && fi.FBP && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x3d80) { skip = 1; - } + } if(fi.TME && fi.FBP ==0x1c00 && (fi.TBP0==0x2e80 ||fi.TBP0==0x2d80) && fi.TPSM ==0 && fi.FBMSK == 0xff000000) { skip = 1; - } + } if(!fi.TME && fi.FBP ==0x2a00 && (fi.TBP0==0x1C00 ) && fi.TPSM ==0 && fi.FBMSK == 0x00FFFFFF) { skip = 1; } } - + return true; } @@ -1701,7 +993,7 @@ bool GSC_NanoBreaker(const GSFrameInfo& fi, int& skip) skip = 2; } } - + return true; } @@ -1735,7 +1027,7 @@ bool GSC_Kunoichi(const GSFrameInfo& fi, int& skip) skip = 0; } } - + return true; } @@ -1797,7 +1089,7 @@ bool GSC_SkyGunner(const GSFrameInfo& fi, int& skip) skip = 1; //Huge Vram usage } } - + return true; } @@ -1811,7 +1103,7 @@ bool GSC_JamesBondEverythingOrNothing(const GSFrameInfo& fi, int& skip) skip = 1; //Huge Vram usage } } - + return true; } @@ -1833,9 +1125,9 @@ bool GSC_ZettaiZetsumeiToshi2(const GSFrameInfo& fi, int& skip) // call.... skip = 1000; } - + } - else + else { if(!fi.TME && fi.TPSM == PSM_PSMCT32 && fi.FBP==0x1180 && fi.TBP0==0x1180 && (fi.FBMSK ==0)) { @@ -1861,9 +1153,9 @@ bool GSC_ZettaiZetsumeiToshi2(const GSFrameInfo& fi, int& skip) { skip = 2; // } - + } - + return true; } @@ -1871,14 +1163,14 @@ bool GSC_ShinOnimusha(const GSFrameInfo& fi, int& skip) { if(skip == 0) { - + if(fi.TME && fi.FBP == 0x001000 && (fi.TBP0 ==0 || fi.TBP0 == 0x0800) && fi.TPSM == PSM_PSMT8H && fi.FBMSK == 0x00FFFFFF) { skip = 0; - } + } else if(fi.TPSM == PSM_PSMCT24 && fi.TME && fi.FBP == 0x01000) // || fi.FBP == 0x00000 { - skip = 28; //28 30 56 64 + skip = 28; //28 30 56 64 } else if(fi.FBP && fi.TPSM == PSM_PSMT8H && fi.FBMSK == 0xFFFFFF) { @@ -1892,46 +1184,9 @@ bool GSC_ShinOnimusha(const GSFrameInfo& fi, int& skip) { skip = 1; } - - } - - return true; -} -bool GSC_XE3(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TPSM == PSM_PSMT8H && fi.FBMSK >= 0xEFFFFFFF) - { - skip = 73; - } - else if(fi.TME && fi.FBP ==0x03800 && fi.TBP0 && fi.TPSM ==0 && fi.FBMSK == 0) - { - skip = 1; - } - /*else if(fi.TPSM ==0x00000 && PSM_PSMCT24 && fi.TME && fi.FBP == 0x03800) - { - skip = 1 ; - }*/ - /*else if(fi.TME ==0 && (fi.FBP ==0 ) && fi.FPSM == PSM_PSMCT32 && ( fi.TPSM == PSM_PSMT8 || fi.TPSM == PSM_PSMT4) && (fi.FBMSK == 0x00FFFFFF || fi.FBMSK == 0xFF000000)) - { - skip = 1; - }*/ - else - { - if(fi.TME) - { - // depth textures (bully, mgs3s1 intro, Front Mission 5) - if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || - // General, often problematic post processing - (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) - { - skip = 1; - } - } - } } + return true; } @@ -1959,7 +1214,7 @@ bool GSC_SakuraWarsSoLongMyLove(const GSFrameInfo& fi, int& skip) else if(fi.TME==0 && fi.FBP == fi.TBP0 && (fi.TBP0 ==0x1200 ||fi.TBP0 ==0x1180 ||fi.TBP0 ==0) && fi.FBMSK == 0x00FFFFFF) { skip = 3; - } + } else if(fi.TME && (fi.FBP ==0 || fi.FBP ==0x1180) && fi.FPSM == PSM_PSMCT32 && fi.TBP0 ==0x3F3F && fi.TPSM == PSM_PSMT8) { skip = 1; @@ -1986,9 +1241,9 @@ bool GSC_TouristTrophy(const GSFrameInfo& fi, int& skip) { if(skip == 0) { - if(fi.TME && fi.FBP >= 0x02f00 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.TPSM == PSM_PSMT8) + if(fi.TME && fi.FBP >= 0x02f00 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.TPSM == PSM_PSMT8) { - skip = 770; + skip = 770; } if(fi.TME && fi.FBP >= 0x02de0 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 ==0 || fi.TBP0==0x1a40 ||fi.TBP0 ==0x2300) && fi.TPSM == PSM_PSMT8) { @@ -2134,20 +1389,6 @@ bool GSC_SengokuBasara(const GSFrameInfo& fi, int& skip) return true; } -bool GSC_Grandia3(const GSFrameInfo& fi, int& skip) // DX ONLY -{ - if(skip == 0) - { - if(fi.TME && (fi.FBP ==0x0 || fi.FBP ==0x0e00) && (fi.TBP0 ==0x2a00 ||fi.TBP0==0x0e00 ||fi.TBP0==0) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT32) - { - skip = 1; - } - } - - - return true; -} - bool GSC_FinalFightStreetwise(const GSFrameInfo& fi, int& skip) { if(skip == 0) @@ -2174,7 +1415,7 @@ bool GSC_TalesofSymphonia(const GSFrameInfo& fi, int& skip) skip = 1; } } - + return true; } @@ -2193,7 +1434,7 @@ bool GSC_SoulCalibur2(const GSFrameInfo& fi, int& skip) } } } - + return true; } @@ -2212,14 +1453,14 @@ bool GSC_SoulCalibur3(const GSFrameInfo& fi, int& skip) } } } - + return true; } bool GSC_Simple2000Vol114(const GSFrameInfo& fi, int& skip) { if(skip == 0) - { + { if(fi.TME==0 && (fi.FBP==0x1500) && (fi.TBP0==0x2c97 || fi.TBP0==0x2ace || fi.TBP0==0x03d0 || fi.TBP0==0x2448) && (fi.FBMSK == 0x0000)) { skip = 1; @@ -2268,6 +1509,783 @@ bool GSC_SteambotChronicles(const GSFrameInfo& fi, int& skip) return true; } +//////////////////////////////////////////////////////////////////////////////// +// Correctly emulated on OpenGL but can be used as potential speed hack +//////////////////////////////////////////////////////////////////////////////// + +bool GSC_Okami(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32) + { + skip = 1000; + } + } + else + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSM_PSMT4) + { + skip = 0; + } + } + + return true; +} + +bool GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip) +{ + // Game requires sub RT support (texture cache limitation) + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT24) + { + skip = 1000; // 76, 79 + } + else if(fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSM_PSMCT24 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT32) + { + skip = 1000; // 69 + } + } + else + { + if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSM_PSMCT32) + { + skip = 0; + } + else if(!fi.TME && fi.FBP == fi.TBP0 && fi.TBP0 == 0x2000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMCT24) + { + if(g_crc_region == CRC::US || g_crc_region == CRC::JP || g_crc_region == CRC::KO) + { + skip = 119; //ntsc + } + else + { + skip = 136; //pal + } + } + } + + return true; +} + +bool GSC_SFEX3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSM_PSMCT16) + { + skip = 2; // blur + } + } + + return true; +} + +bool GSC_Bully(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.FPSM == fi.TPSM) + { + return false; // allowed + } + + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x02300 && fi.TPSM == PSM_PSMZ16S) + { + skip = 6; + } + } + else + { + if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSM_PSMCT32) + { + skip = 0; + } + } + + return true; +} + +bool GSC_BullyCC(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.FPSM == fi.TPSM) + { + return false; // allowed + } + + if(!fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSM_PSMCT24) + { + skip = 9; + } + } + + return true; +} + +bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16) + { + skip = 4; + } + } + + return true; +} + +bool GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16) + { + skip = 4; + } + } + + return true; +} + +bool GSC_GodOfWar(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 1000; + } + else if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32 && fi.FBMSK == 0xff000000) + { + skip = 1; // blur + } + else if(fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8 && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))) + { + skip = 1; // wall of fog + } + else if (fi.TME && (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S)) + { + // Equivalent to the UserHacks_AutoSkipDrawDepth hack but enabled by default + // http://forums.pcsx2.net/Thread-God-of-War-Red-line-rendering-explained + skip = 1; + } + } + else + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16) + { + skip = 3; + } + } + + return true; +} + +bool GSC_GodOfWar2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME) + { + if( fi.FBP == 0x00100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSM_PSMCT16 // ntsc + || fi.FBP == 0x02100 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSM_PSMCT16) // pal + { + skip = 1000; // shadows + } + if((fi.FBP == 0x00100 || fi.FBP == 0x02100) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 & 0x03000) == 0x03000 + && (fi.TPSM == PSM_PSMT8 || fi.TPSM == PSM_PSMT4) + && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))) + { + skip = 1; // wall of fog + } + else if(Aggresive && fi.TPSM == PSM_PSMCT24 && fi.TME && (fi.FBP ==0x1300 ) && (fi.TBP0 ==0x0F00 || fi.TBP0 ==0x1300 || fi.TBP0==0x2b00)) // || fi.FBP == 0x0100 + { + skip = 1; // global haze/halo + } + else if(Aggresive && fi.TPSM == PSM_PSMCT24 && fi.TME && (fi.FBP ==0x0100 ) && (fi.TBP0==0x2b00 || fi.TBP0==0x2e80)) //480P 2e80 + { + skip = 1; // water effect and water vertical lines + } + else if (fi.TME && (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S)) + { + // Equivalent to the UserHacks_AutoSkipDrawDepth hack but enabled by default + // http://forums.pcsx2.net/Thread-God-of-War-Red-line-rendering-explained + skip = 1; + } + } + } + else + { + if(fi.TME && (fi.FBP == 0x00100 || fi.FBP == 0x02100) && fi.FPSM == PSM_PSMCT16) + { + skip = 3; + } + } + + return true; +} + +bool GSC_GiTS(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == PSM_PSMCT16 && fi.TBP0 == 0x02e40 && fi.TPSM == PSM_PSMCT16) + { + skip = 1315; + } + } + else + { + } + + return true; +} + +bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FPSM == PSM_PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT16) + { + skip = 1000; // shadow + } + } + else + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSM_PSMCT16 && fi.TPSM == PSM_PSMCT16S) + { + skip = 2; + } + } + + return true; +} + +bool GSC_SimpsonsGame(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && fi.TBP0 == 0x03000 && fi.TPSM == PSM_PSMCT32) + { + skip = 100; + } + } + else + { + if(fi.TME && fi.FBP == 0x03000 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8H) + { + skip = 2; + } + } + + return true; +} + +bool GSC_StarOcean3(const GSFrameInfo& fi, int& skip) +{ + // The game emulate a stencil buffer with the alpha channel of the RT + // The operation of the stencil is selected with the palette + // For example -1 wrap will be [240, 16, 32, 48 ....] + // i.e. p[A>>4] = (A - 16) % 256 + // + // The fastest and accurate solution will be to replace this pseudo stencil + // by a dedicated GPU draw call + // 1/ Use future GPU capabilities to do a "kind" of SW blending + // 2/ Use a real stencil/atomic image, and then compute the RT alpha value + // + // Both of those solutions will increase code complexity (and only avoid upscaling + // glitches) + + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) + { + skip = 1000; // + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + /*if(fi.TME && (fi.FBP == 0x018c0 || fi.FBP == 0x02180) && fi.FPSM == fi.TPSM && fi.TBP0 >= 0x03200 && fi.TPSM == PSM_PSMCT32) //NTSC only, !(fi.TBP0 == 0x03580 || fi.TBP0 == 0x03960) + { + skip = 1; //red garbage in lost forest, removes other effects... + } + if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 1; // //garbage in cutscenes, doesn't remove completely, better use "Alpha Hack" + }*/ + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) + { + // GH: Hack is quite similar to GSC_StarOcean3. It is potentially the same issue. + skip = 1000; // + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_RadiataStories(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 1; + } + else if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH) + { + // GH: Hack is quite similar to GSC_StarOcean3. It is potentially the same issue. + // Fixed on openGL + skip = 1000; + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_SuikodenTactics(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if( !fi.TME && fi.TPSM == PSM_PSMT8H && fi.FPSM == 0 && + fi.FBMSK == 0x0FF000000 && fi.TBP0 == 0 && GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) + { + skip = 4; + } + } + + return true; +} + +bool GSC_Tenchu(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 3; + } + } + + return true; +} + +bool GSC_Sly3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00700 || fi.FBP == 0x00a80 || fi.FBP == 0x00e00) && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00700 || fi.TBP0 == 0x00a80 || fi.TBP0 == 0x00e00) && fi.TPSM == PSM_PSMCT16) + { + skip = 1000; + } + } + else + { + if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 3; + } + } + + return true; +} + +bool GSC_Sly2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00700 || fi.FBP == 0x00800) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 1000; + } + } + else + { + if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 3; + } + } + + return true; +} + +bool GSC_DemonStone(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT16) + { + skip = 1000; + } + } + else + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSM_PSMCT32) + { + skip = 2; + } + } + + return true; +} + +bool GSC_BigMuthaTruckers(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT16) + { + skip = 3; + } + } + + return true; +} + +bool GSC_LordOfTheRingsTwoTowers(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x01180 || fi.FBP == 0x01400) && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT16) + { + skip = 1000;//shadows + } + else if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.TBP0 == 0x01400 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x03FFF) + { + skip = 3; //wall of fog + } + } + else + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && (fi.TBP0 == 0x01180 || fi.TBP0 == 0x01400) && fi.FPSM == PSM_PSMCT32) + { + skip = 2; + } + } + + return true; +} + +bool GSC_Castlevania(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + // This hack removes the shadows and globally darker image + // I think there are 2 issues on GSdx + // + // 1/ potential not correctly supported colclip. + // + // 2/ use of a 32 bits format to emulate a 16 bit formats + // For example, if you blend 64 time the value 4 on a dark destination pixels + // + // FMT32: 4*64 = 256 <= white pixels + // + // FMT16: output of blending will always be 0 because the 3 lsb of color is dropped. + // Therefore the pixel remains dark !!! + if(fi.TME && fi.FBP == 0 && fi.TBP0 && fi.TPSM == 10 && fi.FBMSK == 0xFFFFFF) + { + skip = 2; + } + } + + return true; +} + +bool GSC_Black(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + // Note: the first part of the hack must be fixed in openGL (texture shuffle). Remains the 2nd part (HasSharedBits) + if(fi.TME /*&& (fi.FBP == 0x00000 || fi.FBP == 0x008c0)*/ && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x01a40 || fi.TBP0 == 0x01b80 || fi.TBP0 == 0x030c0) && fi.TPSM == PSM_PSMZ16 || (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))) + { + skip = 5; + } + } + else + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x008c0 || fi.FBP == 0x0a00 ) && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT4) + { + skip = 0; + } + else if(!fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSM_PSMCT32 && fi.TPSM == PSM_PSMT8H) + { + skip = 0; + } + } + + return true; +} + +bool GSC_CrashNburn(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + + return true; +} + +bool GSC_SpyroNewBeginning(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && fi.TBP0 == 0x034a0 && fi.TPSM == PSM_PSMCT16) + { + skip = 2; + } + } + + return true; +} + +bool GSC_SpyroEternalNight(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == fi.TPSM && (fi.TBP0 == 0x034a0 ||fi.TBP0 == 0x035a0 || fi.TBP0 == 0x036e0) && fi.TPSM == PSM_PSMCT16) + { + skip = 2; + } + } + + return true; +} + +bool GSC_XE3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TPSM == PSM_PSMT8H && fi.FBMSK >= 0xEFFFFFFF) + { + skip = 73; + } + else if(fi.TME && fi.FBP ==0x03800 && fi.TBP0 && fi.TPSM ==0 && fi.FBMSK == 0) + { + skip = 1; + } + /*else if(fi.TPSM ==0x00000 && PSM_PSMCT24 && fi.TME && fi.FBP == 0x03800) + { + skip = 1 ; + }*/ + /*else if(fi.TME ==0 && (fi.FBP ==0 ) && fi.FPSM == PSM_PSMCT32 && ( fi.TPSM == PSM_PSMT8 || fi.TPSM == PSM_PSMT4) && (fi.FBMSK == 0x00FFFFFF || fi.FBMSK == 0xFF000000)) + { + skip = 1; + }*/ + else + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + } + return true; +} + +bool GSC_Grandia3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP ==0x0 || fi.FBP ==0x0e00) && (fi.TBP0 ==0x2a00 ||fi.TBP0==0x0e00 ||fi.TBP0==0) && fi.FPSM == fi.TPSM && fi.TPSM == PSM_PSMCT32) + { + skip = 1; + } + } + + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// Aggresive only hack +//////////////////////////////////////////////////////////////////////////////// + +template +bool GSC_SMTNocturneDDS(const GSFrameInfo& fi, int& skip) +{ + // stop the motion blur on the main character and + // smudge filter from being drawn on USA versions of + // Nocturne, Digital Devil Saga 1 and Digital Devil Saga 2 + + if(Aggresive && g_crc_region == CRC::US && skip == 0 && fi.TBP0 == 0xE00 && fi.TME) + { + // Note: it will crash if the core doesn't allocate the EE mem in 0x2000_0000 (unlikely but possible) + // Aggresive hacks are evil anyway + + // Nocturne: + // -0x5900($gp), ref at 0x100740 + const int state = *(int*)(state_addr); + if (state == 23 || state == 24 || state == 25) + skip = 1; + } + return true; +} + +bool GSC_LegoBatman(const GSFrameInfo& fi, int& skip) +{ + if(Aggresive && skip == 0) + { + if(fi.TME && fi.TPSM == PSM_PSMZ16 && fi.FPSM == PSM_PSMCT16 && fi.FBMSK == 0x00000) + { + skip = 3; + } + } + return true; +} + +bool GSC_SoTC(const GSFrameInfo& fi, int& skip) +{ + // Not needed anymore? What did it fix anyway? (rama) + if(skip == 0) + { + if(Aggresive && fi.TME /*&& fi.FBP == 0x03d80*/ && fi.FPSM == 0 && fi.TBP0 == 0x03fc0 && fi.TPSM == 1) + { + skip = 48; //removes sky bloom + } + /* + if(fi.TME && fi.FBP == 0x02b80 && fi.FPSM == PSM_PSMCT24 && fi.TBP0 == 0x01e80 && fi.TPSM == PSM_PSMCT24) + { + skip = 9; + } + else if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSM_PSMCT32) + { + skip = 8; + } + else if(fi.TME && fi.FBP == 0x01e80 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03880 && fi.TPSM == PSM_PSMCT32) + { + skip = 8; + }*/ + } + + + + + + return true; +} + +bool GSC_FFXII(const GSFrameInfo& fi, int& skip) +{ + if(Aggresive && skip == 0) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + return true; +} + +bool GSC_FFX2(const GSFrameInfo& fi, int& skip) +{ + if(Aggresive && skip == 0) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + return true; +} + +bool GSC_FFX(const GSFrameInfo& fi, int& skip) +{ + if(Aggresive && skip == 0) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + return true; +} + +bool GSC_SSX3(const GSFrameInfo& fi, int& skip) +{ + if(Aggresive && skip == 0) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) || + // General, often problematic post processing + (GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) ) + { + skip = 1; + } + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// + #undef Agressive #ifdef ENABLE_DYNAMIC_CRC_HACK @@ -2341,10 +2359,10 @@ public: struct stat s; if( stat( m_dllPath.c_str(), &s ) ) - { + { // File doesn't exist or other error, unload dll bool wasLoaded = m_library?true:false; - UnloadLib(); + UnloadLib(); return firstTime || wasLoaded; // Changed if previously loaded or the first time accessing this method (and file doesn't exist) } @@ -2384,15 +2402,15 @@ bool IsInvokedDynamicCrcHack( GSFrameInfo &fi, int& skip, int region, bool &resu { dllFunc = (DynaHackType)dll.GetSymbolAddress( "DynamicCrcHack" ); dllFunc2 = (DynaHackType2)dll.GetSymbolAddress( "DynamicCrcHack2" ); - printf( "GSdx: Dynamic CRC-hacks%s: %s\n", + printf( "GSdx: Dynamic CRC-hacks%s: %s\n", ((dllFunc && !dllFunc2)?" [Old dynaDLL - No CRC support]":""), dllFunc? "Loaded OK (-> overriding internal hacks)" : "Not available (-> using internal hacks)"); } - + if( !dllFunc2 && !dllFunc ) return false; - + int32 skip32 = skip; bool hasSharedBits = GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM); if(dllFunc2) @@ -2433,13 +2451,11 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) map[CRC::AlpineRacer3] = GSC_AlpineRacer3; map[CRC::BlackHawkDown] = GSC_BlackHawkDown; map[CRC::BleachBladeBattlers] = GSC_BleachBladeBattlers; - map[CRC::BullyCC] = GSC_BullyCC; // Bully is fixed, maybe this one too? map[CRC::BurnoutDominator] = GSC_Burnout; map[CRC::BurnoutRevenge] = GSC_Burnout; map[CRC::BurnoutTakedown] = GSC_Burnout; map[CRC::CaptainTsubasa] = GSC_CaptainTsubasa; map[CRC::CrashBandicootWoC] = GSC_CrashBandicootWoC; - map[CRC::CrashNburn] = GSC_CrashNburn; map[CRC::DBZBT2] = GSC_DBZBT2; map[CRC::DBZBT3] = GSC_DBZBT3; map[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams; @@ -2521,6 +2537,7 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) // Hack that were fixed on openGL if (Dx_only) { map[CRC::Bully] = GSC_Bully; + map[CRC::BullyCC] = GSC_BullyCC; map[CRC::GodOfWar2] = GSC_GodOfWar2; map[CRC::LordOfTheRingsTwoTowers] = GSC_LordOfTheRingsTwoTowers; map[CRC::Okami] = GSC_Okami; @@ -2531,6 +2548,7 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) // Not tested but must be fixed with texture shuffle map[CRC::BigMuthaTruckers] = GSC_BigMuthaTruckers; map[CRC::DemonStone] = GSC_DemonStone; + map[CRC::CrashNburn] = GSC_CrashNburn; // seem to be a basic depth effect map[CRC::GiTS] = GSC_GiTS; map[CRC::LegoBatman] = GSC_LegoBatman; map[CRC::OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;