recovery_menu/ios_mcp/source/mcp_misc.h
GerbilSoft 73d3180edc
Fix Region Brick (and menu refactoring) (#11)
* menu.c: New menu drawing function drawMenu().

This function takes an array of Menu objects, which consist of a
description and a 64-bit parameter. It returns the selected index.

The parameter can be either a callback or a title ID. The callback
is a 32-bit pointer, so this does waste a bit of space, but I think
consolidating the menu code is worth it.

* fixup! menu.c: New menu drawing function drawMenu().

Cache the 'y' value; otherwise, selecting another index will go offscreen.

* option_SetColdbootTitle(): Use drawMenu().

drawMenu(): Add flags:

- MenuFlag_ShowTID: Append the title ID in hi-lo format.

- MenuFlag_NoClearScreen: Don't clear the screen. Useful if other stuff
  is displayed on the menu.

* drawMenu(): Optimize drawing by only redrawing changed items.

Split out the individual menu item drawing code into a separate function,
drawMenuItem().

The menu no longer flickers when selecting items.

FIXME: Set Coldboot Title's messages at the bottom aren't cleared
properly.

* option_SetColdbootTitle(): Clear the background behind the status text.

FIXME: Add a background color option to gfx_printf()?

* option_SetColdbootTitle(): Also clear behind the titles at the top.

* option_EditParental(): Use drawMenu().

* drawMenu(): Add a 'selected' parameter.

This lets us keep the same item selected when entering a submenu,
or even when applying an option and staying in the same submenu.

* option_FixRegionBrick(): Initial "Fix Region Brick" function.

Currently shows the system region code and installed Wii U Menu.

TODO:
- If they don't match, offer to fix it.
- Also verify that gameRegion contains productArea.

* option_FixRegionBrick(): Display game region and show errors.

Checking that both productArea and gameRegion match Wii U Menu.

For gameRegion, the Wii U Menu's region bit needs to be set, but it
doesn't need to be exclusive; however, the repair functionality will
make it exclusive.

* option_FixRegionBrick(): Prompt the user if they want to fix the region brick.

* option_FixRegionBrick(): Actually set the new region code.

Worked on the first try. 😄

mcp_misc.h: Implemented MCP_SetSysProdSettings().

* waitButtonInput(): Clear the message area before printing the text.

Otherwise, it might end up corrupted after fixing a region brick.

* waitButtonInput(): Blank out the entire screen width.

Otherwise, "POWER: Choose" will remain onscreen.

* option_FixRegionBrick(): Detect multiple install Wii U Menus and fail if found.

* gfx.h: Add the printf format attribute to gfx_printf().

menu.c: Fix gfx_printf() formats.

* menu.c: Use gfx_print() for constant strings with no format specifiers.

This slightly improves performance because gfx_printf() prints to an
internal buffer before calling gfx_print(), so calling gfx_print()
bypasses that step.

Removed the "Waiting for network connection... 5s" string by making it
use a printf() specifier. This adds some runtime overhead, but it
eliminates that string from the binary.

Code size difference:

   text    data     bss     dec     hex filename
  23068       0    8224   31292    7a3c ios_mcp.elf [before]
  23032       0    8224   31256    7a18 ios_mcp.elf [after]
    -36       0       0     -36     -24 Difference

* option_InstallWUP(): Print the title ID in hi-lo format.

* option_FixRegionBrick(): Minor code optimization.

Code size difference:

   text    data     bss     dec     hex filename
  23040       0    8224   31264    7a20 ios_mcp.elf [before]
  23016       0    8224   31240    7a08 ios_mcp.elf [after]
    -24       0       0     -24     -18 Difference

* README.md: Mention "Fix Region Brick".

* option_FixRegionBrick(): Pass 0 as 'selected' instead of the newly-declared 'selected'.

The newly-declared 'selected' will be uninitialized at this point.

* s/MCP_SetTargetUsb/MCP_InstallSetTargetUsb/

MCP_InstallSetTargetUsb() is the name listed on WiiUBrew:
https://wiiubrew.org/wiki//dev/mcp

* gfx_printf(): Replace 'alignRight' with a flags bitfield.

GfxPrintFlag_AlignRight does what alignRight did.
GfxPrintFlag_ClearBG clears the background before printing.
(TODO: Do this in gfx_draw_char() instead of calling
 gfx_draw_rect_filled().)

menu.c: Use GfxPrintFlag_ClearBG in some places instead of manually
clearing the background.

Code size difference:

   text    data     bss     dec     hex filename
  23016       0    8224   31240    7a08 ios_mcp.elf [before]
  22928       0    8224   31152    79b0 ios_mcp.elf [after]
    -88       0       0     -88     -58 Difference

* Move ARRAY_SIZE() from menu.c to utils.h.

* option_FixRegionBrick(): A few string simplifications.

- Use the same string for system and game region errors, with "%s" to
  differentiate them.

- Change the menu item from "Set Region to %s" to "Fix Region".
  "Set Region to %s" is redundant, since the question already says
  what region it will be changed to.

* option_EditParental(): A few more GfxPrintFlag_ClearBG uses.

* option_InstallWUP(): Fix error message for MCP_InstallSetTargetUsb().

* option_FixRegionBrick(): Combine two sets of if/else into one.

* menu.c: "Fix Region Brick" -> "Debug System Region"
2022-08-19 11:52:34 +02:00

43 lines
1.1 KiB
C

#pragma once
#include <assert.h>
#include <stdint.h>
typedef enum MCPRegion {
MCP_REGION_JAPAN = 0x01,
MCP_REGION_USA = 0x02,
MCP_REGION_EUROPE = 0x04,
MCP_REGION_CHINA = 0x10,
MCP_REGION_KOREA = 0x20,
MCP_REGION_TAIWAN = 0x40,
// Force MCPRegion to be 32-bit.
MCP_REGION_U32 = 0xFFFFFFFF,
} MCPRegion;
typedef struct __attribute__((packed)) _MCPSysProdSettings {
MCPRegion product_area;
uint16_t eeprom_version;
uint8_t pad1[2];
MCPRegion game_region;
uint8_t unknown1[4];
char ntsc_pal[5];
//! 5ghz_country_code in xml
char wifi_5ghz_country_code[4];
//! 5ghz_country_code_revision in xml
uint8_t wifi_5ghz_country_code_revision;
char code_id[8];
char serial_id[12];
uint8_t unknown2[4];
char model_number[16];
uint32_t version;
} MCPSysProdSettings;
static_assert(sizeof(MCPSysProdSettings) == 0x46, "MCPSysProdSettings: different size than expected");
int MCP_GetSysProdSettings(int handle, MCPSysProdSettings* out_sysProdSettings);
int MCP_SetSysProdSettings(int handle, const MCPSysProdSettings* sysProdSettings);