summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureDecoder_Common.cpp
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2017-05-29 17:02:09 -0500
committeriwubcode <iwubcode@users.noreply.github.com>2017-11-17 19:47:56 -0600
commit79387dddb24ddf035b70cd9379a42368dcd49e93 (patch)
tree7b783c46e1ffd052842f11112f58c61993f0af1b /Source/Core/VideoCommon/TextureDecoder_Common.cpp
parent84ca9a4aec0048e5ac01caea8f8be9210eb947f6 (diff)
Add support for hybrid XFB
Diffstat (limited to 'Source/Core/VideoCommon/TextureDecoder_Common.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureDecoder_Common.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/Source/Core/VideoCommon/TextureDecoder_Common.cpp b/Source/Core/VideoCommon/TextureDecoder_Common.cpp
index 52debad57b..90be3d8dc7 100644
--- a/Source/Core/VideoCommon/TextureDecoder_Common.cpp
+++ b/Source/Core/VideoCommon/TextureDecoder_Common.cpp
@@ -3,9 +3,11 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <cstddef>
#include <cmath>
#include "Common/CommonTypes.h"
+#include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Common/Swap.h"
@@ -46,6 +48,9 @@ int TexDecoder_GetTexelSizeInNibbles(TextureFormat format)
// Compressed format
case TextureFormat::CMPR:
return 1;
+ // Special formats
+ case TextureFormat::XFB:
+ return 4;
default:
PanicAlert("Invalid Texture Format (0x%X)! (GetTexelSizeInNibbles)", static_cast<int>(format));
return 1;
@@ -82,6 +87,9 @@ int TexDecoder_GetBlockWidthInTexels(TextureFormat format)
// Compressed format
case TextureFormat::CMPR:
return 8;
+ // Special formats
+ case TextureFormat::XFB:
+ return 16;
default:
PanicAlert("Invalid Texture Format (0x%X)! (GetBlockWidthInTexels)", static_cast<int>(format));
return 8;
@@ -113,6 +121,9 @@ int TexDecoder_GetBlockHeightInTexels(TextureFormat format)
// Compressed format
case TextureFormat::CMPR:
return 8;
+ // Special formats
+ case TextureFormat::XFB:
+ return 1;
default:
PanicAlert("Invalid Texture Format (0x%X)! (GetBlockHeightInTexels)", static_cast<int>(format));
return 4;
@@ -144,6 +155,9 @@ int TexDecoder_GetEFBCopyBlockWidthInTexels(EFBCopyFormat format)
// 32-bit formats
case EFBCopyFormat::RGBA8:
return 4;
+ // Special formats
+ case EFBCopyFormat::XFB:
+ return 16;
default:
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBlockWidthInTexels)",
static_cast<int>(format));
@@ -176,6 +190,9 @@ int TexDecoder_GetEFBCopyBlockHeightInTexels(EFBCopyFormat format)
// 32-bit formats
case EFBCopyFormat::RGBA8:
return 4;
+ // Special formats
+ case EFBCopyFormat::XFB:
+ return 1;
default:
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBlockHeightInTexels)",
static_cast<int>(format));
@@ -226,6 +243,8 @@ TextureFormat TexDecoder_GetEFBCopyBaseFormat(EFBCopyFormat format)
return TextureFormat::RGB5A3;
case EFBCopyFormat::RGBA8:
return TextureFormat::RGBA8;
+ case EFBCopyFormat::XFB:
+ return TextureFormat::XFB;
default:
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBaseFormat)", static_cast<int>(format));
return static_cast<TextureFormat>(format);
@@ -247,7 +266,7 @@ static const char* texfmt[] = {
"0x1C", "0x1D", "0x1E", "0x1F",
// pixel + copy
"CR4", "0x21", "CRA4", "CRA8", "0x24", "0x25", "CYUVA8", "CA8", "CR8", "CG8", "CB8", "CRG8",
- "CGB8", "0x2D", "0x2E", "0x2F",
+ "CGB8", "0x2D", "0x2E", "XFB",
// Z + copy
"CZ4", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", "0x38", "CZ8M", "CZ8L", "0x3B",
"CZ16L", "0x3D", "0x3E", "0x3F",
@@ -619,6 +638,24 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = color;
}
break;
+ case TextureFormat::XFB:
+ {
+ // TODO: I should kind of like... ACTUALLY TEST THIS!!!!!
+ size_t offset = (t * imageWidth + (s & (~1))) * 2;
+
+ // We do this one color sample (aka 2 RGB pixles) at a time
+ int Y = int((s & 1) == 0 ? src[offset] : src[offset + 2]) - 16;
+ int U = int(src[offset + 1]) - 128;
+ int V = int(src[offset + 3]) - 128;
+
+ // We do the inverse BT.601 conversion for YCbCr to RGB
+ // http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion
+ u8 R = MathUtil::Clamp(int(1.164f * Y + 1.596f * V), 0, 255);
+ u8 G = MathUtil::Clamp(int(1.164f * Y - 0.392f * U - 0.813f * V), 0, 255);
+ u8 B = MathUtil::Clamp(int(1.164f * Y + 2.017f * U), 0, 255);
+ dst[t * imageWidth + s] = 0xff000000 | B << 16 | G << 8 | R;
+ }
+ break;
}
}