From 11def0fcc58611ae829acaafabfebe42faed930d Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Tue, 20 Feb 2024 20:36:48 -0500 Subject: [PATCH] Optimized IsLZ77Data to return size. --- include/decompress.h | 2 +- src/decompress.c | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/include/decompress.h b/include/decompress.h index 11560122e0..cfa7011576 100644 --- a/include/decompress.h +++ b/include/decompress.h @@ -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); diff --git a/src/decompress.c b/src/decompress.c index 76d6223871..be7bb77c7a 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -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);