diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile index 34bfea6d6..8594591a0 100644 --- a/fusee/fusee-secondary/Makefile +++ b/fusee/fusee-secondary/Makefile @@ -11,6 +11,7 @@ name := fusee-secondary dir_source := src dir_build := build dir_out := out +dir_data := data ARCH := -march=armv4t -mtune=arm7tdmi -marm @@ -34,7 +35,8 @@ LDFLAGS = -specs=linker.specs -g $(ARCH) objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ - $(call rwildcard, $(dir_source), *.s *.c))) + $(call rwildcard, $(dir_source), *.s *.c))) \ + $(dir_build)/default_splash.bmp.o define bin2o bin2s $< | $(AS) -o $(@) @@ -58,6 +60,9 @@ $(dir_build)/$(name).elf: $(objects) $(dir_build)/%.bin.o: $(dir_build)/%.bin @$(bin2o) +$(dir_build)/default_splash.bmp.o: $(dir_data)/default_splash.bmp + @$(bin2o) + $(dir_build)/%.o: $(dir_source)/%.c @mkdir -p "$(@D)" $(COMPILE.c) $(OUTPUT_OPTION) $< @@ -65,3 +70,5 @@ $(dir_build)/%.o: $(dir_source)/%.c $(dir_build)/%.o: $(dir_source)/%.s @mkdir -p "$(@D)" $(COMPILE.c) -x assembler-with-cpp $(OUTPUT_OPTION) $< + + diff --git a/fusee/fusee-secondary/data/default_splash.bmp b/fusee/fusee-secondary/data/default_splash.bmp new file mode 100644 index 000000000..af15d8039 Binary files /dev/null and b/fusee/fusee-secondary/data/default_splash.bmp differ diff --git a/fusee/fusee-secondary/src/main.c b/fusee/fusee-secondary/src/main.c index 4584ae793..b41d8e45c 100644 --- a/fusee/fusee-secondary/src/main.c +++ b/fusee/fusee-secondary/src/main.c @@ -13,6 +13,7 @@ #include "switch_fs.h" #include "gpt.h" #include "display/video_fb.h" +#include "splash_screen.h" extern void (*__program_exit_callback)(int rc); @@ -78,7 +79,7 @@ int main(int argc, void **argv) { g_do_nxboot = loader_ctx->chainload_entrypoint == 0; if (g_do_nxboot) { - nxboot_main(); + nxboot_main((uint8_t*)g_framebuffer); } else { /* TODO: What else do we want to do in terms of argc/argv? */ const char *path = get_loader_ctx()->file_paths[get_loader_ctx()->file_id_of_entrypoint]; diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index c0cf74848..8be37f5a3 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -46,7 +46,7 @@ void nxboot_configure_exosphere(void) { } /* This is the main function responsible for booting Horizon. */ -void nxboot_main(void) { +void nxboot_main(uint8_t *fb_addr) { loader_ctx_t *loader_ctx = get_loader_ctx(); /* TODO: Validate that we're capable of booting. */ @@ -87,7 +87,7 @@ void nxboot_main(void) { } /* Display splash screen. */ - display_splash_screen_bmp(loader_ctx->custom_splash_path); + display_splash_screen_bmp(loader_ctx->custom_splash_path, fb_addr); /* TODO: Halt ourselves. */ } diff --git a/fusee/fusee-secondary/src/nxboot.h b/fusee/fusee-secondary/src/nxboot.h index aefa651f9..277eff3aa 100644 --- a/fusee/fusee-secondary/src/nxboot.h +++ b/fusee/fusee-secondary/src/nxboot.h @@ -22,6 +22,6 @@ #define MAILBOX_NX_BOOTLOADER_BOOT_REASON (MAILBOX_NX_BOOTLOADER_BASE + 0xE10ULL) -void nxboot_main(void); +void nxboot_main(uint8_t *fb_addr); #endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/splash_screen.c b/fusee/fusee-secondary/src/splash_screen.c index 51276d37e..d071076d2 100644 --- a/fusee/fusee-secondary/src/splash_screen.c +++ b/fusee/fusee-secondary/src/splash_screen.c @@ -1,20 +1,59 @@ #include +#include +#include #include "utils.h" #include "timers.h" #include "splash_screen.h" #include "sd_utils.h" #include "display/video_fb.h" -void display_splash_screen_bmp(const char *custom_splash_path) { - uint8_t *splash_screen = g_default_splash_screen; - if (custom_splash_path != NULL && custom_splash_path[0] != '\x00') { - if (!read_sd_file(splash_screen, sizeof(g_default_splash_screen), custom_splash_path)) { - printf("Error: Failed to read custom splash screen from %s!\n", custom_splash_path); - generic_panic(); +uint8_t *load_default_splash() { + printf("Failed to read custom splash. Falling back to default splash"); + uint8_t *buffer = calloc(default_splash_bmp_size, sizeof(uint8_t)); + memcpy(buffer, default_splash_bmp, default_splash_bmp_size); + return buffer; +} + +void display_splash_screen_bmp(const char *custom_splash_path, uint8_t* fb_addr) { + /* Cast the framebuffer to a 2-dimensional array, for easy addressing */ + uint8_t (*fb)[3072] = (uint8_t(*)[3072])fb_addr; + + uint8_t *splash_screen = NULL; + + /* Stat the splash file to set size information, and see if it's there */ + struct stat info; + if (!stat(custom_splash_path, &info)) { + /* Prepare the buffer */ + splash_screen = calloc(info.st_size, sizeof(uint8_t)); + + /* Read the BMP from the SD card */ + if (!read_sd_file(splash_screen, info.st_size, custom_splash_path)) { + splash_screen = load_default_splash(); + } + } else { + splash_screen = load_default_splash(); + } + + /* BMP pixel data offset (dword @ 0xA) */ + int data_offset = (splash_screen[0xA] & 0xFF) | + ((splash_screen[0xB] & 0xFF00) << 8) | + ((splash_screen[0xC] & 0xFF0000) << 16) | + ((splash_screen[0xD] & 0xFF000000) << 24); + + int count = 0; + for (int y = 719; y >= 0; y--) { + for (int x = 1280; x > 0; x--) { + /* Fill the framebuffer w/ necessary pixel format translations (framebuffer is RGBA, BMP is BGRA) */ + fb[x][y * 4] = splash_screen[data_offset + count + 2]; + fb[x][y * 4 + 1] = splash_screen[data_offset + count + 1]; + fb[x][y * 4 + 2] = splash_screen[data_offset + count]; + fb[x][y * 4 + 3] = splash_screen[data_offset + count + 3]; + count += 4; } } - /* TODO: Display the splash screen. It should be a pointer to a BMP, at this point. */ + /* Free the splash buffer; we're done with it. */ + free(splash_screen); /* Display the splash screen for three seconds. */ wait(3000000); diff --git a/fusee/fusee-secondary/src/splash_screen.h b/fusee/fusee-secondary/src/splash_screen.h index 7240b3235..b413dbdd9 100644 --- a/fusee/fusee-secondary/src/splash_screen.h +++ b/fusee/fusee-secondary/src/splash_screen.h @@ -3,9 +3,10 @@ #include -/* TODO: Actually make this a real thing. */ -extern unsigned char g_default_splash_screen[1]; +extern uint8_t default_splash_bmp[]; +extern uint32_t default_splash_bmp_size; -void display_splash_screen_bmp(const char *custom_splash_path); +void display_splash_screen_bmp(const char *custom_splash_path, uint8_t *fb_addr); +uint8_t *load_default_splash(); #endif diff --git a/fusee/fusee-secondary/src/splash_screen_default.c b/fusee/fusee-secondary/src/splash_screen_default.c deleted file mode 100644 index c1391a6cf..000000000 --- a/fusee/fusee-secondary/src/splash_screen_default.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "splash_screen.h" - -uint8_t g_default_splash_screen[1] = {0};