[PICA] Implement A4 textures

This commit is contained in:
wheremyfoodat 2023-03-06 21:07:10 +02:00
parent 922424b8d0
commit 820b8a37b6
2 changed files with 21 additions and 0 deletions

View file

@ -65,6 +65,7 @@ struct Texture {
static u32 mortonInterleave(u32 u, u32 v);
// Get the byte offset of texel (u, v) in the texture
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
// TODO: Make hasAlpha a template parameter

View file

@ -80,6 +80,14 @@ u32 Texture::getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel) {
return offset * bytesPerPixel;
}
// Same as the above code except we need to divide by 2 because 4 bits is smaller than a byte
u32 Texture::getSwizzledOffset_4bpp(u32 u, u32 v, u32 width) {
u32 offset = ((u & ~7) * 8) + ((v & ~7) * width); // Offset of the 8x8 tile the texel belongs to
offset += mortonInterleave(u, v); // Add the in-tile offset of the texel
return offset / 2;
}
// Get the texel at position (u, v)
// fmt: format of the texture
// data: texture data of the texture
@ -147,6 +155,18 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity;
}
case Formats::A4: {
u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
auto ptr = static_cast<const u8*>(data);
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 alpha = ptr[offset] >> ((u % 2) ? 4 : 0);
alpha = Colour::convert4To8Bit(alpha & 0xf);
// A8 sets RGB to 0
return (alpha << 24) | (0 << 16) | (0 << 8) | 0;
}
case Formats::A8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
auto ptr = static_cast<const u8*>(data);