From fbdf7521e5a3928e3c3ef55418b8be20134768ee Mon Sep 17 00:00:00 2001 From: "gregory.hainaut@gmail.com" Date: Tue, 17 Aug 2010 13:38:57 +0000 Subject: [PATCH] GregMiscellaneous: Try to remove blur from some games. Gets the code from GSdx. note: it is not working for the moment. git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3653 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/zzogl-pg/opengl/CMakeLists.txt | 1 + plugins/zzogl-pg/opengl/GS.h | 38 ++ plugins/zzogl-pg/opengl/GSmain.cpp | 50 ++ plugins/zzogl-pg/opengl/ZZoglFlush.cpp | 3 +- plugins/zzogl-pg/opengl/ZZoglFlushHack.cpp | 731 +++++++++++++++++++++ plugins/zzogl-pg/opengl/ZZoglFlushHack.h | 79 +++ plugins/zzogl-pg/opengl/zerogs.h | 1 + 7 files changed, 902 insertions(+), 1 deletion(-) create mode 100644 plugins/zzogl-pg/opengl/ZZoglFlushHack.cpp create mode 100644 plugins/zzogl-pg/opengl/ZZoglFlushHack.h diff --git a/plugins/zzogl-pg/opengl/CMakeLists.txt b/plugins/zzogl-pg/opengl/CMakeLists.txt index fb31588644..3e08f0c627 100644 --- a/plugins/zzogl-pg/opengl/CMakeLists.txt +++ b/plugins/zzogl-pg/opengl/CMakeLists.txt @@ -65,6 +65,7 @@ set(zzoglSources ZZoglCreate.cpp ZZoglCRTC.cpp ZZoglFlush.cpp + ZZoglFlushHack.cpp ZZoglSave.cpp ZZoglShaders.cpp ZZoglShoots.cpp diff --git a/plugins/zzogl-pg/opengl/GS.h b/plugins/zzogl-pg/opengl/GS.h index 623f63e4d4..a250ea2f35 100644 --- a/plugins/zzogl-pg/opengl/GS.h +++ b/plugins/zzogl-pg/opengl/GS.h @@ -310,6 +310,44 @@ enum PSM_value PSMT16SZ = 58, // 111010 }; +enum GS_PRIM +{ + GS_POINTLIST = 0, + GS_LINELIST = 1, + GS_LINESTRIP = 2, + GS_TRIANGLELIST = 3, + GS_TRIANGLESTRIP = 4, + GS_TRIANGLEFAN = 5, + GS_SPRITE = 6, + GS_INVALID = 7, +}; + +enum GS_PRIM_CLASS +{ + GS_POINT_CLASS = 0, + GS_LINE_CLASS = 1, + GS_TRIANGLE_CLASS = 2, + GS_SPRITE_CLASS = 3, + GS_INVALID_CLASS = 7, +}; + +enum GS_PSM +{ + PSM_PSMCT32 = 0, // 0000-0000 + PSM_PSMCT24 = 1, // 0000-0001 + PSM_PSMCT16 = 2, // 0000-0010 + PSM_PSMCT16S = 10, // 0000-1010 + PSM_PSMT8 = 19, // 0001-0011 + PSM_PSMT4 = 20, // 0001-0100 + PSM_PSMT8H = 27, // 0001-1011 + PSM_PSMT4HL = 36, // 0010-0100 + PSM_PSMT4HH = 44, // 0010-1100 + PSM_PSMZ32 = 48, // 0011-0000 + PSM_PSMZ24 = 49, // 0011-0001 + PSM_PSMZ16 = 50, // 0011-0010 + PSM_PSMZ16S = 58, // 0011-1010 +}; + // Check target bit mode. PSMCT32 and 32Z return 0, 24 and 24Z - 1 // 16, 16S, 16Z, 16SZ -- 2, PSMT8 and 8H - 3, PSMT4, 4HL, 4HH -- 4. inline int PSMT_BITMODE(int psm) {return (psm & 0x7);} diff --git a/plugins/zzogl-pg/opengl/GSmain.cpp b/plugins/zzogl-pg/opengl/GSmain.cpp index dd46a08ee3..57bd408dae 100644 --- a/plugins/zzogl-pg/opengl/GSmain.cpp +++ b/plugins/zzogl-pg/opengl/GSmain.cpp @@ -36,6 +36,7 @@ using namespace std; #include "zerogs.h" #include "targets.h" #include "ZeroGSShaders/zerogsshaders.h" +#include "ZZoglFlushHack.h" #ifdef _MSC_VER #pragma warning(disable:4244) @@ -48,6 +49,8 @@ GSconf conf; int ppf, g_GSMultiThreaded, CurrentSavestate = 0; int g_LastCRC = 0, g_TransferredToGPU = 0, s_frameskipping = 0; +int g_SkipFlushFrame = 0; +GetSkipCount GetSkipCount_Handler = 0; int UPDATE_FRAMES = 16, g_nFrame = 0, g_nRealFrame = 0; float fFPS = 0; @@ -175,6 +178,49 @@ void ListHacks() void CALLBACK GSsetGameCRC(int crc, int options) { + // build a list of function pointer for GetSkipCount (UserHacks_SkipDraw) + static GetSkipCount GSC_list[GAME_INFO_INDEX]; + static bool inited = false; + if(!inited) + { + inited = true; + + memset(&GSC_list, 0, sizeof(GSC_list)); + + GSC_list[Okami] = GSC_Okami; + GSC_list[MetalGearSolid3] = GSC_MetalGearSolid3; + GSC_list[DBZBT2] = GSC_DBZBT2; + GSC_list[DBZBT3] = GSC_DBZBT3; + GSC_list[SFEX3] = GSC_SFEX3; + GSC_list[Bully] = GSC_Bully; + GSC_list[BullyCC] = GSC_BullyCC; + GSC_list[SoTC] = GSC_SoTC; + GSC_list[OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure; + GSC_list[OnePieceGrandBattle] = GSC_OnePieceGrandBattle; + GSC_list[ICO] = GSC_ICO; + GSC_list[GT4] = GSC_GT4; + //FIXME GSC_list[WildArms4] = GSC_WildArms4; + GSC_list[WildArms5] = GSC_WildArms5; + GSC_list[Manhunt2] = GSC_Manhunt2; + GSC_list[CrashBandicootWoC] = GSC_CrashBandicootWoC; + GSC_list[ResidentEvil4] = GSC_ResidentEvil4; + GSC_list[Spartan] = GSC_Spartan; + GSC_list[AceCombat4] = GSC_AceCombat4; + GSC_list[Drakengard2] = GSC_Drakengard2; + GSC_list[Tekken5] = GSC_Tekken5; + GSC_list[IkkiTousen] = GSC_IkkiTousen; + GSC_list[GodOfWar] = GSC_GodOfWar; + GSC_list[GodOfWar2] = GSC_GodOfWar2; + GSC_list[GiTS] = GSC_GiTS; + GSC_list[Onimusha3] = GSC_Onimusha3; + GSC_list[TalesOfAbyss] = GSC_TalesOfAbyss; + GSC_list[SonicUnleashed] = GSC_SonicUnleashed; + GSC_list[Genji] = GSC_Genji; + GSC_list[StarOcean3] = GSC_StarOcean3; + GSC_list[ValkyrieProfile2] = GSC_ValkyrieProfile2; + GSC_list[RadiataStories] = GSC_RadiataStories; + } + // TEXDESTROY_THRESH starts out at 16. VALIDATE_THRESH = 8; conf.mrtdepth = (conf.settings().disable_mrt_depth != 0); @@ -210,6 +256,9 @@ void CALLBACK GSsetGameCRC(int crc, int options) ZZLog::WriteLn("Setting TEXDESTROY_THRESH to %d", TEXDESTROY_THRESH); } + // FIXME need to check UserHacks_SkipDraw is positive (enabled by users) + GetSkipCount_Handler = GSC_list[crc_game_list[i].title]; + conf.def_hacks._u32 |= crc_game_list[i].flags; ListHacks(); return; @@ -492,6 +541,7 @@ void CALLBACK GSvsync(int interlace) g_nAlphaVars = 0; g_nResolve = 0; g_nFramesSkipped = 0; + g_SkipFlushFrame = 0; } #if defined(ZEROGS_DEVBUILD) diff --git a/plugins/zzogl-pg/opengl/ZZoglFlush.cpp b/plugins/zzogl-pg/opengl/ZZoglFlush.cpp index e4338b555a..60127d2c2f 100644 --- a/plugins/zzogl-pg/opengl/ZZoglFlush.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglFlush.cpp @@ -25,6 +25,7 @@ #include "Mem.h" #include "zerogs.h" #include "targets.h" +#include "ZZoglFlushHack.h" using namespace ZeroGS; @@ -376,7 +377,7 @@ inline void FlushUpdateEffect() // Check, maybe we cold skip flush inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest) { - if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0) /*|| g_bIsLost*/) + if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0) /*|| g_bIsLost*/ || IsBadFrame(curvb) == 1) { curvb.nCount = 0; return true; diff --git a/plugins/zzogl-pg/opengl/ZZoglFlushHack.cpp b/plugins/zzogl-pg/opengl/ZZoglFlushHack.cpp new file mode 100644 index 0000000000..df23d5e376 --- /dev/null +++ b/plugins/zzogl-pg/opengl/ZZoglFlushHack.cpp @@ -0,0 +1,731 @@ +/* ZZ Open GL graphics plugin + * Copyright (c)2010 gregory.hainaut@gmail.com + * Based on GSdx Copyright (C) 2007-2009 Gabest + * + * 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 + */ + +/* This file is a collection of hack for removing the blur effect on some games + * The blur renders very badly on high screen flat panel. + * + * To avoid severals combo-box, the hack detects the game based on crc + */ + +#include "ZZoglFlushHack.h" + +bool GSC_Okami(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32) + { + skip = 1000; + } + } + else + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMT4) + { + skip = 0; + } + } + + return true; +} + +bool GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT24) + { + skip = 1000; // 76, 79 + } + else if(fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSMCT24 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT32) + { + skip = 1000; // 69 + } + } + else + { + if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSMCT32) + { + skip = 0; + } + } + + return true; +} + +bool GSC_DBZBT2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && /*fi.FBP == 0x00000 && fi.FPSM == PSMCT16 &&*/ fi.TBP0 == 0x02000 && fi.TPSM == PSMT16Z) + { + skip = 27; + } + else if(!fi.TME && fi.FBP == 0x03000 && fi.FPSM == PSMCT16) + { + skip = 10; + } + } + + return true; +} + +bool GSC_DBZBT3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00) && fi.TPSM == PSMT8H) + { + skip = 24; // blur + } + else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8H) + { + skip = 28; // outline + } + } + + return true; +} + +bool GSC_SFEX3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == 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 == PSMCT32 && fi.FPSM == fi.TPSM) + { + return false; // allowed + } + + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSMCT16S && fi.TBP0 == 0x02300 && fi.TPSM == PSMT16SZ) + { + skip = 6; + } + } + else + { + if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == 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 == PSMCT32 && fi.FPSM == fi.TPSM) + { + return false; // allowed + } + + if(!fi.TME && fi.FBP == 0x02800 && fi.FPSM == 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(fi.TME && fi.FBP == 0x02b80 && fi.FPSM == PSMCT24 && fi.TBP0 == 0x01e80 && fi.TPSM == PSMCT24) + { + skip = 9; + } + else if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMCT32) + { + skip = 8; + } + else if(fi.TME && fi.FBP == 0x01e80 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03880 && fi.TPSM == PSMCT32) + { + skip = 8; + } + }*/ + + return true; +} + +bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16) + { + skip = 4; + } + } + + return true; +} + +bool GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16) + { + skip = 4; + } + } + + return true; +} + +bool GSC_ICO(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03d00 && fi.TPSM == PSMCT32) + { + skip = 3; + } + else if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02800 && fi.TPSM == PSMT8H) + { + skip = 1; + } + } + else + { + if(fi.TME && fi.TBP0 == 0x00800 && fi.TPSM == PSMCT32) + { + skip = 0; + } + } + + return true; +} + +bool GSC_GT4(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x03440 || fi.FBP >= 0x03e00) && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400) && fi.TPSM == PSMT8) + { + skip = 880; + } + else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01400) && fi.FPSM == PSMCT24 && fi.TBP0 >= 0x03420 && fi.TPSM == PSMT8) + { + // TODO: removes gfx from where it is not supposed to (garage) + // skip = 58; + } + } + + return true; +} + +bool GSC_WildArms4(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z) + { + skip = 100; + } + } + else + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32) + { + skip = 1; + } + } + + return true; +} + +bool GSC_WildArms5(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z) + { + skip = 100; + } + } + else + { + if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32) + { + skip = 1; + } + } + + return true; +} + +bool GSC_Manhunt2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x03c20 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01400 && fi.TPSM == PSMT8) + { + skip = 640; + } + } + + return true; +} + +bool GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00a00) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM) + { + return false; // allowed + } + + if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01400 && fi.TPSM == PSMT24Z) + { + skip = 41; + } + } + else + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03c00 && fi.TPSM == PSMCT32) + { + skip = 0; + } + else if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT24Z) + { + skip = 176; + } + } + + return true; +} + +bool GSC_Spartan(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32) + { + skip = 107; + } + } + + return true; +} + +bool GSC_AceCombat4(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02a00 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01600 && fi.TPSM == PSMT24Z) + { + skip = 71; // clouds (z, 16-bit) + } + else if(fi.TME && fi.FBP == 0x02900 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT24) + { + skip = 28; // blur + } + } + + return true; +} + +bool GSC_Drakengard2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x026c0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00a00 && fi.TPSM == PSMCT32) + { + skip = 64; + } + } + + return true; +} + +bool GSC_Tekken5(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02ea0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32) + { + skip = 95; + } + } + + return true; +} + +bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00a80 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z) + { + skip = 1000; // shadow (result is broken without depth copy, also includes 16 bit) + } + else if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z) + { + skip = 11; // blur + } + } + else if(skip > 7) + { + if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00700 && fi.TPSM == PSMCT16) + { + skip = 7; // the last steps of shadow drawing + } + } + + return true; +} + +bool GSC_GodOfWar(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16) + { + skip = 30; + } + else if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32 && fi.FBMSK == 0xff000000) + { + skip = 1; // blur + } + else if(fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8 && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))) + { + skip = 1; // wall of fog + } + } + + return true; +} + +bool GSC_GodOfWar2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME) + { + if((fi.FBP == 0x00100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSMCT16) // ntsc + || (fi.FBP == 0x02100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSMCT16)) // pal + { + skip = 29; // shadows + } + if(fi.FBP == 0x00100 && fi.FPSM == PSMCT32 && (fi.TBP0 & 0x03000) == 0x03000 + && (fi.TPSM == PSMT8 || fi.TPSM == PSMT4) + && ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000))){ + skip = 1; // wall of fog + } + } + } + + return true; +} + +bool GSC_GiTS(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02e40 && fi.TPSM == 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 == PSMCT32 || fi.TPSM == PSMCT24)) + { + skip = 1; + } + + return true; +} + +bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT8) // copies the z buffer to the alpha channel of the fb + { + skip = 1000; + } + else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && (fi.TBP0 == 0x03560 || fi.TBP0 == 0x038e0) && fi.TPSM == PSMCT32) + { + skip = 1; + } + } + else + { + if(fi.TME && fi.TPSM != PSMT8) + { + skip = 0; + } + } + + return true; +} + +bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16) + { + skip = 1000; // shadow + } + } + else + { + if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02200 && fi.TPSM == PSMCT16S) + { + skip = 2; + } + } + + return true; +} + +bool GSC_Genji(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == 0x01500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00e00 && fi.TPSM == PSMT16Z) + { + skip = 6; // + } + } + else + { + } + + return true; +} + +bool GSC_StarOcean3(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH) + { + skip = 1000; // + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH) + { + skip = 1000; // + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +bool GSC_RadiataStories(const GSFrameInfo& fi, int& skip) +{ + if(skip == 0) + { + if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH) + { + skip = 1000; // + } + } + else + { + if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)) + { + skip = 0; + } + } + + return true; +} + +static struct GSUtilMaps +{ + u8 PrimClassField[8]; + u32 CompatibleBitsField[64][2]; + u32 SharedBitsField[64][2]; + + GSUtilMaps() + { + PrimClassField[GS_POINTLIST] = GS_POINT_CLASS; + PrimClassField[GS_LINELIST] = GS_LINE_CLASS; + PrimClassField[GS_LINESTRIP] = GS_LINE_CLASS; + PrimClassField[GS_TRIANGLELIST] = GS_TRIANGLE_CLASS; + PrimClassField[GS_TRIANGLESTRIP] = GS_TRIANGLE_CLASS; + PrimClassField[GS_TRIANGLEFAN] = GS_TRIANGLE_CLASS; + PrimClassField[GS_SPRITE] = GS_SPRITE_CLASS; + PrimClassField[GS_INVALID] = GS_INVALID_CLASS; + + memset(CompatibleBitsField, 0, sizeof(CompatibleBitsField)); + + for(int i = 0; i < 64; i++) + { + CompatibleBitsField[i][i >> 5] |= 1 << (i & 0x1f); + } + + CompatibleBitsField[PSM_PSMCT32][PSM_PSMCT24 >> 5] |= 1 << (PSM_PSMCT24 & 0x1f); + CompatibleBitsField[PSM_PSMCT24][PSM_PSMCT32 >> 5] |= 1 << (PSM_PSMCT32 & 0x1f); + CompatibleBitsField[PSM_PSMCT16][PSM_PSMCT16S >> 5] |= 1 << (PSM_PSMCT16S & 0x1f); + CompatibleBitsField[PSM_PSMCT16S][PSM_PSMCT16 >> 5] |= 1 << (PSM_PSMCT16 & 0x1f); + CompatibleBitsField[PSM_PSMZ32][PSM_PSMZ24 >> 5] |= 1 << (PSM_PSMZ24 & 0x1f); + CompatibleBitsField[PSM_PSMZ24][PSM_PSMZ32 >> 5] |= 1 << (PSM_PSMZ32 & 0x1f); + CompatibleBitsField[PSM_PSMZ16][PSM_PSMZ16S >> 5] |= 1 << (PSM_PSMZ16S & 0x1f); + CompatibleBitsField[PSM_PSMZ16S][PSM_PSMZ16 >> 5] |= 1 << (PSM_PSMZ16 & 0x1f); + + memset(SharedBitsField, 0, sizeof(SharedBitsField)); + + SharedBitsField[PSM_PSMCT24][PSM_PSMT8H >> 5] |= 1 << (PSM_PSMT8H & 0x1f); + SharedBitsField[PSM_PSMCT24][PSM_PSMT4HL >> 5] |= 1 << (PSM_PSMT4HL & 0x1f); + SharedBitsField[PSM_PSMCT24][PSM_PSMT4HH >> 5] |= 1 << (PSM_PSMT4HH & 0x1f); + SharedBitsField[PSM_PSMZ24][PSM_PSMT8H >> 5] |= 1 << (PSM_PSMT8H & 0x1f); + SharedBitsField[PSM_PSMZ24][PSM_PSMT4HL >> 5] |= 1 << (PSM_PSMT4HL & 0x1f); + SharedBitsField[PSM_PSMZ24][PSM_PSMT4HH >> 5] |= 1 << (PSM_PSMT4HH & 0x1f); + SharedBitsField[PSM_PSMT8H][PSM_PSMCT24 >> 5] |= 1 << (PSM_PSMCT24 & 0x1f); + SharedBitsField[PSM_PSMT8H][PSM_PSMZ24 >> 5] |= 1 << (PSM_PSMZ24 & 0x1f); + SharedBitsField[PSM_PSMT4HL][PSM_PSMCT24 >> 5] |= 1 << (PSM_PSMCT24 & 0x1f); + SharedBitsField[PSM_PSMT4HL][PSM_PSMZ24 >> 5] |= 1 << (PSM_PSMZ24 & 0x1f); + SharedBitsField[PSM_PSMT4HL][PSM_PSMT4HH >> 5] |= 1 << (PSM_PSMT4HH & 0x1f); + SharedBitsField[PSM_PSMT4HH][PSM_PSMCT24 >> 5] |= 1 << (PSM_PSMCT24 & 0x1f); + SharedBitsField[PSM_PSMT4HH][PSM_PSMZ24 >> 5] |= 1 << (PSM_PSMZ24 & 0x1f); + SharedBitsField[PSM_PSMT4HH][PSM_PSMT4HL >> 5] |= 1 << (PSM_PSMT4HL & 0x1f); + } + +} s_maps; + +bool HasSharedBits(u32 sbp, u32 spsm, u32 dbp, u32 dpsm) +{ + return ((sbp ^ dbp) | (s_maps.SharedBitsField[dpsm][spsm >> 5] & (1 << (spsm & 0x1f)))) == 0; +} + + +bool IsBadFrame(ZeroGS::VB& curvb) +{ + GSFrameInfo fi; + + /* GSdx implementation + fi.FBP = m_context->FRAME.Block(); + fi.FPSM = m_context->FRAME.PSM; + fi.FBMSK = m_context->FRAME.FBMSK; + fi.TME = PRIM->TME; + fi.TBP0 = m_context->TEX0.TBP0; + fi.TPSM = m_context->TEX0.PSM; + fi.TZTST = m_context->TEST.ZTST; + */ + + // FIXME what is the difference between gsfb & frame ? I use the first one maybe the others one is best ... + fi.FBP = curvb.gsfb.fbp << 5; + fi.FPSM = curvb.gsfb.psm; + fi.FBMSK = curvb.gsfb.fbm; + fi.TME = curvb.curprim.tme; + fi.TBP0 = curvb.tex0.tbp0; + fi.TPSM = curvb.tex0.psm; + fi.TZTST = curvb.test.ztst; + + if(GetSkipCount_Handler && !GetSkipCount_Handler(fi, g_SkipFlushFrame)) + { + return 0; + } + + // FIXME Need to add a UserHacks_SkipDraw options, with a "number" value... + int UserHacks_SkipDraw = 1; // test FFX + UserHacks_SkipDraw = 0; + + if(g_SkipFlushFrame == 0 && (UserHacks_SkipDraw > 0) ) + { + if(fi.TME) + { + // depth textures (bully, mgs3s1 intro, Front Mission 5) + if( (fi.TPSM == PSMT32Z || fi.TPSM == PSMT24Z || fi.TPSM == PSMT16Z || fi.TPSM == PSMT16SZ) + // General, often problematic post processing + || (HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) + ) + { + //ZZLog::Error_Log("Run the draw hack"); + g_SkipFlushFrame = UserHacks_SkipDraw; + } + } + } + + if(g_SkipFlushFrame > 0) + { + g_SkipFlushFrame--; + + return 1; + } + + return 0; +} diff --git a/plugins/zzogl-pg/opengl/ZZoglFlushHack.h b/plugins/zzogl-pg/opengl/ZZoglFlushHack.h new file mode 100644 index 0000000000..6219354284 --- /dev/null +++ b/plugins/zzogl-pg/opengl/ZZoglFlushHack.h @@ -0,0 +1,79 @@ +/* ZZ Open GL graphics plugin + * Copyright (c)2010 gregory.hainaut@gmail.com + * Based on GSdx Copyright (C) 2007-2009 Gabest + * + * 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 + */ + +/* This file is a collection of hack for removing the blur effect on some games + * The blur renders very badly on high screen flat panel. + * + * To avoid severals combo-box, the hack detects the game based on crc + */ + +#include "GS.h" +#include "zerogs.h" + +extern int g_SkipFlushFrame; + +struct GSFrameInfo +{ + u32 FBP; + u32 FPSM; + u32 FBMSK; + u32 TBP0; + u32 TPSM; + u32 TZTST; + bool TME; +}; + +typedef bool (*GetSkipCount)(const GSFrameInfo& fi, int& skip); + +extern GetSkipCount GetSkipCount_Handler; + +bool GSC_Okami(const GSFrameInfo& fi, int& skip); +bool GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip); +bool GSC_DBZBT2(const GSFrameInfo& fi, int& skip); +bool GSC_DBZBT3(const GSFrameInfo& fi, int& skip); +bool GSC_SFEX3(const GSFrameInfo& fi, int& skip); +bool GSC_Bully(const GSFrameInfo& fi, int& skip); +bool GSC_BullyCC(const GSFrameInfo& fi, int& skip); +bool GSC_SoTC(const GSFrameInfo& fi, int& skip); +bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip); +bool GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip); +bool GSC_ICO(const GSFrameInfo& fi, int& skip); +bool GSC_GT4(const GSFrameInfo& fi, int& skip); +bool GSC_WildArms4(const GSFrameInfo& fi, int& skip); +bool GSC_WildArms5(const GSFrameInfo& fi, int& skip); +bool GSC_Manhunt2(const GSFrameInfo& fi, int& skip); +bool GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip); +bool GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip); +bool GSC_Spartan(const GSFrameInfo& fi, int& skip); +bool GSC_AceCombat4(const GSFrameInfo& fi, int& skip); +bool GSC_Drakengard2(const GSFrameInfo& fi, int& skip); +bool GSC_Tekken5(const GSFrameInfo& fi, int& skip); +bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip); +bool GSC_GodOfWar(const GSFrameInfo& fi, int& skip); +bool GSC_GodOfWar2(const GSFrameInfo& fi, int& skip); +bool GSC_GiTS(const GSFrameInfo& fi, int& skip); +bool GSC_Onimusha3(const GSFrameInfo& fi, int& skip); +bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip); +bool GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip); +bool GSC_Genji(const GSFrameInfo& fi, int& skip); +bool GSC_StarOcean3(const GSFrameInfo& fi, int& skip); +bool GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip); +bool GSC_RadiataStories(const GSFrameInfo& fi, int& skip); + +bool IsBadFrame(ZeroGS::VB& curvb); diff --git a/plugins/zzogl-pg/opengl/zerogs.h b/plugins/zzogl-pg/opengl/zerogs.h index 6491297e3f..f783bc82f5 100644 --- a/plugins/zzogl-pg/opengl/zerogs.h +++ b/plugins/zzogl-pg/opengl/zerogs.h @@ -423,6 +423,7 @@ union CMemoryTarget* pmemtarg; // the current mem target set CRenderTarget* prndr; CDepthTarget* pdepth; + }; // Return, if tcc, aem or psm mode told us, than Alpha test should be used