uint8_t options[256]; ///< Options in the menu - deliberately large to avoid
///< config version bumps.
+
+ char firm[3][256]; ///< FIRMS.
} __attribute__((packed));
#ifdef LOADER
#define OPTION_RECONFIGURED 255 ///< This is for internal use only. It's set when any changes
///< require caches to be regenerated.
+#define OPTION_NFIRM_PATH 0xFFFD
+#define OPTION_TFIRM_PATH 0xFFFE
+#define OPTION_AFIRM_PATH 0xFFFF
+
//#define HEADER_COLOR 12 // Color of header text.
//#define BG_COLOR 13 // Color of background.
//#define TEXT_COLOR 14 // Color of most text.
*/
void save_config();
-/* Changes an option according to internal rules.
+/* Changes an option according to internal rules. Used in menus.
*/
void change_opt(void* val);
*/
char* get_opt(void* val);
-/* Gets an option in raw form.
+/* Gets an option in uint32_t form.
+ */
+uint32_t get_opt_u32(uint32_t val);
+
+/* Sets an option in uint32_t form
*/
-uint32_t get_opt_raw(uint32_t val);
+int set_opt_u32(uint32_t key, uint32_t val);
-/* Sets an option in raw form
+/* Sets an option in uint32_t form
*/
-void set_opt_raw(uint32_t key, uint32_t val);
+int set_opt_str(uint32_t key, const char* val);
#endif
void screen_mode(uint32_t mode) {
static uint32_t stride, init_top, init_bottom, bright;
- bright = brightness[get_opt_raw(OPTION_BRIGHTNESS)];
+ bright = brightness[get_opt_u32(OPTION_BRIGHTNESS)];
stride = 240 * 3;
if (mode == RGBA8)
return str;
}
-uint32_t get_opt_raw(uint32_t val) {
+uint32_t get_opt_u32(uint32_t val) {
uint32_t opt = config->options[(uint32_t)val];
+
return opt;
}
-void set_opt_raw(uint32_t key, uint32_t val) {
+int set_opt_u32(uint32_t key, uint32_t val) {
+ if (key >= OPTION_NFIRM_PATH && key <= OPTION_AFIRM_PATH)
+ return 1;
+
config->options[(uint32_t)key] = (uint8_t)val;
+
+ return 0;
+}
+
+int set_opt_str(uint32_t key, const char* val) {
+ if (!(key >= OPTION_NFIRM_PATH && key <= OPTION_AFIRM_PATH))
+ return 1;
+
+ key -= OPTION_NFIRM_PATH;
+
+ strncpy(config->firm[key], val, 255);
+
+ return 0;
}
if (patch_firm_all() != 0)
return;
- if (get_opt_raw(OPTION_REBOOT)) {
+ if (get_opt_u32(OPTION_REBOOT)) {
fprintf(stderr, "Saving FIRM for reboot...\n");
if (!write_file(firm_loc, PATH_NATIVE_P, firm_size))
abort("Failed to save prepatched native\n");
void
wait()
{
- if (get_opt_raw(OPTION_TRACE) && !doing_autoboot) {
+ if (get_opt_u32(OPTION_TRACE) && !doing_autoboot) {
fprintf(stderr, "[Waiting...]");
wait_key(0); // No delay on traces.
}
#ifdef LOADER
if (config.options[OPTION_OVERLY_VERBOSE]) {
#else
- if (get_opt_raw(OPTION_OVERLY_VERBOSE)) {
+ if (get_opt_u32(OPTION_OVERLY_VERBOSE)) {
#endif
debug = 1;
}
installArm11Stub();
if (CFG_BOOTENV == 7)
- set_opt_raw(OPTION_EMUNAND, 0); // Disable EmuNAND on AGB reboot.
+ set_opt_u32(OPTION_EMUNAND, 0); // Disable EmuNAND on AGB reboot.
set_font(PATH_TERMFONT); // Read the font before all else.
clear_disp(TOP_SCREEN);
clear_disp(BOTTOM_SCREEN);
- if (get_opt_raw(OPTION_AUTOBOOT) && !r_held) {
+ if (get_opt_u32(OPTION_AUTOBOOT) && !r_held) {
doing_autoboot = 1;
- if (get_opt_raw(OPTION_SILENCE))
+ if (get_opt_u32(OPTION_SILENCE))
shut_up(); // This does exactly what it sounds like.
} else {
menu_handler();
header(const char *append)
{
set_cursor(TOP_SCREEN, 0, 0);
- fill_line(stdout, 0, get_opt_raw(OPTION_ACCENT_COLOR));
+ fill_line(stdout, 0, get_opt_u32(OPTION_ACCENT_COLOR));
accent_color(TOP_SCREEN, 0);
fprintf(stdout, "\x1b[30m ." FW_NAME " // %s\x1b[0m\n\n", append);
}
void accent_color(void* screen, int fg) {
char color[] = "\x1b[30m";
if (!fg) color[2] = '4';
- color[3] = ("01234567")[get_opt_raw(OPTION_ACCENT_COLOR)];
+ color[3] = ("01234567")[get_opt_u32(OPTION_ACCENT_COLOR)];
fprintf(screen, "%s", color);
}
}
}
-// This is dual purpose. When we actually list
-// patches to build the cache - desc_is_fname
-// will be set to 1.
-
-void
-list_patches_build(const char *name, int desc_is_fname)
-{
- desc_is_fname_sto = desc_is_fname;
-
- current_menu_index_patches = 0;
-
- if (!patches)
- patches = malloc(sizeof(struct options_s) * 258); // FIXME - hard limit. Implement realloc.
-
- patches[0].name = "Patches";
- patches[0].desc = "";
- patches[0].handle = unselectable;
- patches[0].indent = 0;
- patches[0].func = NULL;
- patches[0].value = NULL;
- patches[0].highlight = 1;
-
- current_menu_index_patches += 1;
-
- recurse_call(name, patch_func);
-
- patches[current_menu_index_patches].name = NULL;
-}
-
-void
-menu_patches()
-{
- show_menu(patches);
-}
-
-void
-menu_options()
-{
- show_menu(options);
-}
-
#ifndef REL
#define REL "master"
#endif
{ NULL, NULL, unselectable, 0, NULL, NULL, 0, 0 }, // cursor_min and cursor_max are stored in the last two.
};
-void
-menu_help()
-{
- show_menu(help_d);
-}
-
void
reset()
{
static struct options_s config_opts[] = {
{ "Options",
"Internal options for the CFW.\nThese are part of " FW_NAME " itself.",
- option, 0, menu_options, NULL, 0, 0 },
+ option, options, (void(*)(void*))show_menu, NULL, 0, 0 },
{ "Patches",
"External bytecode patches found in `" PATH_PATCHES "`.\nYou can choose which to enable.",
- option, 0, menu_patches, NULL, 0, 0 },
+ option, NULL, (void(*)(void*))show_menu, NULL, 0, 0 },
// Sentinel.
{ NULL, NULL, 0, 0, NULL, NULL, 0, 0 }, // cursor_min and cursor_max are stored in the last two.
};
+// This is dual purpose. When we actually list
+// patches to build the cache - desc_is_fname
+// will be set to 1.
+
+void
+list_patches_build(const char *name, int desc_is_fname)
+{
+ desc_is_fname_sto = desc_is_fname;
+
+ current_menu_index_patches = 0;
+
+ if (!patches)
+ patches = malloc(sizeof(struct options_s) * 258); // FIXME - hard limit. Implement realloc.
+
+ patches[0].name = "Patches";
+ patches[0].desc = "";
+ patches[0].handle = unselectable;
+ patches[0].indent = 0;
+ patches[0].func = NULL;
+ patches[0].value = NULL;
+ patches[0].highlight = 1;
+
+ current_menu_index_patches += 1;
+
+ recurse_call(name, patch_func);
+
+ patches[current_menu_index_patches].name = NULL;
+
+ config_opts[1].param = (void*)patches;
+}
+
void config_main_menu() {
show_menu(config_opts);
option, 0, config_main_menu, NULL, 0, 0 },
{ "Readme",
"Mini-readme.\nWhy are you opening help on this, though?\nThat's kind of silly.",
- option, 0, menu_help, NULL, 0, 0 },
+ option, help_d, (void(*)(void*))show_menu, NULL, 0, 0 },
{ "Reboot",
"Reboots the console.",
option, 0, reset, NULL, 0, 0 },
fprintf(stderr, "VM exited without issue\n");
// Hook firmlaunch?
- if (get_opt_raw(OPTION_REBOOT)) {
+ if (get_opt_u32(OPTION_REBOOT)) {
patch_reboot();
wait();
}
// Use EmuNAND?
- if (get_opt_raw(OPTION_EMUNAND)) {
+ if (get_opt_u32(OPTION_EMUNAND)) {
// Yes.
- patch_emunand(get_opt_raw(OPTION_EMUNAND_INDEX));
+ patch_emunand(get_opt_u32(OPTION_EMUNAND_INDEX));
wait();
}
// Inject services?
- if (get_opt_raw(OPTION_SVCS)) {
+ if (get_opt_u32(OPTION_SVCS)) {
if (patch_services()) {
abort("Fatal. Svc inject has failed.");
}
}
// Replace loader?
- if (get_opt_raw(OPTION_LOADER)) {
+ if (get_opt_u32(OPTION_LOADER)) {
if (patch_modules()) {
abort("Fatal. Loader inject has failed.");
}
}
void dump_log(unsigned int force) {
- if(!get_opt_raw(OPTION_SAVE_LOGS))
+ if(!get_opt_u32(OPTION_SAVE_LOGS))
return;
if (force == 0 && log_size < LOG_BUFFER_SIZE-1)
screen[j + 1] = top_bg[i];
screen[j + 2] = top_bg[i + 1];
screen[j + 3] = top_bg[i + 2];
- if (!kill_output && get_opt_raw(OPTION_DIM_MODE)) {
+ if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) {
screen[j + 1] = alphamap[screen[j + 1]];
screen[j + 2] = alphamap[screen[j + 2]];
screen[j + 3] = alphamap[screen[j + 3]];
screen[j + 1] = bottom_bg[i];
screen[j + 2] = bottom_bg[i + 1];
screen[j + 3] = bottom_bg[i + 2];
- if (!kill_output && get_opt_raw(OPTION_DIM_MODE)) {
+ if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) {
screen[j + 1] = alphamap[screen[j + 1]];
screen[j + 2] = alphamap[screen[j + 2]];
screen[j + 3] = alphamap[screen[j + 3]];
screen[pos + 1] = buffer_bg[pos_b];
screen[pos + 2] = buffer_bg[pos_b + 1];
screen[pos + 3] = buffer_bg[pos_b + 2];
- if (get_opt_raw(OPTION_DIM_MODE)) {
+ if (get_opt_u32(OPTION_DIM_MODE)) {
screen[pos + 1] = alphamap[screen[pos + 1]];
screen[pos + 2] = alphamap[screen[pos + 2]];
screen[pos + 3] = alphamap[screen[pos + 3]];
screen[pos + 1] = buffer_bg[pos_b];
screen[pos + 2] = buffer_bg[pos_b + 1];
screen[pos + 3] = buffer_bg[pos_b + 2];
- if (get_opt_raw(OPTION_DIM_MODE)) {
+ if (get_opt_u32(OPTION_DIM_MODE)) {
screen[pos + 1] = alphamap[screen[pos + 1]];
screen[pos + 2] = alphamap[screen[pos + 2]];
screen[pos + 3] = alphamap[screen[pos + 3]];
if (f_mount(NULL, "SD:", 1))
return 1;
- set_opt_raw(OPTION_SAVE_LOGS, 0); // FS unmounted, can't log anymore
+ set_opt_u32(OPTION_SAVE_LOGS, 0); // FS unmounted, can't log anymore
return 0;
}