diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index d6723a7860..dafcae0237 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -720,17 +720,45 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour GL_INS("Blue channel"); ps_sel.channel = 3; } else if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MINU & 0x8) == 0)) { - // Read either Red or Green. Let's go for Red ;) - // Pop - if (m_context->FRAME.FBMSK == 0xF0FFFFFF) { - GL_INS("Terminator 3 G4B4 Channel"); - ps_sel.channel = 6; - m_context->FRAME.FBMSK = 0x00FFFFFF; - } else if (m_context->FRAME.FBMSK == 0x80FFFFFF) {; - GL_INS("Terminator 3 G7B1 Channel"); - ps_sel.channel = 5; - m_context->FRAME.FBMSK = 0x00FFFFFF; + // Read either Red or Green. Let's check the V coordinate. 0-1 is likely top so + // red. 2-3 is likely bottom so green (actually depends on texture base pointer offset) + bool green = PRIM->FST && (m_vertex.buff[0].V & 32); + if (green && (m_context->FRAME.FBMSK & 0x00FFFFFF) == 0x00FFFFFF) { + // Typically used in Terminator 3 + int blue_mask = m_context->FRAME.FBMSK >> 24; + int green_mask = ~blue_mask & 0xFF; + int blue_shift = -1; + + // Note: potentially we could also check the value of the clut + switch (m_context->FRAME.FBMSK >> 24) { + case 0xFF: ASSERT(0); break; + case 0xFE: blue_shift = 1; break; + case 0xFC: blue_shift = 2; break; + case 0xF8: blue_shift = 3; break; + case 0xF0: blue_shift = 4; break; + case 0xE0: blue_shift = 5; break; + case 0xC0: blue_shift = 6; break; + case 0x80: blue_shift = 7; break; + default: ASSERT(0); break; + } + + int green_shift = 8 - blue_shift; + dev->SetupCBMisc(GSVector4i(blue_mask, blue_shift, green_mask, green_shift)); + + if (blue_shift >= 0) { + GL_INS("Green/Blue channel (%d, %d)", blue_shift, green_shift); + ps_sel.channel = 6; + m_context->FRAME.FBMSK = 0x00FFFFFF; + } else { + GL_INS("Green channel (wrong mask) (fbmask %x)", m_context->FRAME.FBMSK >> 24); + ps_sel.channel = 2; + } + + } else if (green) { + GL_INS("Green channel"); + ps_sel.channel = 2; } else { + // Pop GL_INS("Red channel"); ps_sel.channel = 1; } diff --git a/plugins/GSdx/res/glsl/tfx_fs.glsl b/plugins/GSdx/res/glsl/tfx_fs.glsl index 85eb3110b8..59a9c4a648 100644 --- a/plugins/GSdx/res/glsl/tfx_fs.glsl +++ b/plugins/GSdx/res/glsl/tfx_fs.glsl @@ -345,20 +345,12 @@ vec4 fetch_rgb() return c * 255.0f; } -vec4 fetch_g7b1() +vec4 fetch_gXbY() { - vec4 rt = fetch_raw_color() * 255.0f; - uint g7 = (uint(rt.g) >> 1u) & 0x7Fu; - uint b1 = (uint(rt.b) << 7u) & 0x80u; - return vec4(float(g7 | b1)); -} - -vec4 fetch_g4b4() -{ - vec4 rt = fetch_raw_color() * 255.0f; - uint g4 = (uint(rt.g) >> 4u) & 0x0Fu; - uint b4 = (uint(rt.b) << 4u) & 0xF0u; - return vec4(float(g4 | b4)); + ivec4 rt = ivec4(fetch_raw_color() * 255.0f); + int green = (rt.g >> ChannelShuffle.w) & ChannelShuffle.z; + int blue = (rt.b << ChannelShuffle.y) & ChannelShuffle.x; + return vec4(green | blue); } ////////////////////////////////////////////////////////////////////// @@ -530,10 +522,8 @@ vec4 ps_color() vec4 T = fetch_blue(); #elif PS_CHANNEL_FETCH == 4 vec4 T = fetch_alpha(); -#elif PS_CHANNEL_FETCH == 5 - vec4 T = fetch_g7b1(); #elif PS_CHANNEL_FETCH == 6 - vec4 T = fetch_g4b4(); + vec4 T = fetch_gXbY(); #elif PS_CHANNEL_FETCH == 7 vec4 T = fetch_rgb(); #elif PS_DEPTH_FMT > 0 diff --git a/plugins/GSdx/res/glsl_source.h b/plugins/GSdx/res/glsl_source.h index 9e52876b2c..c9404a166f 100644 --- a/plugins/GSdx/res/glsl_source.h +++ b/plugins/GSdx/res/glsl_source.h @@ -1190,20 +1190,12 @@ static const char* const tfx_fs_all_glsl = " return c * 255.0f;\n" "}\n" "\n" - "vec4 fetch_g7b1()\n" + "vec4 fetch_gXbY()\n" "{\n" - " vec4 rt = fetch_raw_color() * 255.0f;\n" - " uint g7 = (uint(rt.g) >> 1u) & 0x7Fu;\n" - " uint b1 = (uint(rt.b) << 7u) & 0x80u;\n" - " return vec4(float(g7 | b1));\n" - "}\n" - "\n" - "vec4 fetch_g4b4()\n" - "{\n" - " vec4 rt = fetch_raw_color() * 255.0f;\n" - " uint g4 = (uint(rt.g) >> 4u) & 0x0Fu;\n" - " uint b4 = (uint(rt.b) << 4u) & 0xF0u;\n" - " return vec4(float(g4 | b4));\n" + " ivec4 rt = ivec4(fetch_raw_color() * 255.0f);\n" + " int green = (rt.g >> ChannelShuffle.w) & ChannelShuffle.z;\n" + " int blue = (rt.b << ChannelShuffle.y) & ChannelShuffle.x;\n" + " return vec4(green | blue);\n" "}\n" "\n" "//////////////////////////////////////////////////////////////////////\n" @@ -1375,10 +1367,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 == 5\n" - " vec4 T = fetch_g7b1();\n" "#elif PS_CHANNEL_FETCH == 6\n" - " vec4 T = fetch_g4b4();\n" + " vec4 T = fetch_gXbY();\n" "#elif PS_CHANNEL_FETCH == 7\n" " vec4 T = fetch_rgb();\n" "#elif PS_DEPTH_FMT > 0\n"