Optimized IsLZ77Data to return size.

This commit is contained in:
Ariel A 2024-02-20 20:36:48 -05:00
parent 195d2bb79a
commit 11def0fcc5
2 changed files with 10 additions and 17 deletions

View file

@ -8,7 +8,7 @@ extern u8 ALIGNED(4) gDecompressionBuffer[0x4000];
void LZDecompressWram(const u32 *src, void *dest);
void LZDecompressVram(const u32 *src, void *dest);
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize);
u32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize);
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src);
u16 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset);

View file

@ -21,20 +21,23 @@ void LZDecompressVram(const u32 *src, void *dest)
// Checks if `ptr` is likely LZ77 data
// Checks word-alignment, min/max size, and header byte
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize) {
// Returns uncompressed size if true, 0 otherwise
u32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize) {
const u8 *data = ptr;
u32 size;
// Compressed data must be word aligned
if (((u32)ptr) & 3)
return FALSE;
return 0;
// Check LZ77 header byte
// See https://problemkaputt.de/gbatek.htm#biosdecompressionfunctions
if (data[0] != 0x10)
return FALSE;
return 0;
// Read 24-bit uncompressed size
size = data[1] | (data[2] << 8) | (data[3] << 16);
return (size >= minSize && size <= maxSize);
if (size >= minSize && size <= maxSize)
return size;
return 0;
}
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src)
@ -52,20 +55,10 @@ u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src)
u16 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset) {
struct SpriteTemplate myTemplate;
struct SpriteFrameImage myImage;
const u8 *data = template->images->data;
u32 size;
// (Heuristic) Check for LZ77 header
// See https://problemkaputt.de/gbatek.htm#biosdecompressionfunctions
// data[3] could be nonzero; but this would mean data >= 65536 bytes,
// which is 2048 tiles, far too big in practice
if (data[0] != 0x10 || data[3] != 0) // not compressed
return LoadSpriteSheetByTemplate(template, 0, offset);
// read uncompressed size from header
size = T1_READ_16(&data[1]);
// too big for compression buffer, so probably not compressed
if (size >= ARRAY_COUNT(gDecompressionBuffer))
// Check for LZ77 header and read uncompressed size, or fallback if not compressed (zero size)
if ((size = IsLZ77Data(template->images->data, TILE_SIZE_4BPP, sizeof(gDecompressionBuffer))) == 0)
return LoadSpriteSheetByTemplate(template, 0, offset);
LZ77UnCompWram(template->images->data, gDecompressionBuffer);