mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #1349 from PCSX2/gsdx-channel-effect
Gsdx channel effect
This commit is contained in:
commit
5ecbc2889b
|
@ -534,6 +534,7 @@ bool IsCrcExcluded(string exclusionList, uint32 crc)
|
|||
|
||||
CRC::Game CRC::Lookup(uint32 crc)
|
||||
{
|
||||
printf("GSdx Lookup CRC:%X\n", crc);
|
||||
if(m_map.empty())
|
||||
{
|
||||
string exclusions = theApp.GetConfig( "CrcHacksExclusions", "" );
|
||||
|
@ -549,7 +550,7 @@ CRC::Game CRC::Lookup(uint32 crc)
|
|||
, m_games[i].crc, m_games[i].title, m_games[i].region, m_map[m_games[i].crc]->title, m_map[m_games[i].crc]->region);
|
||||
crcDups++;
|
||||
}
|
||||
|
||||
|
||||
m_map[m_games[i].crc] = &m_games[i];
|
||||
}
|
||||
//else
|
||||
|
|
|
@ -767,7 +767,8 @@ 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_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
|
||||
+ format("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
|
||||
+ 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,9 +289,10 @@ class GSDeviceOGL final : public GSDevice
|
|||
|
||||
// Hack
|
||||
uint32 tcoffsethack:1;
|
||||
uint32 urban_chaos_hack:1;
|
||||
uint32 urban_chaos_hle:1;
|
||||
uint32 tales_of_abyss_hle:1;
|
||||
|
||||
uint32 _free2:15;
|
||||
uint32 _free2:14;
|
||||
};
|
||||
|
||||
uint64 key;
|
||||
|
|
|
@ -295,31 +295,6 @@ bool GSC_AceCombat4(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSC_Tekken5(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP == 0x02d60 || fi.FBP == 0x02d80 || fi.FBP == 0x02ea0 || fi.FBP == 0x03620) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 95;
|
||||
}
|
||||
else if(fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 2;
|
||||
}
|
||||
else if(fi.TME)
|
||||
{
|
||||
if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
|
||||
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) )
|
||||
{
|
||||
skip = 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -354,30 +329,6 @@ bool GSC_Onimusha3(const GSFrameInfo& fi, int& skip)
|
|||
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 == PSM_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 == PSM_PSMCT32)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fi.TME && fi.TPSM != PSM_PSMT8)
|
||||
{
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
|
@ -1358,6 +1309,56 @@ bool GSC_SteambotChronicles(const GSFrameInfo& fi, int& skip)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Correctly emulated on OpenGL but can be used as potential speed hack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 == PSM_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 == PSM_PSMCT32)
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fi.TME && fi.TPSM != PSM_PSMT8)
|
||||
{
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_Tekken5(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && (fi.FBP == 0x02d60 || fi.FBP == 0x02d80 || fi.FBP == 0x02ea0 || fi.FBP == 0x03620) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 95;
|
||||
}
|
||||
else if(fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
|
||||
{
|
||||
skip = 2;
|
||||
}
|
||||
else if(fi.TME)
|
||||
{
|
||||
if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
|
||||
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) )
|
||||
{
|
||||
skip = 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_DeathByDegreesTekkenNinaWilliams(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -2491,10 +2492,8 @@ void GSState::SetupCrcHack()
|
|||
lut[CRC::Spartan] = GSC_Spartan;
|
||||
lut[CRC::StarWarsForceUnleashed] = GSC_StarWarsForceUnleashed;
|
||||
lut[CRC::SteambotChronicles] = GSC_SteambotChronicles;
|
||||
lut[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
|
||||
lut[CRC::TalesOfLegendia] = GSC_TalesOfLegendia;
|
||||
lut[CRC::TalesofSymphonia] = GSC_TalesofSymphonia;
|
||||
lut[CRC::Tekken5] = GSC_Tekken5;
|
||||
lut[CRC::TimeSplitters2] = GSC_TimeSplitters2;
|
||||
lut[CRC::TombRaiderAnniversary] = GSC_TombRaider;
|
||||
lut[CRC::TombRaiderLegend] = GSC_TombRaiderLegend;
|
||||
|
@ -2567,15 +2566,18 @@ void GSState::SetupCrcHack()
|
|||
|
||||
// Channel Effect
|
||||
lut[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
|
||||
lut[CRC::GT3] = GSC_GT3;
|
||||
lut[CRC::GT4] = GSC_GT4;
|
||||
lut[CRC::GTConcept] = GSC_GTConcept;
|
||||
lut[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
|
||||
lut[CRC::MetalGearSolid3] = GSC_MetalGearSolid3; // + accurate blending
|
||||
lut[CRC::SkyGunner] = GSC_SkyGunner;
|
||||
lut[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
|
||||
lut[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
|
||||
// Dedicated shader for channel effect
|
||||
lut[CRC::TouristTrophy] = GSC_TouristTrophy;
|
||||
lut[CRC::GT3] = GSC_GT3;
|
||||
lut[CRC::GT4] = GSC_GT4;
|
||||
lut[CRC::GTConcept] = GSC_GTConcept;
|
||||
lut[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
|
||||
lut[CRC::Tekken5] = GSC_Tekken5;
|
||||
}
|
||||
|
||||
m_gsc = lut[m_game.title];
|
||||
|
|
|
@ -673,7 +673,41 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
|
|||
//
|
||||
// First let's check we really have a channel shuffle effect
|
||||
if (m_channel_shuffle) {
|
||||
if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MAXU & 0x8) == 8)) {
|
||||
if (m_game.title == CRC::GT4 || m_game.title == CRC::GT3 || m_game.title == CRC::GTConcept || m_game.title == CRC::TouristTrophy) {
|
||||
GL_INS("Gran Turismo RGB Channel");
|
||||
ps_sel.channel = 7;
|
||||
m_context->TEX0.TFX = TFX_DECAL;
|
||||
rt = tex->m_from_target;
|
||||
} else if (m_game.title == CRC::Tekken5) {
|
||||
GL_INS("Tekken5 RGB Channel");
|
||||
ps_sel.channel = 7;
|
||||
m_context->FRAME.FBMSK = 0xFF000000;
|
||||
// 12 pages: 2 calls by channel, 3 channels, 1 blit
|
||||
// Minus current draw call
|
||||
m_skip = 12 * (3 + 3 + 1) - 1;
|
||||
rt = tex->m_from_target;
|
||||
} else if ((tex->m_texture->GetType() == GSTexture::DepthStencil) && !(tex->m_32_bits_fmt)) {
|
||||
// So far 2 games hit this code path. Urban Chaos and Tales of Abyss
|
||||
// UC: will copy depth to green channel
|
||||
// ToA: will copy depth to alpha channel
|
||||
if ((m_context->FRAME.FBMSK & 0xFF0000) == 0xFF0000) {
|
||||
// Green channel is masked
|
||||
GL_INS("Tales Of Abyss Crazyness (MSB 16b depth to Alpha)");
|
||||
ps_sel.tales_of_abyss_hle = 1;
|
||||
} else {
|
||||
GL_INS("Urban Chaos Crazyness (Green extraction)");
|
||||
ps_sel.urban_chaos_hle = 1;
|
||||
}
|
||||
} else if (m_index.tail <= 64 && m_context->CLAMP.WMT == 3) {
|
||||
// Blood will tell. I think it is channel effect too but again
|
||||
// implemented in a different way. I don't want to add more CRC stuff. So
|
||||
// let's disable channel when the signature is different
|
||||
//
|
||||
// Note: Tales Of Abyss and Tekken5 could hit this path too. Those games are
|
||||
// handled above.
|
||||
GL_INS("maybe not a channel!");
|
||||
m_channel_shuffle = false;
|
||||
} else if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MAXU & 0x8) == 8)) {
|
||||
// Read either blue or Alpha. Let's go for Blue ;)
|
||||
// MGS3/Kill Zone
|
||||
GL_INS("Blue channel");
|
||||
|
@ -683,9 +717,6 @@ 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;
|
||||
|
|
|
@ -235,7 +235,14 @@ vec4 sample_depth(vec2 st)
|
|||
ivec2 uv = ivec2(uv_f);
|
||||
|
||||
vec4 t;
|
||||
#if PS_URBAN_CHAOS_HACK == 1
|
||||
#if PS_TALES_OF_ABYSS_HLE == 1
|
||||
// Warning: UV can't be used in channel effect
|
||||
int depth = fetch_raw_depth();
|
||||
|
||||
// Convert msb based on the palette
|
||||
t = texelFetch(PaletteSampler, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;
|
||||
|
||||
#elif PS_URBAN_CHAOS_HLE == 1
|
||||
// Depth buffer is read as a RGB5A1 texture. The game try to extract the green channel.
|
||||
// So it will do a first channel trick to extract lsb, value is right-shifted.
|
||||
// Then a new channel trick to extract msb which will shifted to the left.
|
||||
|
@ -246,7 +253,7 @@ vec4 sample_depth(vec2 st)
|
|||
int depth = fetch_raw_depth();
|
||||
|
||||
// Convert lsb based on the palette
|
||||
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);
|
||||
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0) * 255.0f;
|
||||
|
||||
// Msb is easier
|
||||
float green = float((depth >> 8) & 0xFF) * 36.0f;
|
||||
|
@ -331,6 +338,13 @@ vec4 fetch_alpha()
|
|||
return sample_p(rt.a) * 255.0f;
|
||||
}
|
||||
|
||||
vec4 fetch_rgb()
|
||||
{
|
||||
vec4 rt = fetch_raw_color();
|
||||
vec4 c = vec4(sample_p(rt.r).r, sample_p(rt.g).g, sample_p(rt.b).b, 1.0f);
|
||||
return c * 255.0f;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
vec4 sample_color(vec2 st)
|
||||
|
@ -500,6 +514,8 @@ vec4 ps_color()
|
|||
vec4 T = fetch_blue();
|
||||
#elif PS_CHANNEL_FETCH == 4
|
||||
vec4 T = fetch_alpha();
|
||||
#elif PS_CHANNEL_FETCH == 7
|
||||
vec4 T = fetch_rgb();
|
||||
#elif PS_DEPTH_FMT > 0
|
||||
// Integral coordinate
|
||||
vec4 T = sample_depth(PSin.t_int.zw);
|
||||
|
|
|
@ -1079,7 +1079,14 @@ static const char* const tfx_fs_all_glsl =
|
|||
" ivec2 uv = ivec2(uv_f);\n"
|
||||
"\n"
|
||||
" vec4 t;\n"
|
||||
"#if PS_URBAN_CHAOS_HACK == 1\n"
|
||||
"#if PS_TALES_OF_ABYSS_HLE == 1\n"
|
||||
" // Warning: UV can't be used in channel effect\n"
|
||||
" int depth = fetch_raw_depth();\n"
|
||||
"\n"
|
||||
" // Convert msb based on the palette\n"
|
||||
" t = texelFetch(PaletteSampler, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;\n"
|
||||
"\n"
|
||||
"#elif PS_URBAN_CHAOS_HLE == 1\n"
|
||||
" // Depth buffer is read as a RGB5A1 texture. The game try to extract the green channel.\n"
|
||||
" // So it will do a first channel trick to extract lsb, value is right-shifted.\n"
|
||||
" // Then a new channel trick to extract msb which will shifted to the left.\n"
|
||||
|
@ -1090,7 +1097,7 @@ static const char* const tfx_fs_all_glsl =
|
|||
" int depth = fetch_raw_depth();\n"
|
||||
"\n"
|
||||
" // Convert lsb based on the palette\n"
|
||||
" t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);\n"
|
||||
" t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0) * 255.0f;\n"
|
||||
"\n"
|
||||
" // Msb is easier\n"
|
||||
" float green = float((depth >> 8) & 0xFF) * 36.0f;\n"
|
||||
|
@ -1175,6 +1182,13 @@ static const char* const tfx_fs_all_glsl =
|
|||
" return sample_p(rt.a) * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"vec4 fetch_rgb()\n"
|
||||
"{\n"
|
||||
" vec4 rt = fetch_raw_color();\n"
|
||||
" vec4 c = vec4(sample_p(rt.r).r, sample_p(rt.g).g, sample_p(rt.b).b, 1.0f);\n"
|
||||
" return c * 255.0f;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"//////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"vec4 sample_color(vec2 st)\n"
|
||||
|
@ -1344,6 +1358,8 @@ static const char* const tfx_fs_all_glsl =
|
|||
" vec4 T = fetch_blue();\n"
|
||||
"#elif PS_CHANNEL_FETCH == 4\n"
|
||||
" vec4 T = fetch_alpha();\n"
|
||||
"#elif PS_CHANNEL_FETCH == 7\n"
|
||||
" vec4 T = fetch_rgb();\n"
|
||||
"#elif PS_DEPTH_FMT > 0\n"
|
||||
" // Integral coordinate\n"
|
||||
" vec4 T = sample_depth(PSin.t_int.zw);\n"
|
||||
|
|
Loading…
Reference in New Issue