From e882dd7aaf6b47db3259e7f9250a65d8115e56a0 Mon Sep 17 00:00:00 2001 From: Aurora Date: Tue, 5 Apr 2016 23:01:46 +0200 Subject: [PATCH] Rewrote the config menu (no longer prints the whole menu on each button press), cleaned up the reboot patch, boot options will keep being forced if a GBA game was lanched from SysNAND, added option to have a splash screen with the built-in screen-init --- patches/reboot.s | 22 +++--------- source/config.c | 89 ++++++++++++++++++++++++++++++++++-------------- source/draw.c | 5 +-- source/firm.c | 9 ++--- 4 files changed, 75 insertions(+), 50 deletions(-) diff --git a/patches/reboot.s b/patches/reboot.s index bae45ff..1d81acf 100644 --- a/patches/reboot.s +++ b/patches/reboot.s @@ -2,7 +2,6 @@ firm_addr equ 0x24000000 ; Temporary location where we'll load the FIRM to firm_maxsize equ 0x200000 ; Random value that's bigger than any of the currently known firm's sizes. -kernel_code equ 0x080F0000 ; Offset to copy the Kernel9 code to .create "reboot.bin", 0 .arm @@ -108,24 +107,11 @@ kernel_code equ 0x080F0000 ; Offset to copy the Kernel9 code to ; Jump to reboot code ldr r0, =(kernelcode_start - goto_reboot - 12) add r0, pc - ldr r1, =kernel_code - ldr r2, =0x300 - bl memcpy32 - ldr r0, =kernel_code swi 0x7B die: b die -memcpy32: ; memcpy32(void *src, void *dst, unsigned int size) - add r2, r0 - memcpy32_loop: - ldmia r0!, {r3} - stmia r1!, {r3} - cmp r0, r2 - blo memcpy32_loop - bx lr - bytes_read: .word 0 fopen: .ascii "OPEN" .pool @@ -182,7 +168,7 @@ agbfirm_fname: .dcw "sdmc:/aurei/patched_firmware_agb.bin" addne r0, r4 ; src ldrne r1, [r5, #4] ; dest ldrne r2, [r5, #8] ; size - blne kernelmemcpy32 + blne memcpy32 cmp r5, r6 addlo r5, #0x30 @@ -221,12 +207,12 @@ agbfirm_fname: .dcw "sdmc:/aurei/patched_firmware_agb.bin" bx r0 .pool -kernelmemcpy32: ; memcpy32(void *src, void *dst, unsigned int size) +memcpy32: ; memcpy32(void *src, void *dst, unsigned int size) add r2, r0 - kmemcpy32_loop: + memcpy32_loop: ldmia r0!, {r3} stmia r1!, {r3} cmp r0, r2 - blo kmemcpy32_loop + blo memcpy32_loop bx lr .close diff --git a/source/config.c b/source/config.c index 515c800..f58a3ed 100644 --- a/source/config.c +++ b/source/config.c @@ -19,13 +19,15 @@ void configureCFW(const char *configPath, const char *patchedFirms[]) drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE); drawString("Press A to select, START to save and reboot", 10, 30, COLOR_WHITE); - const char *optionsText[] = { "( ) Updated SysNAND mode (A9LH-only)", + const char *optionsText[] = { "Screen-init brightness: 4( ) 3( ) 2( ) 1( )", + "( ) Updated SysNAND mode (A9LH-only)", "( ) Use pre-patched FIRMs", "( ) Force A9LH detection", "( ) Use 9.0 FIRM as default", "( ) Use second EmuNAND as default", "( ) Show current NAND in System Settings", - "( ) Show GBA boot screen in patched AGB_FIRM" }; + "( ) Show GBA boot screen in patched AGB_FIRM", + "( ) Enable splash screen with no screen-init" }; u32 optionsAmount = sizeof(optionsText) / sizeof(char *); @@ -35,52 +37,88 @@ void configureCFW(const char *configPath, const char *patchedFirms[]) } options[optionsAmount]; //Parse the existing configuration - for(u32 i = 0; i < optionsAmount; i++) - options[i].enabled = (config >> i) & 1; - - options[optionsAmount].enabled = (config >> 10) & 3; + options[0].enabled = (config >> 10) & 3; + for(u32 i = optionsAmount; i; i--) + options[i].enabled = (config >> (i - 1)) & 1; //Pre-select the first configuration option - u32 selectedOption = 0; + u32 selectedOption = 1, + oldSelectedOption = 0, + optionChanged = 0; + + //Character to display a selected option + char selected = 'x'; + + //Starting position + options[0].posY = 52; + + //Display all the normal options in white, brightness will be displayed later + for(u32 i = 1; i < optionsAmount; i++) + { + options[i].posY = drawString(optionsText[i], 10, options[i - 1].posY + SPACING_Y + (!(1 - i) * 7), COLOR_WHITE); + if(options[i].enabled) drawCharacter(selected, 10 + SPACING_X, options[i].posY, COLOR_WHITE); + } //Boring configuration menu while(1) { - u16 pressed = 0; + u32 pressed = 0; do { - options[optionsAmount].posY = drawString("Screen-init brightness: 4( ) 3( ) 2( ) 1( )", 10, 53, selectedOption == optionsAmount ? COLOR_RED : COLOR_WHITE); - - for(u32 i = 0; i < optionsAmount; i++) + //An option changed, black out the 'x' for the previously selected option/brightness level + if(optionChanged) { - options[i].posY = drawString(optionsText[i], 10, !i ? options[optionsAmount].posY + 2 * SPACING_Y : options[i - 1].posY + SPACING_Y, selectedOption == i ? COLOR_RED : COLOR_WHITE); - drawCharacter('x', 10 + SPACING_X, options[i].posY, options[i].enabled ? (selectedOption == i ? COLOR_RED : COLOR_WHITE) : COLOR_BLACK); + if(!selectedOption) + drawCharacter(selected, 10 + (26 + 5 * (optionChanged - 1)) * SPACING_X, options[0].posY, COLOR_BLACK); + else if(!options[selectedOption].enabled) + drawCharacter(selected, 10 + SPACING_X, options[selectedOption].posY, COLOR_BLACK); + + optionChanged = 0; } - for(u32 i = 0; i < 4; i++) - drawCharacter('x', 10 + (26 + 5 * i) * SPACING_X, options[optionsAmount].posY, options[optionsAmount].enabled == i ? (selectedOption == optionsAmount ? COLOR_RED : COLOR_WHITE) : COLOR_BLACK); + //The selected option changed, draw the new one in red and the old one (with its 'x') in white + else if(selectedOption != oldSelectedOption) + { + drawString(optionsText[oldSelectedOption], 10, options[oldSelectedOption].posY, COLOR_WHITE); + drawString(optionsText[selectedOption], 10, options[selectedOption].posY, COLOR_RED); + + if(!oldSelectedOption) + drawCharacter(selected, 10 + (26 + 5 * options[0].enabled) * SPACING_X, options[0].posY, COLOR_WHITE); + else if(options[oldSelectedOption].enabled) + drawCharacter(selected, 10 + SPACING_X, options[oldSelectedOption].posY, COLOR_WHITE); + } + + //In any case, if the current option is enabled (or brightness is selected) we must display a red 'x' + if(!selectedOption) + drawCharacter(selected, 10 + (26 + 5 * options[0].enabled) * SPACING_X, options[0].posY, COLOR_RED); + else if(options[selectedOption].enabled) + drawCharacter(selected, 10 + SPACING_X, options[selectedOption].posY, COLOR_RED); pressed = waitInput(); } while(!(pressed & MENU_BUTTONS)); + //Remember the previously selected option + oldSelectedOption = selectedOption; + switch(pressed) { case BUTTON_UP: - selectedOption = !selectedOption ? optionsAmount : selectedOption - 1; + selectedOption = !selectedOption ? optionsAmount - 1 : selectedOption - 1; break; case BUTTON_DOWN: - selectedOption = selectedOption >= optionsAmount - 1 ? 0 : selectedOption + 1; + selectedOption = selectedOption == (optionsAmount - 1) ? 1 : selectedOption + 1; break; case BUTTON_LEFT: - selectedOption = 0; + selectedOption = 1; break; case BUTTON_RIGHT: selectedOption = optionsAmount - 1; break; case BUTTON_A: - if(selectedOption != optionsAmount) options[selectedOption].enabled = !options[selectedOption].enabled; - else options[optionsAmount].enabled = options[optionsAmount].enabled == 3 ? 0 : options[optionsAmount].enabled + 1; + optionChanged = 1 + options[0].enabled; + if(selectedOption) options[selectedOption].enabled = !options[selectedOption].enabled; + else options[0].enabled = options[0].enabled == 3 ? 0 : options[0].enabled + 1; break; } @@ -88,19 +126,18 @@ void configureCFW(const char *configPath, const char *patchedFirms[]) } //If the user has been using A9LH and the "Updated SysNAND" setting changed, delete the patched 9.0 FIRM - if(((config >> 16) & 1) && ((config & 1) != options[0].enabled)) fileDelete(patchedFirms[3]); + if(((config >> 16) & 1) && ((config & 1) != options[1].enabled)) fileDelete(patchedFirms[3]); //If the "Show GBA boot screen in patched AGB_FIRM" setting changed, delete the patched AGB_FIRM - if(((config >> 6) & 1) != options[6].enabled) fileDelete(patchedFirms[5]); + if(((config >> 6) & 1) != options[7].enabled) fileDelete(patchedFirms[5]); //Preserve the last-used boot options (last 12 bits) config &= 0xFFF000; //Parse and write the new configuration - for(u32 i = 0; i < optionsAmount; i++) - config |= options[i].enabled << i; - - config |= options[optionsAmount].enabled << 10; + config |= options[0].enabled << 10; + for(u32 i = optionsAmount; i; i--) + config |= options[i].enabled << (i - 1); fileWrite(&config, configPath, 3); diff --git a/source/draw.c b/source/draw.c index eedd46f..17010ef 100644 --- a/source/draw.c +++ b/source/draw.c @@ -7,6 +7,7 @@ */ #include "draw.h" +#include "screeninit.h" #include "fs.h" #include "memory.h" #include "font.h" @@ -36,13 +37,13 @@ void clearScreens(void) void loadSplash(void) { - clearScreens(); + initScreens(); //Don't delay boot if no splash image is on the SD if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) + fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)) { - u64 i = 0x1300000; + u64 i = 0x1400000; while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func } } diff --git a/source/firm.c b/source/firm.c index 3c8c64a..83225bc 100755 --- a/source/firm.c +++ b/source/firm.c @@ -123,8 +123,8 @@ void setupCFW(void) if(needConfig == 2 || (pressed & BUTTON_SELECT)) configureCFW(configPath, patchedFirms); - //If screens are inited, load splash screen - if(PDN_GPU_CNT != 1) loadSplash(); + //If screens are inited or the corresponding option is set, load splash screen + if(PDN_GPU_CNT != 1 || ((config >> 7) & 1)) loadSplash(); /* If L is pressed, or L or R are not pressed when it is the default FIRM, boot 9.0 FIRM */ @@ -173,8 +173,9 @@ void setupCFW(void) tempConfig |= (emuNAND << 13) | (mode << 12); - //If the boot configuration is different from previously, overwrite it - if(tempConfig != (config & 0xFFF000)) + /* If the boot configuration is different from previously, overwrite it. + Just the no-forcing flag being set is not enough */ + if((tempConfig & 0xFF7000) != (config & 0xFFF000)) { //Preserve user settings (first 12 bits) tempConfig |= config & 0xFFF;