mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1322 from PCSX2/gsdx-8b-subrt
gsdx: improve detection of channel shuffle
This commit is contained in:
commit
9cacfee8c7
|
@ -779,6 +779,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
|
|||
+ format("#define PS_DFMT %d\n", sel.dfmt)
|
||||
+ format("#define PS_DEPTH_FMT %d\n", sel.depth_fmt)
|
||||
+ format("#define PS_CHANNEL_FETCH %d\n", sel.channel)
|
||||
+ format("#define PS_URBAN_CHAOS_HACK %d\n", sel.urban_chaos_hack)
|
||||
+ format("#define PS_AEM %d\n", sel.aem)
|
||||
+ format("#define PS_TFX %d\n", sel.tfx)
|
||||
+ format("#define PS_TCC %d\n", sel.tcc)
|
||||
|
|
|
@ -289,8 +289,9 @@ class GSDeviceOGL final : public GSDevice
|
|||
|
||||
// Hack
|
||||
uint32 tcoffsethack:1;
|
||||
uint32 urban_chaos_hack:1;
|
||||
|
||||
uint32 _free2:16;
|
||||
uint32 _free2:15;
|
||||
};
|
||||
|
||||
uint64 key;
|
||||
|
|
|
@ -112,86 +112,6 @@ bool GSC_DBZBT3(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Potentially partially dx only
|
||||
bool GSC_ICO(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03d00 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 3;
|
||||
}
|
||||
else if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x02800 && fi.TPSM == PSM_PSMT8H)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
else if( Aggresive && fi.TME && fi.FBP == 0x0800 && (fi.TBP0 == 0x2800 || fi.TBP0 ==0x2c00) && fi.TPSM ==0 && fi.FBMSK == 0)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fi.TME && fi.TBP0 == 0x00800 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GT4(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Game requires to extract source from RT (block boundary) (texture cache limitation)
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x02f00 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180 /*|| fi.TBP0 == 0x01a40*/) && fi.TPSM == PSM_PSMT8) //TBP0 0x1a40 progressive
|
||||
{
|
||||
skip = 770; //ntsc, progressive 1540
|
||||
}
|
||||
if(g_crc_region == CRC::EU && fi.TME && fi.FBP >= 0x03400 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400 ) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 880; //pal
|
||||
}
|
||||
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01400) && fi.FPSM == PSM_PSMCT24 && fi.TBP0 >= 0x03420 && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
// TODO: removes gfx from where it is not supposed to (garage)
|
||||
// skip = 58;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GT3(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Same issue as GSC_GT4 ???
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x02de0 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 770;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GTConcept(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Same issue as GSC_GT4 ???
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x03420 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 880;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_WildArms4(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -234,6 +154,24 @@ bool GSC_WildArms5(const GSFrameInfo& fi, int& skip)
|
|||
|
||||
bool GSC_Manhunt2(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
/*
|
||||
* The game readback RT as 8 bits index texture to apply a non-linear brightness/gamma correction on all channel
|
||||
* It could be written in HLE shader as:
|
||||
* out = blue_lut[in.blue] + green_lut[in.green] + blue_lut[in.blue]
|
||||
*
|
||||
* Unlike others games (which do all pages of a channel), man hunt apply the 3 channel corrections by page.
|
||||
* (in short it is loop index/loop page instead of loop page/loop index)
|
||||
*
|
||||
* It is very annoying to detect.So in order to fix the effect the best
|
||||
* solution will be to implement an alternate draw call and then skip the
|
||||
* useless gs draw call.
|
||||
*
|
||||
* Blue Palette correction is located @ 0x3C08 (TEX0.CBP of the first draw call that will fire the effect)
|
||||
* Green Palette correction is located @ 0x3C04
|
||||
* Blue Palette correction is located @ 0x3C00
|
||||
* Either we upload the data as a new texture or we could hardcode them in a shader
|
||||
*
|
||||
*/
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP == 0x03c20 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x01400 && fi.TPSM == PSM_PSMT8)
|
||||
|
@ -865,36 +803,6 @@ bool GSC_StarWarsForceUnleashed(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSC_StarWarsBattlefront(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP > 0x0 && fi.FBP < 0x01000) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x02000 && fi.TBP0 < 0x03000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_StarWarsBattlefront2(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP > 0x01000 && fi.FBP < 0x02000) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x0 && fi.TBP0 < 0x01000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
if(fi.TME && (fi.FBP > 0x01000 && fi.FBP < 0x02000) && fi.FPSM == PSM_PSMZ32 && (fi.TBP0 > 0x0 && fi.TBP0 < 0x01000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_BlackHawkDown(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -1079,34 +987,6 @@ bool GSC_Yakuza2(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSC_SkyGunner(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
|
||||
if(!fi.TME && !(fi.FBP == 0x0 || fi.FBP == 0x00800 || fi.FBP == 0x008c0 || fi.FBP == 0x03e00) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x0 || fi.TBP0 == 0x01800) && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 1; //Huge Vram usage
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_JamesBondEverythingOrNothing(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
|
||||
if(fi.TME && (fi.FBP < 0x02000 && !(fi.FBP == 0x0 || fi.FBP == 0x00e00)) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x01c00 && fi.TBP0 < 0x03000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1; //Huge Vram usage
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_ZettaiZetsumeiToshi2(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -1237,23 +1117,6 @@ bool GSC_FightingBeautyWulong(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
skip = 770; //480P
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GTASanAndreas(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -1327,29 +1190,6 @@ bool GSC_UltramanFightingEvolution(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSC_DeathByDegreesTekkenNinaWilliams(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP ==0 ) && fi.TBP0==0x34a0 && (fi.TPSM == PSM_PSMCT32))
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
else if((fi.FBP ==0x3500)&& fi.TPSM == PSM_PSMT8 && fi.FBMSK == 0xFFFF00FF)
|
||||
{
|
||||
skip = 4;
|
||||
}
|
||||
}
|
||||
if(fi.TME)
|
||||
{
|
||||
if((fi.FBP | fi.TBP0 | fi.FPSM | fi.TPSM) && (fi.FBMSK == 0x00FFFFFF ))
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_AlpineRacer3(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -1512,6 +1352,182 @@ bool GSC_SteambotChronicles(const GSFrameInfo& fi, int& skip)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Correctly emulated on OpenGL but can be used as potential speed hack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool GSC_DeathByDegreesTekkenNinaWilliams(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP ==0 ) && fi.TBP0==0x34a0 && (fi.TPSM == PSM_PSMCT32))
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
else if((fi.FBP ==0x3500)&& fi.TPSM == PSM_PSMT8 && fi.FBMSK == 0xFFFF00FF)
|
||||
{
|
||||
skip = 4;
|
||||
}
|
||||
}
|
||||
if(fi.TME)
|
||||
{
|
||||
if((fi.FBP | fi.TBP0 | fi.FPSM | fi.TPSM) && (fi.FBMSK == 0x00FFFFFF ))
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_ICO(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x03d00 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 3;
|
||||
}
|
||||
else if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSM_PSMCT32 && fi.TBP0 == 0x02800 && fi.TPSM == PSM_PSMT8H)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
else if( Aggresive && fi.TME && fi.FBP == 0x0800 && (fi.TBP0 == 0x2800 || fi.TBP0 ==0x2c00) && fi.TPSM ==0 && fi.FBMSK == 0)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fi.TME && fi.TBP0 == 0x00800 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GT4(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Game requires to extract source from RT (block boundary) (texture cache limitation)
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x02f00 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180 /*|| fi.TBP0 == 0x01a40*/) && fi.TPSM == PSM_PSMT8) //TBP0 0x1a40 progressive
|
||||
{
|
||||
skip = 770; //ntsc, progressive 1540
|
||||
}
|
||||
if(g_crc_region == CRC::EU && fi.TME && fi.FBP >= 0x03400 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400 ) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 880; //pal
|
||||
}
|
||||
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01400) && fi.FPSM == PSM_PSMCT24 && fi.TBP0 >= 0x03420 && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
// TODO: removes gfx from where it is not supposed to (garage)
|
||||
// skip = 58;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GT3(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Same issue as GSC_GT4 ???
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x02de0 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 770;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_GTConcept(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
// Same issue as GSC_GT4 ???
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP >= 0x03420 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 880;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
skip = 770; //480P
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_SkyGunner(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
|
||||
if(!fi.TME && !(fi.FBP == 0x0 || fi.FBP == 0x00800 || fi.FBP == 0x008c0 || fi.FBP == 0x03e00) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x0 || fi.TBP0 == 0x01800) && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 1; //Huge Vram usage
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_JamesBondEverythingOrNothing(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
|
||||
if(fi.TME && (fi.FBP < 0x02000 && !(fi.FBP == 0x0 || fi.FBP == 0x00e00)) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x01c00 && fi.TBP0 < 0x03000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1; //Huge Vram usage
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_StarWarsBattlefront(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP > 0x0 && fi.FBP < 0x01000) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x02000 && fi.TBP0 < 0x03000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_StarWarsBattlefront2(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP > 0x01000 && fi.FBP < 0x02000) && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 > 0x0 && fi.TBP0 < 0x01000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
if(fi.TME && (fi.FBP > 0x01000 && fi.FBP < 0x02000) && fi.FPSM == PSM_PSMZ32 && (fi.TBP0 > 0x0 && fi.TBP0 < 0x01000) && fi.TPSM == PSM_PSMT8)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_Okami(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
|
@ -2458,7 +2474,6 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
map[CRC::CrashBandicootWoC] = GSC_CrashBandicootWoC;
|
||||
map[CRC::DBZBT2] = GSC_DBZBT2;
|
||||
map[CRC::DBZBT3] = GSC_DBZBT3;
|
||||
map[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
|
||||
map[CRC::DevilMayCry3] = GSC_DevilMayCry3;
|
||||
map[CRC::EternalPoison] = GSC_EternalPoison;
|
||||
map[CRC::EvangelionJo] = GSC_EvangelionJo;
|
||||
|
@ -2470,16 +2485,11 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
map[CRC::GetaWayBlackMonday] = GSC_GetaWay;
|
||||
map[CRC::GetaWay] = GSC_GetaWay;
|
||||
map[CRC::GodHand] = GSC_GodHand;
|
||||
map[CRC::GT3] = GSC_GT3;
|
||||
map[CRC::GT4] = GSC_GT4;
|
||||
map[CRC::GTASanAndreas] = GSC_GTASanAndreas;
|
||||
map[CRC::GTConcept] = GSC_GTConcept;
|
||||
map[CRC::HauntingGround] = GSC_HauntingGround;
|
||||
map[CRC::HeavyMetalThunder] = GSC_HeavyMetalThunder;
|
||||
map[CRC::HummerBadlands] = GSC_HummerBadlands;
|
||||
map[CRC::ICO] = GSC_ICO;
|
||||
map[CRC::IkkiTousen] = GSC_IkkiTousen;
|
||||
map[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
|
||||
map[CRC::KnightsOfTheTemple2] = GSC_KnightsOfTheTemple2;
|
||||
map[CRC::Kunoichi] = GSC_Kunoichi;
|
||||
map[CRC::LordOfTheRingsThirdAge] = GSC_LordOfTheRingsThirdAge;
|
||||
|
@ -2499,12 +2509,9 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
map[CRC::ShadowofRome] = GSC_ShadowofRome;
|
||||
map[CRC::ShinOnimusha] = GSC_ShinOnimusha;
|
||||
map[CRC::Simple2000Vol114] = GSC_Simple2000Vol114;
|
||||
map[CRC::SkyGunner] = GSC_SkyGunner;
|
||||
map[CRC::SoulCalibur2] = GSC_SoulCalibur2;
|
||||
map[CRC::SoulCalibur3] = GSC_SoulCalibur3;
|
||||
map[CRC::Spartan] = GSC_Spartan;
|
||||
map[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
|
||||
map[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
|
||||
map[CRC::StarWarsForceUnleashed] = GSC_StarWarsForceUnleashed;
|
||||
map[CRC::SteambotChronicles] = GSC_SteambotChronicles;
|
||||
map[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
|
||||
|
@ -2515,7 +2522,6 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
map[CRC::TombRaiderAnniversary] = GSC_TombRaider;
|
||||
map[CRC::TombRaiderLegend] = GSC_TombRaiderLegend;
|
||||
map[CRC::TombRaiderUnderworld] = GSC_TombRaiderUnderWorld;
|
||||
map[CRC::TouristTrophy] = GSC_TouristTrophy;
|
||||
map[CRC::UltramanFightingEvolution] = GSC_UltramanFightingEvolution;
|
||||
map[CRC::UrbanReign] = GSC_UrbanReign;
|
||||
map[CRC::WildArms4] = GSC_WildArms4;
|
||||
|
@ -2536,9 +2542,11 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
|
||||
// Hack that were fixed on openGL
|
||||
if (Dx_only) {
|
||||
// Depth
|
||||
map[CRC::Bully] = GSC_Bully;
|
||||
map[CRC::BullyCC] = GSC_BullyCC;
|
||||
map[CRC::GodOfWar2] = GSC_GodOfWar2;
|
||||
map[CRC::ICO] = GSC_ICO;
|
||||
map[CRC::LordOfTheRingsTwoTowers] = GSC_LordOfTheRingsTwoTowers;
|
||||
map[CRC::Okami] = GSC_Okami;
|
||||
map[CRC::SimpsonsGame] = GSC_SimpsonsGame;
|
||||
|
@ -2560,9 +2568,6 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
map[CRC::TenchuFS] = GSC_Tenchu;
|
||||
map[CRC::TenchuWoH] = GSC_Tenchu;
|
||||
|
||||
// Basic Accurate blending + channel effect
|
||||
map[CRC::MetalGearSolid3] = GSC_MetalGearSolid3;
|
||||
|
||||
// Those games might requires accurate fbmask
|
||||
map[CRC::Sly2] = GSC_Sly2;
|
||||
map[CRC::Sly3] = GSC_Sly3;
|
||||
|
@ -2583,6 +2588,18 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
// At least a part of the CRC is fixed with texture shuffle.
|
||||
// The status of post-processing effect is unknown
|
||||
map[CRC::Black] = GSC_Black;
|
||||
|
||||
// Channel Effect
|
||||
map[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
|
||||
map[CRC::GT3] = GSC_GT3;
|
||||
map[CRC::GT4] = GSC_GT4;
|
||||
map[CRC::GTConcept] = GSC_GTConcept;
|
||||
map[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
|
||||
map[CRC::MetalGearSolid3] = GSC_MetalGearSolid3; // + accurate blending
|
||||
map[CRC::SkyGunner] = GSC_SkyGunner;
|
||||
map[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
|
||||
map[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
|
||||
map[CRC::TouristTrophy] = GSC_TouristTrophy;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,18 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
|
|||
|
||||
GSDeviceDX* dev = (GSDeviceDX*)m_dev;
|
||||
|
||||
// Channel shuffle effect not supported on DX. Let's keep the logic because it help to
|
||||
// reduce memory requirement (and why not a partial port)
|
||||
if (m_channel_shuffle) {
|
||||
if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MAXU & 0x8) == 8)) {
|
||||
;
|
||||
} else if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MINU & 0x8) == 0)) {
|
||||
;
|
||||
} else {
|
||||
m_channel_shuffle = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(DATE)
|
||||
{
|
||||
if(dev->HasStencil())
|
||||
|
|
|
@ -372,17 +372,26 @@ void GSRendererHW::Draw()
|
|||
(context->FRAME.FBP == context->ZBUF.ZBP && !PRIM->TME && !context->ZBUF.ZMSK && !context->FRAME.FBMSK && context->TEST.ZTE)
|
||||
);
|
||||
|
||||
if (PRIM->TME && m_context->FRAME.Block() == m_context->TEX0.TBP0 && (m_vt.m_primclass == GS_SPRITE_CLASS)) {
|
||||
// Special post-processing effect
|
||||
GSVector4 delta_p = m_vt.m_max.p - m_vt.m_min.p;
|
||||
const bool draw_sprite_tex = PRIM->TME && (m_vt.m_primclass == GS_SPRITE_CLASS);
|
||||
const GSVector4 delta_p = m_vt.m_max.p - m_vt.m_min.p;
|
||||
bool single_page = (delta_p.x <= 64.0f) && (delta_p.y <= 64.0f);
|
||||
|
||||
if (m_channel_shuffle) {
|
||||
m_channel_shuffle = draw_sprite_tex && (m_context->TEX0.PSM == PSM_PSMT8) && single_page;
|
||||
if (m_channel_shuffle) {
|
||||
GL_INS("Channel shuffle effect detected SKIP");
|
||||
GL_POP();
|
||||
s_n += 3; // Keep it sync with SW renderer
|
||||
return;
|
||||
}
|
||||
} else if (draw_sprite_tex && m_context->FRAME.Block() == m_context->TEX0.TBP0) {
|
||||
// Special post-processing effect
|
||||
if (m_vertex.next == 4) {
|
||||
// Note potentially we could also check the content of vertex (2nd
|
||||
// sprite must be half of the first one)
|
||||
GL_INS("Double downscale effect detected");
|
||||
m_double_downscale = true;
|
||||
} else if ((m_context->TEX0.PSM == PSM_PSMT8) && (delta_p.x <= 64.0f) && (delta_p.y <= 32.0f)) {
|
||||
//fprintf(stderr, "delta_p %f %f\n", delta_p.x, delta_p.y);
|
||||
} else if ((m_context->TEX0.PSM == PSM_PSMT8) && single_page) {
|
||||
if (m_channel_shuffle) {
|
||||
GL_INS("Channel shuffle effect detected SKIP");
|
||||
GL_POP();
|
||||
|
@ -465,10 +474,17 @@ void GSRendererHW::Draw()
|
|||
//
|
||||
// Both input and output are 16 bits and texture was initially 32 bits!
|
||||
m_texture_shuffle = (GSLocalMemory::m_psm[context->FRAME.PSM].bpp == 16) && (tex_psm.bpp == 16)
|
||||
&& (m_vt.m_primclass == GS_SPRITE_CLASS) && tex->m_32_bits_fmt;
|
||||
&& draw_sprite_tex && tex->m_32_bits_fmt;
|
||||
|
||||
// Texture shuffle is not yet supported with strange clamp mode
|
||||
ASSERT(!m_texture_shuffle || (context->CLAMP.WMS < 3 && context->CLAMP.WMT < 3));
|
||||
|
||||
if (tex->m_target && m_context->TEX0.PSM == PSM_PSMT8 && single_page && draw_sprite_tex) {
|
||||
GL_INS("Channel shuffle effect detected (2nd shot)");
|
||||
m_channel_shuffle = true;
|
||||
} else {
|
||||
m_channel_shuffle = false;
|
||||
}
|
||||
}
|
||||
if (rt) {
|
||||
// Be sure texture shuffle detection is properly propagated
|
||||
|
@ -578,7 +594,7 @@ void GSRendererHW::Draw()
|
|||
context->ZBUF.ZMSK = zm != 0;
|
||||
|
||||
// A couple of hack to avoid upscaling issue. So far it seems to impacts mostly sprite
|
||||
if ((m_upscale_multiplier > 1) && (m_vt.m_primclass == GS_SPRITE_CLASS)) {
|
||||
if ((m_upscale_multiplier > 1) && draw_sprite_tex) {
|
||||
size_t count = m_vertex.next;
|
||||
GSVertex* v = &m_vertex.buff[0];
|
||||
|
||||
|
|
|
@ -773,8 +773,12 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
// Pop
|
||||
GL_INS("Red channel");
|
||||
ps_sel.channel = 1;
|
||||
} else if ((tex->m_texture->GetType() == GSTexture::DepthStencil) && !(tex->m_32_bits_fmt)) {
|
||||
GL_INS("Urban Chaos Crazyness");
|
||||
ps_sel.urban_chaos_hack = 1;
|
||||
} else {
|
||||
GL_INS("channel not supported");
|
||||
m_channel_shuffle = false;
|
||||
ASSERT(0);
|
||||
}
|
||||
dev->PSSetShaderResource(4, tex->m_from_target);
|
||||
|
@ -981,10 +985,16 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
}
|
||||
|
||||
// Depth format
|
||||
if (psm.depth) {
|
||||
// Require a float conversion if the texure is a depth otherwise uses Integral scaling
|
||||
if (tex->m_texture->GetType() == GSTexture::DepthStencil) {
|
||||
// Require a float conversion if the texure is a depth format
|
||||
ps_sel.depth_fmt = (psm.bpp == 16) ? 2 : 1;
|
||||
|
||||
// Don't force interpolation on depth format
|
||||
bilinear &= m_vt.IsLinear();
|
||||
} else if (psm.depth) {
|
||||
// Use Integral scaling
|
||||
ps_sel.depth_fmt = (tex->m_texture->GetType() != GSTexture::DepthStencil) ? 3 :
|
||||
(psm.bpp == 16) ? 2 : 1;
|
||||
|
||||
// Don't force interpolation on depth format
|
||||
bilinear &= m_vt.IsLinear();
|
||||
}
|
||||
|
|
|
@ -85,12 +85,11 @@ void GSTextureCache::RemoveAll()
|
|||
}
|
||||
}
|
||||
|
||||
GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r)
|
||||
GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette)
|
||||
{
|
||||
if (!CanConvertDepth()) return NULL;
|
||||
|
||||
if(GSLocalMemory::m_psm[TEX0.PSM].pal > 0)
|
||||
m_renderer->m_mem.m_clut.Read32(TEX0, TEXA);
|
||||
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM];
|
||||
|
||||
Source* src = NULL;
|
||||
Target* dst = NULL;
|
||||
|
@ -98,6 +97,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
|
|||
// Check only current frame, I guess it is only used as a postprocessing effect
|
||||
uint32 bp = TEX0.TBP0;
|
||||
uint32 psm = TEX0.PSM;
|
||||
|
||||
for(auto t : m_dst[DepthStencil]) {
|
||||
if(!t->m_age && t->m_used && t->m_dirty.empty() && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM))
|
||||
{
|
||||
|
@ -122,23 +122,32 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
|
|||
if (dst) {
|
||||
GL_CACHE("TC depth: dst %s hit: %d (0x%x, F:0x%x)", to_string(dst->m_type),
|
||||
dst->m_texture ? dst->m_texture->GetID() : 0,
|
||||
TEX0.TBP0, TEX0.PSM);
|
||||
TEX0.TBP0, psm);
|
||||
|
||||
// Create a shared texture source
|
||||
src = new Source(m_renderer, TEX0, TEXA, m_temp, true);
|
||||
src->m_texture = dst->m_texture;
|
||||
src->m_shared_texture = true;
|
||||
src->m_target = true; // So renderer can check if a conversion is required
|
||||
src->m_from_target = dst->m_texture; // avoid complex condition on the renderer
|
||||
src->m_32_bits_fmt = dst->m_32_bits_fmt;
|
||||
|
||||
// Insert the texture in the hash set to keep track of it. But don't bother with
|
||||
// texture cache list. It means that a new Source is created everytime we need it.
|
||||
// If it is too expensive, one could cut memory allocation in Source constructor for this
|
||||
// use case.
|
||||
if (palette) {
|
||||
const uint32* clut = m_renderer->m_mem.m_clut;
|
||||
int size = psm_s.pal * sizeof(clut[0]);
|
||||
|
||||
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
|
||||
src->m_palette->Update(GSVector4i(0, 0, psm_s.pal, 1), clut, size);
|
||||
src->m_initpalette = false;
|
||||
}
|
||||
|
||||
m_src.m_surfaces.insert(src);
|
||||
} else {
|
||||
GL_CACHE("TC depth: ERROR miss (0x%x, F:0x%x)", TEX0.TBP0, TEX0.PSM);
|
||||
GL_CACHE("TC depth: ERROR miss (0x%x, F:0x%x)", TEX0.TBP0, psm);
|
||||
// Possible ? In this case we could call LookupSource
|
||||
// Or just put a basic texture
|
||||
// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
|
||||
|
@ -156,12 +165,12 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
|
|||
|
||||
GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r)
|
||||
{
|
||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
||||
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM];
|
||||
//const GSLocalMemory::psm_t& cpsm = psm.pal > 0 ? GSLocalMemory::m_psm[TEX0.CPSM] : psm;
|
||||
|
||||
// Until DX is fixed
|
||||
if (s_IS_OPENGL) {
|
||||
if(psm.pal > 0)
|
||||
if(psm_s.pal > 0)
|
||||
m_renderer->m_mem.m_clut.Read32(TEX0, TEXA);
|
||||
} else {
|
||||
GIFRegTEXA plainTEXA;
|
||||
|
@ -188,16 +197,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
// Target are converted (AEM & palette) on the fly by the GPU. They don't need extra check
|
||||
if (!s->m_target) {
|
||||
// We request a palette texture (psm.pal). If the texture was
|
||||
// We request a palette texture (psm_s.pal). If the texture was
|
||||
// converted by the CPU (s->m_palette == NULL), we need to ensure
|
||||
// palette content is the same.
|
||||
// Note: content of the palette will be uploaded at the end of the function
|
||||
if (psm.pal > 0 && s->m_palette == NULL && !GSVector4i::compare64(clut, s->m_clut, psm.pal * sizeof(clut[0])))
|
||||
if (psm_s.pal > 0 && s->m_palette == NULL && !GSVector4i::compare64(clut, s->m_clut, psm_s.pal * sizeof(clut[0])))
|
||||
continue;
|
||||
|
||||
// We request a 24/16 bit RGBA texture. Alpha expansion was done by
|
||||
// the CPU. We need to check that TEXA is identical
|
||||
if (psm.pal == 0 && psm.fmt > 0 && s->m_TEXA.u64 != TEXA.u64)
|
||||
if (psm_s.pal == 0 && psm_s.fmt > 0 && s->m_TEXA.u64 != TEXA.u64)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -295,14 +304,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
if(!t->m_age && t->m_used && t->m_dirty.empty() && GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM))
|
||||
{
|
||||
GL_INS("TC: Warning depth format read as color format. Pixels will be scrambled");
|
||||
//dst = t;
|
||||
//break;
|
||||
// Let's fetch a depth format texture. Rational, it will avoid the texture allocation and the
|
||||
// rescaling of the current function.
|
||||
GIFRegTEX0 depth_TEX0;
|
||||
depth_TEX0.u32[0] = TEX0.u32[0] | (0x30u << 20u);
|
||||
depth_TEX0.u32[1] = TEX0.u32[1];
|
||||
return LookupDepthSource(depth_TEX0, TEXA, r);
|
||||
if (psm_s.bpp > 8) {
|
||||
GIFRegTEX0 depth_TEX0;
|
||||
depth_TEX0.u32[0] = TEX0.u32[0] | (0x30u << 20u);
|
||||
depth_TEX0.u32[1] = TEX0.u32[1];
|
||||
return LookupDepthSource(depth_TEX0, TEXA, r);
|
||||
} else {
|
||||
return LookupDepthSource(TEX0, TEXA, r, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,11 +345,11 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
|
||||
if (src->m_palette)
|
||||
{
|
||||
int size = psm.pal * sizeof(clut[0]);
|
||||
int size = psm_s.pal * sizeof(clut[0]);
|
||||
|
||||
if(src->m_initpalette || !GSVector4i::update(src->m_clut, clut, size))
|
||||
{
|
||||
src->m_palette->Update(GSVector4i(0, 0, psm.pal, 1), src->m_clut, size);
|
||||
src->m_palette->Update(GSVector4i(0, 0, psm_s.pal, 1), src->m_clut, size);
|
||||
src->m_initpalette = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ public:
|
|||
void RemovePartial();
|
||||
|
||||
Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r);
|
||||
Source* LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r);
|
||||
Source* LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette = false);
|
||||
|
||||
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used);
|
||||
Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int real_h);
|
||||
|
|
|
@ -225,7 +225,21 @@ vec4 sample_depth(vec2 st)
|
|||
ivec2 uv = ivec2(uv_f);
|
||||
|
||||
vec4 t;
|
||||
#if PS_DEPTH_FMT == 1
|
||||
#if PS_URBAN_CHAOS_HACK == 1
|
||||
// Convert a GL_FLOAT32 to a special color format expected by the game
|
||||
int depth = int(fetch_c(uv).r * exp2(32.0f));
|
||||
|
||||
// Convert lsb based on the palette
|
||||
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);
|
||||
|
||||
// Msb is easier
|
||||
float green = float((depth >> 8) & 0xFF) * 36.0f;
|
||||
green = min(green, 255.0f);
|
||||
|
||||
t.g += green;
|
||||
|
||||
|
||||
#elif PS_DEPTH_FMT == 1
|
||||
// Based on ps_main11 of convert
|
||||
|
||||
// Convert a GL_FLOAT32 depth texture into a RGBA color texture
|
||||
|
@ -252,6 +266,7 @@ vec4 sample_depth(vec2 st)
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
// warning t ranges from 0 to 255
|
||||
#if (PS_AEM_FMT == FMT_24)
|
||||
t.a = ( (PS_AEM == 0) || any(bvec3(t.rgb)) ) ? 255.0f * TA.x : 0.0f;
|
||||
|
@ -266,27 +281,47 @@ vec4 sample_depth(vec2 st)
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// Fetch a Single Channel
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int fetch_raw_depth()
|
||||
{
|
||||
return int(texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));
|
||||
}
|
||||
|
||||
vec4 fetch_raw_color()
|
||||
{
|
||||
return texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
}
|
||||
|
||||
vec4 fetch_red()
|
||||
{
|
||||
vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth()) & 0xFF;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
#endif
|
||||
return sample_p(rt.r) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_blue()
|
||||
{
|
||||
vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2
|
||||
int depth = (fetch_raw_depth() >> 16) & 0xFF;
|
||||
vec4 rt = vec4(depth) / 255.0f;
|
||||
#else
|
||||
vec4 rt = fetch_raw_color();
|
||||
#endif
|
||||
return sample_p(rt.b) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_green()
|
||||
{
|
||||
vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
vec4 rt = fetch_raw_color();
|
||||
return sample_p(rt.g) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_alpha()
|
||||
{
|
||||
vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);
|
||||
vec4 rt = fetch_raw_color();
|
||||
return sample_p(rt.a) * 255.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -1069,7 +1069,21 @@ static const char* const tfx_fs_all_glsl =
|
|||
" ivec2 uv = ivec2(uv_f);\n"
|
||||
"\n"
|
||||
" vec4 t;\n"
|
||||
"#if PS_DEPTH_FMT == 1\n"
|
||||
"#if PS_URBAN_CHAOS_HACK == 1\n"
|
||||
" // Convert a GL_FLOAT32 to a special color format expected by the game\n"
|
||||
" int depth = int(fetch_c(uv).r * exp2(32.0f));\n"
|
||||
"\n"
|
||||
" // Convert lsb based on the palette\n"
|
||||
" t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);\n"
|
||||
"\n"
|
||||
" // Msb is easier\n"
|
||||
" float green = float((depth >> 8) & 0xFF) * 36.0f;\n"
|
||||
" green = min(green, 255.0f);\n"
|
||||
"\n"
|
||||
" t.g += green;\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"#elif PS_DEPTH_FMT == 1\n"
|
||||
" // Based on ps_main11 of convert\n"
|
||||
"\n"
|
||||
" // Convert a GL_FLOAT32 depth texture into a RGBA color texture\n"
|
||||
|
@ -1096,6 +1110,7 @@ static const char* const tfx_fs_all_glsl =
|
|||
"\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" // warning t ranges from 0 to 255\n"
|
||||
"#if (PS_AEM_FMT == FMT_24)\n"
|
||||
" t.a = ( (PS_AEM == 0) || any(bvec3(t.rgb)) ) ? 255.0f * TA.x : 0.0f;\n"
|
||||
|
@ -1110,27 +1125,47 @@ static const char* const tfx_fs_all_glsl =
|
|||
"//////////////////////////////////////////////////////////////////////\n"
|
||||
"// Fetch a Single Channel\n"
|
||||
"//////////////////////////////////////////////////////////////////////\n"
|
||||
"int fetch_raw_depth()\n"
|
||||
"{\n"
|
||||
" return int(texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0).r * exp2(32.0f));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_raw_color()\n"
|
||||
"{\n"
|
||||
" return texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_red()\n"
|
||||
"{\n"
|
||||
" vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);\n"
|
||||
"#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2\n"
|
||||
" int depth = (fetch_raw_depth()) & 0xFF;\n"
|
||||
" vec4 rt = vec4(depth) / 255.0f;\n"
|
||||
"#else\n"
|
||||
" vec4 rt = fetch_raw_color();\n"
|
||||
"#endif\n"
|
||||
" return sample_p(rt.r) * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_blue()\n"
|
||||
"{\n"
|
||||
" vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);\n"
|
||||
"#if PS_DEPTH_FMT == 1 || PS_DEPTH_FMT == 2\n"
|
||||
" int depth = (fetch_raw_depth() >> 16) & 0xFF;\n"
|
||||
" vec4 rt = vec4(depth) / 255.0f;\n"
|
||||
"#else\n"
|
||||
" vec4 rt = fetch_raw_color();\n"
|
||||
"#endif\n"
|
||||
" return sample_p(rt.b) * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_green()\n"
|
||||
"{\n"
|
||||
" vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);\n"
|
||||
" vec4 rt = fetch_raw_color();\n"
|
||||
" return sample_p(rt.g) * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_alpha()\n"
|
||||
"{\n"
|
||||
" vec4 rt = texelFetch(RawTextureSampler, ivec2(gl_FragCoord.xy), 0);\n"
|
||||
" vec4 rt = fetch_raw_color();\n"
|
||||
" return sample_p(rt.a) * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
|
Loading…
Reference in New Issue