Permalink
Comparing changes
Open a pull request
- 5 commits
- 13 files changed
- 0 commit comments
- 1 contributor
Unified
Split
Showing
with
794 additions
and 48 deletions.
- +63 −48 src/firmware.c
- +1 −0 src/hwinit/gfx.h
- +2 −0 src/hwinit/max77620.h
- +149 −0 src/menu/menu.c
- +44 −0 src/menu/menu.h
- +32 −0 src/menu/menu_entry.c
- +36 −0 src/menu/menu_entry.h
- +48 −0 src/menu/menu_pool.c
- +34 −0 src/menu/menu_pool.h
- +168 −0 src/menu/menu_tools.c
- +34 −0 src/menu/menu_tools.h
- +156 −0 src/reinx_menu.c
- +27 −0 src/reinx_menu.h
| @@ -22,6 +22,7 @@ | ||
| #include "error.h" | ||
| #include "bootloader.h" | ||
| #include "firmware.h" | ||
| #include "reinx_menu.h" | ||
| static pk11_offs *pk11Offs = NULL; | ||
| @@ -42,6 +43,59 @@ pk11_offs *pkg11_offsentify(u8 *pkg1) { | ||
| return NULL; | ||
| } | ||
| void patchFS(pkg2_kip1_info_t* ki) { | ||
| u8 kipHash[0x20]; | ||
| print("Patching FS\n"); | ||
| se_calc_sha256(&kipHash, ki->kip1, ki->size); | ||
| se_calc_sha256(&kipHash, ki->kip1, ki->size); | ||
| //Create header | ||
| size_t sizeDiff = ki->kip1->sections[0].size_decomp - ki->kip1->sections[0].size_comp; | ||
| size_t newSize = ki->size + sizeDiff; | ||
| pkg2_kip1_t *moddedKip = malloc(newSize); | ||
| memcpy(moddedKip, ki->kip1, newSize); | ||
| u32 pos = 0; | ||
| //Get decomp .text segment | ||
| u8 *kipDecompText = blz_decompress(moddedKip->data, moddedKip->sections[0].size_comp); | ||
| kippatchset_t *pset = kippatch_find_set(kipHash, kip_patches); | ||
| if (!pset) { | ||
| print(" could not find patchset with matching hash\n"); | ||
| } else { | ||
| int res = kippatch_apply_set(kipDecompText, moddedKip->sections[0].size_decomp, pset); | ||
| if (res) error("kippatch_apply_set() failed\n"); | ||
| } | ||
| moddedKip->flags &= ~1; | ||
| memcpy((void*)moddedKip->data, kipDecompText, moddedKip->sections[0].size_decomp); | ||
| free(kipDecompText); | ||
| pos += moddedKip->sections[0].size_comp; | ||
| moddedKip->sections[0].size_comp = moddedKip->sections[0].size_decomp; | ||
| for(int i = 1; i < KIP1_NUM_SECTIONS; i++) { | ||
| if(moddedKip->sections[i].offset != 0) { | ||
| memcpy((void*)moddedKip->data + pos + sizeDiff, (void*)ki->kip1->data + pos, moddedKip->sections[i].size_comp); | ||
| pos += moddedKip->sections[i].size_comp; | ||
| } | ||
| } | ||
| free(ki->kip1); | ||
| ki->size = newSize; | ||
| ki->kip1 = moddedKip; | ||
| } | ||
| pkg2_kip1_info_t* find_by_tid(link_t* kip_list, u64 tid) { | ||
| LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kip_list, link) { | ||
| if(ki->kip1->tid == 0x0100000000000000) | ||
| return ki; | ||
| } | ||
| return NULL; | ||
| } | ||
| void patch(pk11_offs *pk11, pkg2_hdr_t *pkg2, link_t *kips) { | ||
| //Patch Secmon | ||
| if(!customSecmon){ | ||
| @@ -224,53 +278,12 @@ void patch(pk11_offs *pk11, pkg2_hdr_t *pkg2, link_t *kips) { | ||
| end:; | ||
| } | ||
| u8 kipHash[0x20]; | ||
| //Patch FS module (truly not my proudest code TODO cleanup) | ||
| LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips, link) { | ||
| //Patch FS | ||
| if(ki->kip1->tid == 0x0100000000000000) { | ||
| print("Patching FS\n"); | ||
| se_calc_sha256(&kipHash, ki->kip1, ki->size); | ||
| se_calc_sha256(&kipHash, ki->kip1, ki->size); | ||
| //Create header | ||
| size_t sizeDiff = ki->kip1->sections[0].size_decomp - ki->kip1->sections[0].size_comp; | ||
| size_t newSize = ki->size + sizeDiff; | ||
| pkg2_kip1_t *moddedKip = malloc(newSize); | ||
| memcpy(moddedKip, ki->kip1, newSize); | ||
| u32 pos = 0; | ||
| for(int i = 0; i < KIP1_NUM_SECTIONS; i++) { | ||
| if(!i) { | ||
| //Get decomp .text segment | ||
| u8 *kipDecompText = blz_decompress(moddedKip->data, moddedKip->sections[i].size_comp); | ||
| kippatchset_t *pset = kippatch_find_set(kipHash, kip_patches); | ||
| if (!pset) { | ||
| print(" could not find patchset with matching hash\n"); | ||
| } else { | ||
| int res = kippatch_apply_set(kipDecompText, moddedKip->sections[i].size_decomp, pset); | ||
| if (res) error("kippatch_apply_set() failed\n"); | ||
| } | ||
| moddedKip->flags &= ~1; | ||
| memcpy((void*)moddedKip->data, kipDecompText, moddedKip->sections[i].size_decomp); | ||
| free(kipDecompText); | ||
| pos += moddedKip->sections[i].size_comp; | ||
| moddedKip->sections[i].size_comp = moddedKip->sections[i].size_decomp; | ||
| } else { | ||
| if(moddedKip->sections[i].offset == 0) continue; | ||
| memcpy((void*)moddedKip->data + pos + sizeDiff, (void*)ki->kip1->data + pos, moddedKip->sections[i].size_comp); | ||
| pos += moddedKip->sections[i].size_comp; | ||
| } | ||
| } | ||
| free(ki->kip1); | ||
| ki->size = newSize; | ||
| ki->kip1 = moddedKip; | ||
| } | ||
| pkg2_kip1_info_t* FS_module = find_by_tid(kips, 0x0100000000000000); | ||
| if(FS_module == NULL) { | ||
| error("Could not find FS Module.\n"); | ||
| } else { | ||
| patchFS(FS_module); | ||
| } | ||
| } | ||
| @@ -386,7 +399,7 @@ void launch() { | ||
| void firmware() { | ||
| display_init(); | ||
| gfx_init_ctxt(&gfx_ctxt, display_init_framebuffer(), 720, 1280, 768); | ||
| gfx_clear_color(&gfx_ctxt, 0xFF000000); | ||
| gfx_clear_color(&gfx_ctxt, BLACK); | ||
| gfx_con_init(&gfx_con, &gfx_ctxt); | ||
| gfx_con_setcol(&gfx_con, DEFAULT_TEXT_COL, 0, 0); | ||
| @@ -412,7 +425,9 @@ void firmware() { | ||
| PMC(APBDEV_PMC_SCRATCH49) = 0; | ||
| if (btn_read() & BTN_VOL_DOWN) { | ||
| print("Booting verbosely\n"); | ||
| print("Running in verbose mode!\n"); | ||
| } else if (btn_read() & BTN_VOL_UP) { | ||
| init_reinx_menu(); | ||
| } else if (drawSplash()) { | ||
| gfx_con.mute = 1; | ||
| } | ||
| @@ -26,6 +26,7 @@ | ||
| #define YELLOW 0xFF00FFFF | ||
| #define ORANGE 0xFF3891FF | ||
| #define WHITE 0xFFFFFFFF | ||
| #define BLACK 0xFF000000 | ||
| typedef struct _gfx_ctxt_t | ||
| { | ||
| @@ -11,6 +11,8 @@ | ||
| #ifndef _MFD_MAX77620_H_ | ||
| #define _MFD_MAX77620_H_ | ||
| #define MAX77620_I2C_ADDR 0x3C | ||
| /* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */ | ||
| #define MAX77620_REG_CNFGGLBL1 0x00 | ||
| #define MAX77620_REG_CNFGGLBL2 0x01 | ||
| @@ -0,0 +1,149 @@ | ||
| /* | ||
| * Copyright (c) 2018 Guillem96 | ||
| * | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms and conditions of the GNU General Public License, | ||
| * version 2, as published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| #include "menu.h" | ||
| #include "menu_pool.h" | ||
| menu_t *menu_create(const char *title) | ||
| { | ||
| menu_t *menu = (menu_t *)malloc(sizeof(menu_t)); | ||
| strcpy(menu->title, title); | ||
| menu->next_entry = 0; | ||
| menu->selected_index = 0; | ||
| push_to_pool(menu); | ||
| return menu; | ||
| } | ||
| menu_t *create_yes_no_menu(const char *action, | ||
| int (*on_yes)(void *), void *on_yes_param, | ||
| int (*on_no)(void *), void *on_no_param) | ||
| { | ||
| char buffer[0x100]; | ||
| strcpy(buffer, "Do you want to "); | ||
| strcat(buffer, action); | ||
| menu_t *menu = menu_create(buffer); | ||
| // Create yes entry | ||
| menu_entry_t *yes_entry = create_menu_entry("Yes", 0xFF, on_yes, on_yes_param); | ||
| // Create no entry | ||
| menu_entry_t *no_entry = create_menu_entry("No", 0xFF, on_no, on_no_param); | ||
| menu_append_entry(menu, yes_entry); | ||
| menu_append_entry(menu, no_entry); | ||
| push_to_pool(menu); | ||
| return menu; | ||
| } | ||
| void menu_append_entry(menu_t *menu, menu_entry_t *menu_entry) | ||
| { | ||
| if (menu->next_entry == MAX_ENTRIES) | ||
| return; | ||
| menu->entries[menu->next_entry] = menu_entry; | ||
| menu->next_entry++; | ||
| } | ||
| void menu_draw(menu_t *menu) | ||
| { | ||
| gfx_con_setpos(&gfx_con, 20, 50); | ||
| gfx_con.fntsz = 16; | ||
| gfx_printf(&gfx_con, "%k----- %s -----%k\n\n", 0xFFF45642, menu->title, WHITE); | ||
| for (size_t i = 0; i < menu->next_entry; i++) | ||
| { | ||
| if (i == menu->selected_index) | ||
| { | ||
| gfx_printf(&gfx_con, "%k-> %k%s%k\n", WHITE, menu->entries[i]->color, menu->entries[i]->text, WHITE); | ||
| } | ||
| else if (menu->entries[i]->handler == NULL) | ||
| { | ||
| gfx_printf(&gfx_con, "\n %k%s%k\n", menu->entries[i]->color, menu->entries[i]->text, WHITE); | ||
| } | ||
| else | ||
| { | ||
| gfx_printf(&gfx_con, "%k-> %k%s%k\n", BLACK, menu->entries[i]->color, menu->entries[i]->text, WHITE); | ||
| } | ||
| } | ||
| } | ||
| void skip_null_handlers(menu_t *menu, int direction) | ||
| { | ||
| while (menu->entries[menu->selected_index]->handler == NULL && | ||
| ((direction > 0 && menu->selected_index < menu->next_entry - 1) || | ||
| (direction < 0 && menu->selected_index > 0))) | ||
| { | ||
| menu->selected_index += direction; | ||
| } | ||
| if (menu->entries[menu->selected_index]->handler == NULL) | ||
| menu->selected_index -= direction; | ||
| } | ||
| int menu_update(menu_t *menu) | ||
| { | ||
| menu_entry_t *entry = NULL; | ||
| u32 input; | ||
| menu_draw(menu); | ||
| input = btn_wait(); | ||
| if ((input & BTN_VOL_UP) && menu->selected_index > 0) | ||
| { | ||
| menu->selected_index--; | ||
| skip_null_handlers(menu, -1); | ||
| } | ||
| else if ((input & BTN_VOL_DOWN) && menu->selected_index < menu->next_entry - 1) | ||
| { | ||
| menu->selected_index++; | ||
| skip_null_handlers(menu, 1); | ||
| } | ||
| else if (input & BTN_POWER) | ||
| { | ||
| entry = menu->entries[menu->selected_index]; | ||
| if (entry->handler != NULL) | ||
| { | ||
| gfx_clear_color(&gfx_ctxt, BLACK); | ||
| gfx_con_setpos(&gfx_con, 20, 50); | ||
| if (entry->handler(entry->param) != 0) | ||
| return 0; | ||
| gfx_clear_color(&gfx_ctxt, BLACK); | ||
| menu_draw(menu); | ||
| } | ||
| } | ||
| return 1; | ||
| } | ||
| int menu_open(menu_t *menu) | ||
| { | ||
| skip_null_handlers(menu, 1); | ||
| while (menu_update(menu)) | ||
| ; | ||
| return 0; | ||
| } | ||
| void menu_destroy(menu_t *menu) | ||
| { | ||
| for (int i = 0; i < menu->next_entry; i++) | ||
| free(menu->entries[i]); | ||
| free(menu->entries); | ||
| free(menu); | ||
| } |
| @@ -0,0 +1,44 @@ | ||
| /* | ||
| * Copyright (c) 2018 Guillem96 | ||
| * | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms and conditions of the GNU General Public License, | ||
| * version 2, as published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| #ifndef _MENU_H_ | ||
| #define _MENU_H_ | ||
| #include "../hwinit.h" | ||
| #include "../hwinit/types.h" | ||
| #include "menu_entry.h" | ||
| #define MAX_ENTRIES 0x10 | ||
| typedef struct | ||
| { | ||
| char title[0x100]; | ||
| int next_entry; | ||
| int selected_index; | ||
| menu_entry_t *entries[MAX_ENTRIES]; | ||
| } menu_t; | ||
| menu_t *menu_create(const char *title); | ||
| void menu_append_entry(menu_t *menu, menu_entry_t *menu_entry); | ||
| void menu_draw(menu_t *menu); | ||
| int menu_update(menu_t *menu); | ||
| int menu_open(menu_t *menu); | ||
| menu_t *create_yes_no_menu(const char *action, | ||
| int (*on_yes)(void *), void *on_yes_param, | ||
| int (*on_no)(void *), void *on_no_param); | ||
| void menu_destroy(menu_t *menu); | ||
| #endif |
| @@ -0,0 +1,32 @@ | ||
| /* | ||
| * Copyright (c) 2018 Guillem96 | ||
| * | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms and conditions of the GNU General Public License, | ||
| * version 2, as published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| #include "menu_entry.h" | ||
| menu_entry_t *create_menu_entry(const char *text, u32 color, int (*handler)(void *), void *param) | ||
| { | ||
| menu_entry_t *menu_entry = (menu_entry_t *)malloc(sizeof(menu_entry_t)); | ||
| strcpy(menu_entry->text, text); | ||
| menu_entry->color = color; | ||
| menu_entry->handler = handler; | ||
| menu_entry->param = param; | ||
| return menu_entry; | ||
| } | ||
| int cancel(void *param) | ||
| { | ||
| return -1; | ||
| } |
Oops, something went wrong.