From 820b8a37b610d4e4821a536f02ae2647d0fbe8e8 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Mon, 6 Mar 2023 21:07:10 +0200 Subject: [PATCH] [PICA] Implement A4 textures --- include/renderer_gl/textures.hpp | 1 + src/core/renderer_gl/textures.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/renderer_gl/textures.hpp b/include/renderer_gl/textures.hpp index 2deaf33f..3abdece1 100644 --- a/include/renderer_gl/textures.hpp +++ b/include/renderer_gl/textures.hpp @@ -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 diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index 1e02f574..a48bf602 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -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(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(data);