diff --git a/include/helpers.hpp b/include/helpers.hpp index 9830cc88..4162309e 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -113,9 +113,16 @@ namespace Helpers { } /// Extract bits from an integer-type - template - static constexpr T getBits(T value) { - return (value >> offset) & ones(); + template + static constexpr ReturnT getBits(ValueT value) { + static_assert((offset + bits) <= (CHAR_BIT * sizeof(ValueT)), "Invalid bit range"); + static_assert(bits > 0, "Invalid bit size"); + return ReturnT(ValueT(value >> offset) & ones()); + } + + template + static constexpr ValueT getBits(ValueT value) { + return getBits(value); } #ifdef HELPERS_APPLE_CLANG diff --git a/src/core/renderer_gl/etc1.cpp b/src/core/renderer_gl/etc1.cpp index ae5abb65..82f06724 100644 --- a/src/core/renderer_gl/etc1.cpp +++ b/src/core/renderer_gl/etc1.cpp @@ -60,14 +60,14 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) { }; // Parse colour data for 4x4 block - const u32 subindices = getBits<0, 16>(colourData); - const u32 negationFlags = getBits<16, 16>(colourData); + const u32 subindices = getBits<0, 16, u32>(colourData); + const u32 negationFlags = getBits<16, 16, u32>(colourData); const bool flip = getBit<32>(colourData); const bool diffMode = getBit<33>(colourData); // Note: index1 is indeed stored on the higher bits, with index2 in the lower bits - const u32 tableIndex1 = getBits<37, 3>(colourData); - const u32 tableIndex2 = getBits<34, 3>(colourData); + const u32 tableIndex1 = getBits<37, 3, u32>(colourData); + const u32 tableIndex2 = getBits<34, 3, u32>(colourData); const u32 texelIndex = u * 4 + v; // Index of the texel in the block if (flip) @@ -75,14 +75,14 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) { s32 r, g, b; if (diffMode) { - r = getBits<59, 5>(colourData); - g = getBits<51, 5>(colourData); - b = getBits<43, 5>(colourData); + r = getBits<59, 5, s32>(colourData); + g = getBits<51, 5, s32>(colourData); + b = getBits<43, 5, s32>(colourData); if (u >= 2) { - r += signExtend3To32(getBits<56, 3>(colourData)); - g += signExtend3To32(getBits<48, 3>(colourData)); - b += signExtend3To32(getBits<40, 3>(colourData)); + r += signExtend3To32(getBits<56, 3, u32>(colourData)); + g += signExtend3To32(getBits<48, 3, u32>(colourData)); + b += signExtend3To32(getBits<40, 3, u32>(colourData)); } // Expand from 5 to 8 bits per channel @@ -91,13 +91,13 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) { b = Colour::convert5To8Bit(b); } else { if (u < 2) { - r = getBits<60, 4>(colourData); - g = getBits<52, 4>(colourData); - b = getBits<44, 4>(colourData); + r = getBits<60, 4, s32>(colourData); + g = getBits<52, 4, s32>(colourData); + b = getBits<44, 4, s32>(colourData); } else { - r = getBits<56, 4>(colourData); - g = getBits<48, 4>(colourData); - b = getBits<40, 4>(colourData); + r = getBits<56, 4, s32>(colourData); + g = getBits<48, 4, s32>(colourData); + b = getBits<40, 4, s32>(colourData); } // Expand from 4 to 8 bits per channel diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index e4df36a0..819bf783 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -119,10 +119,10 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) { auto ptr = static_cast(data); u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); - u8 alpha = Colour::convert4To8Bit(getBits<0, 4>(texel)); - u8 b = Colour::convert4To8Bit(getBits<4, 4>(texel)); - u8 g = Colour::convert4To8Bit(getBits<8, 4>(texel)); - u8 r = Colour::convert4To8Bit(getBits<12, 4>(texel)); + u8 alpha = Colour::convert4To8Bit(getBits<0, 4, u8>(texel)); + u8 b = Colour::convert4To8Bit(getBits<4, 4, u8>(texel)); + u8 g = Colour::convert4To8Bit(getBits<8, 4, u8>(texel)); + u8 r = Colour::convert4To8Bit(getBits<12, 4, u8>(texel)); return (alpha << 24) | (b << 16) | (g << 8) | r; } @@ -133,9 +133,9 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) { u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); u8 alpha = getBit<0>(texel) ? 0xff : 0; - u8 b = Colour::convert5To8Bit(getBits<1, 5>(texel)); - u8 g = Colour::convert5To8Bit(getBits<6, 5>(texel)); - u8 r = Colour::convert5To8Bit(getBits<11, 5>(texel)); + u8 b = Colour::convert5To8Bit(getBits<1, 5, u8>(texel)); + u8 g = Colour::convert5To8Bit(getBits<6, 5, u8>(texel)); + u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel)); return (alpha << 24) | (b << 16) | (g << 8) | r; } @@ -145,9 +145,9 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) { auto ptr = static_cast(data); u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); - u8 b = Colour::convert5To8Bit(getBits<0, 5>(texel)); - u8 g = Colour::convert6To8Bit(getBits<5, 6>(texel)); - u8 r = Colour::convert5To8Bit(getBits<11, 5>(texel)); + u8 b = Colour::convert5To8Bit(getBits<0, 5, u8>(texel)); + u8 g = Colour::convert6To8Bit(getBits<5, 6, u8>(texel)); + u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel)); return (0xff << 24) | (b << 16) | (g << 8) | r; }