diff --git a/arm9/Makefile b/arm9/Makefile index 52fb7c4..3684baf 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -130,7 +130,7 @@ @$(bin2o) #--------------------------------------------------------------------------------- -%.ppm.o : %.ppm +%.ppm.lz.o : %.ppm.lz #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) diff --git a/arm9/data/banner.ppm b/arm9/data/banner.ppm deleted file mode 100644 index 3a63f84..0000000 --- a/arm9/data/banner.ppm +++ /dev/null Binary files differ diff --git a/arm9/data/banner.ppm.lz b/arm9/data/banner.ppm.lz new file mode 100644 index 0000000..2e195dd --- /dev/null +++ b/arm9/data/banner.ppm.lz Binary files differ diff --git a/arm9/data/bootfail.ppm b/arm9/data/bootfail.ppm deleted file mode 100644 index 1d6b929..0000000 --- a/arm9/data/bootfail.ppm +++ /dev/null Binary files differ diff --git a/arm9/data/bootfail.ppm.lz b/arm9/data/bootfail.ppm.lz new file mode 100644 index 0000000..1554a90 --- /dev/null +++ b/arm9/data/bootfail.ppm.lz Binary files differ diff --git a/arm9/data/bootwarning.ppm b/arm9/data/bootwarning.ppm deleted file mode 100644 index 808647f..0000000 --- a/arm9/data/bootwarning.ppm +++ /dev/null Binary files differ diff --git a/arm9/data/bootwarning.ppm.lz b/arm9/data/bootwarning.ppm.lz new file mode 100644 index 0000000..521391d --- /dev/null +++ b/arm9/data/bootwarning.ppm.lz Binary files differ diff --git a/source/arm9/lzss.s b/source/arm9/lzss.s new file mode 100644 index 0000000..e5ff084 --- /dev/null +++ b/source/arm9/lzss.s @@ -0,0 +1,64 @@ +@ Code by mtheall + +#include "asmfunc.h" + +.arm +.cpu arm946e-s +.fpu softvfp + + + +ASM_FUNC lzssDecompress + push {r4-r6} + ldr r3, =(0x01010101) + +.Lloop: + cmp r2, #0 @ if(size <= 0) + pople {r4-r6} @ pop stack + bxle lr @ return + + rors r3, r3, #1 @ r3 = (r3<<31) | (r3>>1) + ldrcsb r12, [r0], #1 @ if(r3 & (1<<31)) flags = *in++ + tst r12, r3 @ if(flags & r3 == 0) + beq .Lcopy_uncompressed @ goto copy_uncompressed + + ldrb r4, [r0], #1 @ r4 = *in++ + lsr r6, r4, #4 @ len = r4>>4 + add r6, r6, #3 @ len += 3 + and r5, r4, #0x0F @ disp = r4 & 0x0F note: disp is in r5 + ldrb r4, [r0], #1 @ r4 = *in++ + orr r4, r4, r5, lsl #8 @ disp = r4 | (disp<<8) note: disp changes to r4 + add r4, r4, #1 @ disp++ + sub r2, r2, r6 @ size -= len + tst r4, #1 @ if(r4 & 1 == 0) // aligned displacement + beq .Lcopy_aligned @ goto copy_aligned + +.Lcopy_compressed: + ldrb r5, [r1, -r4] @ r5 = *(out - disp) + subs r6, r6, #1 @ --len + strb r5, [r1], #1 @ *out++ = r5 + bne .Lcopy_compressed @ goto copy_compressed + b .Lloop @ if(len == 0) goto loop + +.Lcopy_aligned: + tst r1, #0x1 @ if(r1 & 0x1 == 0) // src/dst is aligned + beq .Lcopy_hwords @ goto copy_hwords + ldrb r5, [r1, -r4] @ r5 = *(out - disp) // read a byte to align + sub r6, r6, #1 @ len-- + strb r5, [r1], #1 @ *out++ = r5 +.Lcopy_hwords: + subs r6, r6, #2 @ len -= 2 + ldrgeh r5, [r1, -r4] @ if(len >= 0) r5 = *(short*)(out - disp) + strgeh r5, [r1], #2 @ if(len >= 0) *(short*)out++ = r5 + bgt .Lcopy_hwords @ if(len > 0) goto copy_hwords + beq .Lloop @ if(len == 0) goto loop +@ extra byte + ldrb r5, [r1, -r4] @ r5 = *(out - disp) + strb r5, [r1], #1 @ *out++ = r5 + b .Lloop @ goto loop + +.Lcopy_uncompressed: + ldrb r4, [r0], #1 @ r4 = *in++ + sub r2, r2, #1 @ size-- + strb r4, [r1], #1 @ *out++ = r4 + b .Lloop @ goto loop diff --git a/source/arm9/ui.c b/source/arm9/ui.c index 64c337b..346f770 100644 --- a/source/arm9/ui.c +++ b/source/arm9/ui.c @@ -29,17 +29,17 @@ #include "arm9/main.h" #include "arm9/ui.h" #include "arm9/console.h" -#include "banner_ppm.h" -#include "bootwarning_ppm.h" -#include "bootfail_ppm.h" +#include "banner_ppm_lz.h" +#include "bootwarning_ppm_lz.h" +#include "bootfail_ppm_lz.h" static u8 randomColor; static bool verbose = false; -static const void *bannerData = banner_ppm; -static const void *bootWarningData = bootwarning_ppm; -static const void *bootFailureData = bootfail_ppm; +static const void *bannerData = banner_ppm_lz; +static const void *bootWarningData = bootwarning_ppm_lz; +static const void *bootFailureData = bootfail_ppm_lz; static void uiGetPPMInfo(const u8 *data, unsigned *width, unsigned *height); @@ -59,13 +59,21 @@ consoleSelect(&con_top); } +void lzssDecompress(const void *in, void *out, u32 size); + void uiDrawSplashScreen() { + u8 *buf = (u8*)malloc(0x3259); + if(!buf) return; + + lzssDecompress(bannerData + 4, buf, 0x3259); unsigned width, height; - - uiGetPPMInfo(bannerData, &width, &height); + uiGetPPMInfo(buf, &width, &height); + // centered draw - uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, (SCREEN_HEIGHT_TOP - height) / 2, bannerData); + uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, (SCREEN_HEIGHT_TOP - height) / 2, buf); + + free(buf); } void uiInit() @@ -414,21 +422,33 @@ void uiPrintBootWarning() { + u8 *buf = (u8*)malloc(0x39CD); + if(!buf) return; + + lzssDecompress(bootWarningData + 4, buf, 0x39CD); unsigned width, height; - - uiGetPPMInfo(bootWarningData, &width, &height); - uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, bootWarningData); + uiGetPPMInfo(buf, &width, &height); + uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, buf); + + free(buf); TIMER_sleep(400); } void uiPrintBootFailure() { + u8 *buf = (u8*)malloc(0x39CD); + if(!buf) return; + + lzssDecompress(bootWarningData + 4, buf, 0x39CD); unsigned width, height; - - uiGetPPMInfo(bootWarningData, &width, &height); - clearPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, bootWarningData); - uiGetPPMInfo(bootFailureData, &width, &height); - uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, bootFailureData); + uiGetPPMInfo(buf, &width, &height); + clearPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, buf); + + lzssDecompress(bootFailureData + 4, buf, 0x304F); + uiGetPPMInfo(buf, &width, &height); + uiDrawPPM((SCREEN_WIDTH_TOP - width) / 2, SCREEN_HEIGHT_TOP + 10, buf); + + free(buf); TIMER_sleep(400); }