From: chaoskagami Date: Tue, 3 May 2016 05:31:49 +0000 (-0400) Subject: Lots of misc menu work, proc9 search added X-Git-Tag: stable-1~81 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=f0310cf2c3cbcf15f582cd551b3c0f85b02c370d;p=corbenik%2Fcorbenik.git Lots of misc menu work, proc9 search added --- diff --git a/source/common.h b/source/common.h index f58b083..b582b61 100644 --- a/source/common.h +++ b/source/common.h @@ -7,6 +7,7 @@ #include "std/fs.h" #include "std/memory.h" #include "std/abort.h" +#include "std/unused.h" #include "firm/fcram.h" #include "firm/crypto.h" @@ -15,6 +16,7 @@ #include "patch_format.h" #include "config.h" #include "input.h" +#include "patcher.h" #include "i2c.h" diff --git a/source/config.h b/source/config.h index 7420fdb..5b4d250 100644 --- a/source/config.h +++ b/source/config.h @@ -1,7 +1,7 @@ #ifndef __CONFIG_H #define __CONFIG_H -static unsigned int config_version = 1; +_UNUSED static unsigned int config_version = 1; #define CONFIG_MAGIC "OVAN" @@ -15,23 +15,27 @@ struct config_file { uint64_t patch_ids[256]; // What patches are enabled by UUID. 256 is an arbitrary limit - contact me if you hit it. }__attribute__((packed)); -static struct config_file config; +_UNUSED static struct config_file config; -#define OPTION_AUTOBOOT 0 // Skip menu unless L is held. -#define OPTION_SILENCE 1 // Don't print debug information. -#define OPTION_TRACE 2 // Pause for A key on each step. +#define OPTION_SIGPATCH 0 // Use builtin signature patch. +#define OPTION_LOADER 1 // Use builtin loader module replacer. +#define OPTION_ARM9THREAD 2 // Use builtin ARM9 thread injector. -#define OPTION_TRANSP_BG 3 // Background color is not drawn under text. -#define OPTION_NO_CLEAR_BG 4 // Framebuffer is preserved from whatever ran before us. -#define OPTION_READ_ME 5 // Remove Help/Readme from menu. +#define OPTION_AUTOBOOT 3 // Skip menu unless L is held. +#define OPTION_SILENCE 4 // Don't print debug information. +#define OPTION_TRACE 5 // Pause for A key on each step. -#define IGNORE_PATCH_DEPS 6 // Ignore patch UUID dependencies. Not recommended. -#define IGNORE_BROKEN_SHIT 7 // Allow enabling patches which are marked as 'incompatible'. Chances are there's a reason. +#define OPTION_TRANSP_BG 6 // Background color is not drawn under text. +#define OPTION_NO_CLEAR_BG 7 // Framebuffer is preserved from whatever ran before us. +#define OPTION_READ_ME 8 // Remove Help/Readme from menu. -#define HEADER_COLOR 8 // Color of header text. -#define BG_COLOR 9 // Color of background. -#define TEXT_COLOR 10 // Color of most text. -#define ARROW_COLOR 11 // Color of Arrow. +#define IGNORE_PATCH_DEPS 9 // Ignore patch UUID dependencies. Not recommended. +#define IGNORE_BROKEN_SHIT 10 // Allow enabling patches which are marked as 'incompatible'. Chances are there's a reason. + +#define HEADER_COLOR 11 // Color of header text. +#define BG_COLOR 12 // Color of background. +#define TEXT_COLOR 13 // Color of most text. +#define ARROW_COLOR 14 // Color of Arrow. void load_config(); diff --git a/source/firm/fcram.h b/source/firm/fcram.h index cfc5ca9..4cf5126 100644 --- a/source/firm/fcram.h +++ b/source/firm/fcram.h @@ -6,6 +6,8 @@ #include +#include "../std/unused.h" + extern void *fcram_temp; // Space between most of the locations @@ -22,7 +24,7 @@ extern void *fcram_temp; // patch.c #define FCRAM_MEMORY_LOC (FCRAM_START + FCRAM_SPACING * 4) -static uint8_t *memory_loc = (uint8_t *)FCRAM_MEMORY_LOC; -static void *current_memory_loc; +_UNUSED static uint8_t *memory_loc = (uint8_t *)FCRAM_MEMORY_LOC; +_UNUSED static void *current_memory_loc; #endif diff --git a/source/firm/firm.c b/source/firm/firm.c index 69900d6..27e6000 100644 --- a/source/firm/firm.c +++ b/source/firm/firm.c @@ -7,12 +7,15 @@ firm_h *firm_loc = (firm_h *)FCRAM_FIRM_LOC; static uint32_t firm_size = FCRAM_SPACING; +firm_section_h firm_proc9; firm_h *twl_firm_loc = (firm_h *)FCRAM_TWL_FIRM_LOC; static uint32_t twl_firm_size = FCRAM_SPACING * 2; +firm_section_h twl_firm_proc9; firm_h *agb_firm_loc = (firm_h *)FCRAM_AGB_FIRM_LOC; static uint32_t agb_firm_size = FCRAM_SPACING; +firm_section_h agb_firm_proc9; static int update_96_keys = 0; static int save_firm = 0; @@ -36,8 +39,7 @@ void slot0x11key96_init() // Otherwise, we make sure the error message for decrypting arm9bin mentions this. } -int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) -{ +int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) { uint8_t firm_iv[16] = {0}; uint8_t exefs_key[16] = {0}; uint8_t exefs_iv[16] = {0}; @@ -108,7 +110,7 @@ int decrypt_arm9bin(arm9bin_h *header, uint64_t firm_title) { else return 0; } -int decrypt_firm(firm_h *dest, char *path_firmkey, char *path_cetk, uint32_t *size, uint64_t firm_title) { +int decrypt_firm(firm_h *dest, char *path_firmkey, uint32_t *size) { uint8_t firm_key[AES_BLOCK_SIZE]; // Firmware is likely encrypted. Decrypt. @@ -127,7 +129,7 @@ int decrypt_firm(firm_h *dest, char *path_firmkey, char *path_cetk, uint32_t *si return 0; } -int load_firm(firm_h *dest, char *path, char *path_firmkey, char *path_cetk, uint32_t *size, uint64_t firm_title) { +int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint64_t firm_title) { int status = 0; int firmware_changed = 0; @@ -147,7 +149,7 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, char *path_cetk, uin // Check and decrypt FIRM if it is encrypted. if (dest->magic != FIRM_MAGIC) { - status = decrypt_firm(dest, path_firmkey, path_cetk, size, firm_title); + status = decrypt_firm(dest, path_firmkey, size); if (status != 0) { if (firm_title == NATIVE_FIRM_TITLEID) { fprintf(BOTTOM_SCREEN, "Failed to decrypt firmware.\n" @@ -277,28 +279,62 @@ void boot_firm() { ((void (*)())firm_loc->a9Entry)(); } +int find_proc9(firm_h* firm, firm_section_h* process9) { + for (firm_section_h *section = firm->section; section < firm->section + 4; section++) { + if (section->address == 0) + break; + + if (section->type == FIRM_TYPE_ARM9) { + void* arm9section = (void*)firm + section->offset; + while (arm9section < arm9section + section->size) { + if (!memcmp(arm9section, "Process9", 8)) { // Process9 + ncch_h *ncch = (ncch_h*)(arm9section - sizeof(ncch_h)); + if (ncch->magic == NCCH_MAGIC) { + // Found Process9 + ncch_ex_h *p9exheader = (ncch_ex_h *)(ncch + 1); + exefs_h *p9exefs = (exefs_h *)(p9exheader + 1); + process9->address = p9exheader->sci.textCodeSet.address; + process9->size = p9exefs->fileHeaders[0].size; + process9->offset = (void*)(p9exefs + 1) - (void*)firm; + fprintf(BOTTOM_SCREEN, "Found Process9 for FIRM.\n"); + return 0; + } + } + ++arm9section; + } + } + } + fprintf(BOTTOM_SCREEN, "Couldn't find Process9 for FIRM?\n"); + return 1; +} + int load_firms() { fprintf(TOP_SCREEN, "[Loading FIRM]"); fprintf(BOTTOM_SCREEN, "Loading NATIVE_FIRM\n"); - if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, PATH_NATIVE_CETK, &firm_size, NATIVE_FIRM_TITLEID) != 0) + if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, &firm_size, NATIVE_FIRM_TITLEID) != 0) return 1; + find_proc9(firm_loc, &firm_proc9); fprintf(BOTTOM_SCREEN, "Loading TWL_FIRM\n"); - if(load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, PATH_TWL_CETK, &twl_firm_size, TWL_FIRM_TITLEID)) + if(load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, &twl_firm_size, TWL_FIRM_TITLEID)) fprintf(BOTTOM_SCREEN, "TWL_FIRM failed to load.\n"); + else + find_proc9(twl_firm_loc, &twl_firm_proc9); fprintf(BOTTOM_SCREEN, "Loading AGB_FIRM\n"); - if(load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, PATH_AGB_CETK, &agb_firm_size, AGB_FIRM_TITLEID)) + if(load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, &agb_firm_size, AGB_FIRM_TITLEID)) fprintf(BOTTOM_SCREEN, "AGB_FIRM failed to load.\n"); + else + find_proc9(agb_firm_loc, &agb_firm_proc9); return 0; } void boot_cfw() { fprintf(TOP_SCREEN, "[Patching]"); -// if (patch_firm_all() != 0) -// return; + if (patch_firm_all() != 0) + return; // Only save the firm if that option is required (or it's needed for autoboot), // and either the patches have been modified, or the file doesn't exist. @@ -336,5 +372,5 @@ void boot_cfw() { } } -// boot_firm(); + boot_firm(); } diff --git a/source/i2c.c b/source/i2c.c index 2053fbb..c00f19b 100644 --- a/source/i2c.c +++ b/source/i2c.c @@ -113,7 +113,7 @@ int i2cReadRegisterBuffer(unsigned int dev_id, int reg, uint8_t* buffer, size_t } if (buf_size != 1) { - for (int i = 0; i < buf_size - 1; i++) { + for (size_t i = 0; i < buf_size - 1; i++) { i2cWaitBusy(bus_id); *i2cGetCntReg(bus_id) = 0xF0; i2cWaitBusy(bus_id); diff --git a/source/main.c b/source/main.c index e59a704..bf2ab72 100644 --- a/source/main.c +++ b/source/main.c @@ -1,184 +1,11 @@ #include "common.h" +#include "firm/firm.h" void init_system() {} -#define MENU_BOOTME -1 -#define MENU_MAIN 1 +int menu_handler(); -#define MENU_OPTIONS 2 -#define MENU_PATCHES 3 -#define MENU_INFO 4 -#define MENU_HELP 5 -#define MENU_RESET 6 -#define MENU_POWER 7 - -static int cursor_y = 0; -static int which_menu = 1; - -uint32_t wait_key() { - uint32_t get = 0; - while(get == 0) { - if(HID_PAD & BUTTON_UP) - get = BUTTON_UP; - else if (HID_PAD & BUTTON_DOWN) - get = BUTTON_DOWN; - else if (HID_PAD & BUTTON_A) - get = BUTTON_A; - else if (HID_PAD & BUTTON_B) - get = BUTTON_B; - } - while(HID_PAD&get); - return get; -} - -void header() { - fprintf(stdout, "\x1b[33;40m[.corbenik//%s]\x1b[0m\n", VERSION); -} - -int menu_options() { return MENU_MAIN; } - -int menu_patches() { return MENU_MAIN; } - -int menu_info() { return MENU_MAIN; } - -int menu_help() { - set_cursor(TOP_SCREEN, 0, 0); - - header(); - - fprintf(stdout, "\nCorbenik is a 3DS firmware patcher\n" - " commonly known as a CFW. It seeks to address\n" - " some faults in other CFWs and is generally\n" - " just another choice for users - but primarily\n" - " the kind of person who runs Gentoo or LFS. ;P\n" - "\n " - "Credits to people who've helped me put this\n" - " together either by having written GPL code,\n" - " or being just generally helpful/cool people:\n" - " @mid-kid, @Wolfvak, @Reisyukaku, @AuroraWright\n" - " @d0k3, and others\n" - "\n " - "The name of this comes from the .hack//series.\n" - " Look it up, if you don't already know it.\n" - "\n " - "Any bugs filed including the letters S, A\n" - " and O will be closed with no discussion.\n" - "\n " - " \n" - "\n " - "Press any button to return.\n"); - while (1) { - if (wait_key() & BUTTON_ANY) - break; - } - - clear_screen(TOP_SCREEN); - - return MENU_MAIN; -} - -int menu_reset() { - fumount(); // Unmount SD. - - // Reboot. - fprintf(BOTTOM_SCREEN, "Resetting system.\n"); - i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); - while(1); -} - -int menu_poweroff() { - fumount(); // Unmount SD. - - // Reboot. - fprintf(BOTTOM_SCREEN, "Powering off system.\n"); - i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); - while(1); -} - -int menu_main() { - set_cursor(TOP_SCREEN, 0, 0); - - const char *list[] = { - "Options ", - "Patches ", - "Info ", - "Help/Readme ", - "Reset ", - "Power off ", - "Boot firmware " - }; - - header(); - - int menu_max = 6; - - for(int i=0; i < menu_max; i++) { - if (cursor_y == i) - fprintf(TOP_SCREEN, "\x1b[32m>>\x1b[0m "); - else - fprintf(TOP_SCREEN, " "); - fprintf(TOP_SCREEN, "%s\n", list[i]); - } - - uint32_t key = wait_key(); - int entry = cursor_y + 2; - if (cursor_y > MENU_POWER) - entry = MENU_BOOTME; - - switch(key) { - case BUTTON_UP: - cursor_y -= 1; - break; - case BUTTON_DOWN: - cursor_y += 1; - break; - case BUTTON_A: - return entry; - break; - } - - // Loop around the cursor. - if (cursor_y < 0) - cursor_y = menu_max -1; - if (cursor_y > menu_max - 1) - cursor_y = 0; - - return 0; -} - -int menu_handler() { - int to_menu = 0; - switch(which_menu) { - case MENU_MAIN: - to_menu = menu_main(); - break; - case MENU_OPTIONS: - to_menu = menu_options(); - break; - case MENU_PATCHES: - to_menu = menu_patches(); - break; - case MENU_INFO: - to_menu = menu_info(); - break; - case MENU_HELP: - to_menu = menu_help(); - break; - case MENU_BOOTME: - return 0; - case MENU_RESET: - menu_reset(); - case MENU_POWER: - menu_poweroff(); - } - - if (to_menu != 0) - which_menu = to_menu; - - return 1; -} - -void main() { +int main() { if (fmount()) { // Failed to mount SD. Bomb out. fprintf(BOTTOM_SCREEN, "%pFailed to mount SD card.\n", COLOR(RED, BLACK)); diff --git a/source/menu.c b/source/menu.c new file mode 100644 index 0000000..7113280 --- /dev/null +++ b/source/menu.c @@ -0,0 +1,241 @@ +#include "common.h" +#include "firm/firm.h" + +#define MENU_BOOTME -1 +#define MENU_MAIN 1 + +#define MENU_OPTIONS 2 +#define MENU_PATCHES 3 +#define MENU_INFO 4 +#define MENU_HELP 5 +#define MENU_RESET 6 +#define MENU_POWER 7 + +static int cursor_y = 0; +static int which_menu = 1; + +uint32_t wait_key() { + uint32_t get = 0; + while(get == 0) { + if(HID_PAD & BUTTON_UP) + get = BUTTON_UP; + else if (HID_PAD & BUTTON_DOWN) + get = BUTTON_DOWN; + else if (HID_PAD & BUTTON_A) + get = BUTTON_A; + else if (HID_PAD & BUTTON_B) + get = BUTTON_B; + } + while(HID_PAD&get); + return get; +} + +void header() { + fprintf(stdout, "\x1b[33;40m[.corbenik//%s]\x1b[0m\n", VERSION); +} + +int menu_patches() { return MENU_MAIN; } + +int menu_options() { + clear_screen(TOP_SCREEN); + + set_cursor(TOP_SCREEN, 0, 0); + + const char *list[] = { + "Signature patch (builtin)", + "Loader module (builtin)", + "ARM9 thread (builtin)", + + "Autoboot", + "Silence debug output", + "Trace steps with (A)", + + "Don't draw background color", + "Preserve current framebuffer", + "Hide Readme/Help from menu", + + "Ignore dependencies", + "Allow enabling broken", + }; + const int menu_max = 11; + + header(); + + for(int i=0; i < menu_max; i++) { + if (cursor_y == i) + fprintf(TOP_SCREEN, "\x1b[32m>>\x1b[0m "); + else + fprintf(TOP_SCREEN, " "); + + fprintf(TOP_SCREEN, "[%c] %s\n", (config.options[i] ? 'X' : ' '), list[i]); + } + + uint32_t key = wait_key(); + + switch(key) { + case BUTTON_UP: + cursor_y -= 1; + break; + case BUTTON_DOWN: + cursor_y += 1; + break; + case BUTTON_A: + // TODO - Value options + config.options[cursor_y] = !config.options[cursor_y]; + break; + case BUTTON_B: + return MENU_MAIN; + break; + } + + // Loop around the cursor. + if (cursor_y < 0) + cursor_y = menu_max - 1; + if (cursor_y > menu_max - 1) + cursor_y = 0; + + return 0; +} + +int menu_info() { return MENU_MAIN; } + +int menu_help() { + clear_screen(TOP_SCREEN); + + set_cursor(TOP_SCREEN, 0, 0); + + header(); + + fprintf(stdout, "\nCorbenik is a 3DS firmware patcher\n" + " commonly known as a CFW. It seeks to address\n" + " some faults in other CFWs and is generally\n" + " just another choice for users - but primarily\n" + " the kind of person who runs Gentoo or LFS. ;P\n" + "\n" + "Credits to people who've helped me put this\n" + " together either by having written GPL code,\n" + " or being just generally helpful/cool people:\n" + " @mid-kid, @Wolfvak, @Reisyukaku, @AuroraWright\n" + " @d0k3, and others\n" + "\n" + "The name of this comes from the .hack//series.\n" + " Look it up, if you don't already know it.\n" + "\n" + "Any bugs filed including the letters S, A\n" + " and O will be closed with no discussion.\n" + "\n" + " \n" + "\n"); + while (1) { + if (wait_key() & BUTTON_ANY) + break; + } + + return MENU_MAIN; +} + +int menu_reset() { + fumount(); // Unmount SD. + + // Reboot. + fprintf(BOTTOM_SCREEN, "Resetting system.\n"); + i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); + while(1); +} + +int menu_poweroff() { + fumount(); // Unmount SD. + + // Reboot. + fprintf(BOTTOM_SCREEN, "Powering off system.\n"); + i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); + while(1); +} + +int menu_main() { + clear_screen(TOP_SCREEN); + + set_cursor(TOP_SCREEN, 0, 0); + + const char *list[] = { + "Options", + "Patches", + "Info", + "Help/Readme", + "Reset", + "Power off", + "Boot firmware" + }; + int menu_max = 6; + + header(); + + for(int i=0; i < menu_max; i++) { + if (!(i+2 == MENU_HELP && config.options[OPTION_READ_ME])) { + if (cursor_y == i) + fprintf(TOP_SCREEN, "\x1b[32m>>\x1b[0m "); + else + fprintf(TOP_SCREEN, " "); + fprintf(TOP_SCREEN, "%s\n", list[i]); + } + } + + uint32_t key = wait_key(); + + switch(key) { + case BUTTON_UP: + cursor_y -= 1; + if (config.options[OPTION_READ_ME] && cursor_y+2 == MENU_HELP) + cursor_y -= 1; // Disable help. + break; + case BUTTON_DOWN: + cursor_y += 1; + if (config.options[OPTION_READ_ME] && cursor_y+2 == MENU_HELP) + cursor_y += 1; // Disable help. + break; + case BUTTON_A: + return cursor_y+2; + break; + } + + // Loop around the cursor. + if (cursor_y < 0) + cursor_y = menu_max -1; + if (cursor_y > menu_max - 1) + cursor_y = 0; + + return 0; +} + +int menu_handler() { + int to_menu = 0; + switch(which_menu) { + case MENU_MAIN: + to_menu = menu_main(); + break; + case MENU_OPTIONS: + to_menu = menu_options(); + break; + case MENU_PATCHES: + to_menu = menu_patches(); + break; + case MENU_INFO: + to_menu = menu_info(); + break; + case MENU_HELP: + to_menu = menu_help(); + break; + case MENU_BOOTME: + return 0; + case MENU_RESET: + menu_reset(); + case MENU_POWER: + menu_poweroff(); + } + + if (to_menu != 0) + which_menu = to_menu; + + return 1; +} + diff --git a/source/patcher.c b/source/patcher.c new file mode 100644 index 0000000..422fd36 --- /dev/null +++ b/source/patcher.c @@ -0,0 +1,30 @@ +#include +#include "std/unused.h" +#include "std/memory.h" +#include "config.h" + +#define SIGNATURE_CHECK {0x00, 0x20} +#define SIGNATURE_CHECK_FIX {0x70, 0x60, 0x70, 0x47} + +int patch_firm_all() { + // Use builtin signature patcher? + if (config.options[OPTION_SIGPATCH]) { + // Yes. + // memfind( + } + + // Replace loader? + if (config.options[OPTION_LOADER]) { + // Yes. + + // This requires OPTION_SIGPATCH. + } + + // Use ARM9 hook thread? + if (config.options[OPTION_ARM9THREAD]) { + // Yes. + // FIXME - NYI + } + + return 0; +} diff --git a/source/patcher.h b/source/patcher.h new file mode 100644 index 0000000..0858829 --- /dev/null +++ b/source/patcher.h @@ -0,0 +1,6 @@ +#ifndef __PATCHER__ +#define __PATCHER__ + +int patch_firm_all(); + +#endif diff --git a/source/std/abort.h b/source/std/abort.h index b672e82..39ac0f4 100644 --- a/source/std/abort.h +++ b/source/std/abort.h @@ -1,8 +1,10 @@ #ifndef __ABORT_H #define __ABORT_H +#include "draw.h" + #define abort(x...) { \ - fprintf(2, x); \ + fprintf(stderr, x); \ fumount(); \ while(1); \ } diff --git a/source/std/draw.c b/source/std/draw.c index 35ece25..bb10b62 100644 --- a/source/std/draw.c +++ b/source/std/draw.c @@ -7,6 +7,7 @@ #include "font.h" #include "../fatfs/ff.h" #include "fs.h" +#include "unused.h" static unsigned int top_cursor_x = 0, top_cursor_y = 0; static unsigned int bottom_cursor_x = 0, bottom_cursor_y = 0; @@ -40,9 +41,10 @@ void clear_screen(uint8_t* screen) { uint32_t size = 0; char* buffer = 0; uint32_t buffer_size = 0; - if ((int)screen == TOP_SCREEN) + + if (screen == TOP_SCREEN) screen = framebuffers->top_left; - else if ((int)screen == BOTTOM_SCREEN) + else if (screen == BOTTOM_SCREEN) screen = framebuffers->bottom; if(screen == framebuffers->top_left || @@ -66,16 +68,13 @@ void clear_screen(uint8_t* screen) { memset(buffer, 0, buffer_size); } -void set_cursor(int channel, unsigned int x, unsigned int y) { - switch(channel) { - case TOP_SCREEN: - top_cursor_x = x; - top_cursor_y = y; - break; - case BOTTOM_SCREEN: - bottom_cursor_x = x; - bottom_cursor_y = y; - break; +void set_cursor(void* channel, unsigned int x, unsigned int y) { + if (channel == TOP_SCREEN) { + top_cursor_x = x; + top_cursor_y = y; + } else if (channel == BOTTOM_SCREEN) { + bottom_cursor_x = x; + bottom_cursor_y = y; } } @@ -88,7 +87,7 @@ void draw_character(uint8_t* screen, const char character, const unsigned int bu if (!isprint(character)) return; // Don't output non-printables. - int width = 0; + _UNUSED int width = 0; int height = 0; if(screen == framebuffers->top_left || screen == framebuffers->top_right) { @@ -127,9 +126,9 @@ unsigned char color_top = 0xf0; unsigned char color_bottom = 0xf0; void putc(void* buf, const int c) { - if ((int)buf == stdout || (int)buf == stderr) { + if (buf == stdout || buf == stderr) { unsigned int width = 0; - unsigned int height = 0; + _UNUSED unsigned int height = 0; unsigned int size = 0; unsigned int cursor_x; unsigned int cursor_y; @@ -138,7 +137,7 @@ void putc(void* buf, const int c) { unsigned char* color = NULL; - if ((int)buf == TOP_SCREEN) { + if (buf == TOP_SCREEN) { width = TEXT_TOP_WIDTH; height = TEXT_TOP_HEIGHT; size = TEXT_TOP_SIZE; @@ -147,7 +146,7 @@ void putc(void* buf, const int c) { cursor_x = top_cursor_x; cursor_y = top_cursor_y; color = &color_top; - } else if ((int)buf == BOTTOM_SCREEN) { + } else if (buf == BOTTOM_SCREEN) { width = TEXT_BOTTOM_WIDTH; height = TEXT_BOTTOM_HEIGHT; size = TEXT_BOTTOM_SIZE; @@ -193,10 +192,10 @@ void putc(void* buf, const int c) { break; } - if ((int)buf == TOP_SCREEN) { + if (buf == TOP_SCREEN) { top_cursor_x = cursor_x; top_cursor_y = cursor_y; - } else if ((int)buf == BOTTOM_SCREEN) { + } else if (buf == BOTTOM_SCREEN) { bottom_cursor_x = cursor_x; bottom_cursor_y = cursor_y; } @@ -273,7 +272,7 @@ void put_int(void* channel, int n, int length) { } void fflush(void* channel) { - if ((int)channel == TOP_SCREEN) { + if (channel == TOP_SCREEN) { for(int x=0; x < TEXT_TOP_WIDTH; x++) { for(int y=0; y < TEXT_TOP_HEIGHT; y++) { char c = text_buffer_top[y*TEXT_TOP_WIDTH+x]; @@ -282,7 +281,7 @@ void fflush(void* channel) { draw_character(framebuffers->top_left, c, x, y, color_fg, color_bg); } } - } else if ((int)channel == BOTTOM_SCREEN) { + } else if (channel == BOTTOM_SCREEN) { for(int x=0; x < TEXT_BOTTOM_WIDTH; x++) { for(int y=0; y < TEXT_BOTTOM_HEIGHT; y++) { char c = text_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x]; @@ -303,13 +302,13 @@ void fprintf(void* channel, const char* format, ...) { char *ref = (char*)format; unsigned char* color; - if ((int)channel == TOP_SCREEN) + if (channel == TOP_SCREEN) color = &color_top; - else if ((int)channel == TOP_SCREEN) + else if (channel == TOP_SCREEN) color = &color_bottom; while(*ref != '\0') { - if (*ref == 0x1B && *(++ref) == '[' && ( (int)channel == stdout || (int)channel == stderr) ) { + if (*ref == 0x1B && *(++ref) == '[' && ( channel == stdout || channel == stderr) ) { ansi_codes: // Ansi escape code. ++ref; diff --git a/source/std/draw.h b/source/std/draw.h index df90863..77023c4 100644 --- a/source/std/draw.h +++ b/source/std/draw.h @@ -35,11 +35,14 @@ enum screen { screen_bottom }; -static struct framebuffers { +#include "unused.h" + +_UNUSED static struct framebuffers { uint8_t *top_left; uint8_t *top_right; uint8_t *bottom; } *framebuffers = (struct framebuffers *)0x23FFFE00; +// This is marked unused since it occurs in all files. #define TOP_FB framebuffers->top_left #define BOTTOM_FB framebuffers->bottom @@ -48,8 +51,8 @@ void clear_screen(uint8_t* screen); void clear_screens(); void draw_character(uint8_t* screen, const char character, const unsigned int pos_x, const unsigned int pos_y, const uint32_t color_fg, const uint32_t color_bg); -#define TOP_SCREEN 0 -#define BOTTOM_SCREEN 2 +#define TOP_SCREEN ((void*)0) +#define BOTTOM_SCREEN ((void*)2) #define stdout TOP_SCREEN #define stderr BOTTOM_SCREEN @@ -58,7 +61,7 @@ void putc(void* buf, const int c); void puts(void* buf, const char *string); void fflush(void* channel); -void set_cursor(int channel, unsigned int x, unsigned int y); +void set_cursor(void* channel, unsigned int x, unsigned int y); // Like printf. Supports the following format specifiers: // %s - char* diff --git a/source/std/unused.h b/source/std/unused.h new file mode 100644 index 0000000..b66bf0e --- /dev/null +++ b/source/std/unused.h @@ -0,0 +1 @@ +#define _UNUSED __attribute__((unused))