diff --git a/Makefile b/Makefile index 21c37ec..2da3941 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ CFLAGS := -Wall -O0 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ -CXXFLAGS := $(CFLAGS) +CXXFLAGS := $(CFLAGS) -std=c++20 ASFLAGS := -g $(ARCH) LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld $(WUPSSPECS) diff --git a/src/ConfigUtils.cpp b/src/ConfigUtils.cpp index 79768d0..bf7977c 100644 --- a/src/ConfigUtils.cpp +++ b/src/ConfigUtils.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,15 @@ #define MAX_BUTTONS_ON_SCREEN 8 +template +std::string string_format(const std::string &format, Args... args) { + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' + auto size = static_cast(size_s); + auto buf = std::make_unique(size); + std::snprintf(buf.get(), size, format.c_str(), args...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + static uint32_t remapWiiMoteButtons(uint32_t buttons) { uint32_t conv_buttons = 0; @@ -205,7 +215,7 @@ void ConfigUtils::displayMenu() { } } - if (buttonsTriggered & VPAD_BUTTON_HOME) { + if (buttonsTriggered & (VPAD_BUTTON_A)) { break; } @@ -277,24 +287,29 @@ void ConfigUtils::displayMenu() { DrawUtils::setFontColor(COLOR_TEXT); DrawUtils::setFontSize(24); + std::string regionText = region_map[curSelectedRegion]; if (selectedBtn == 0) { DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED); + regionText = string_format("%s%s%s", curRegionIndex > 0 ? "< " : " ", regionText.c_str(), curRegionIndex < region_map.size() - 1 ? " >" : "").c_str(); } else { DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER); } DrawUtils::print(16 * 2, index + 8 + 24, "Region"); - DrawUtils::print(SCREEN_WIDTH - 16 * 2, index + 8 + 24, region_map[curSelectedRegion], true); + DrawUtils::print(SCREEN_WIDTH - 16 * 2, index + 8 + 24, regionText.c_str(), true); index += 42 + 8; + std::string languageText = lang_map[curSelectedLanguage]; if (selectedBtn == 1) { DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED); + languageText = string_format("%s%s%s", curLangIndex > 0 ? "< " : " ", languageText.c_str(), curLangIndex < lang_map.size() - 1 ? " >" : "").c_str(); } else { DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER); } DrawUtils::print(16 * 2, index + 8 + 24, "Language"); - DrawUtils::print(SCREEN_WIDTH - 16 * 2, index + 8 + 24, lang_map[curSelectedLanguage], true); + + DrawUtils::print(SCREEN_WIDTH - 16 * 2, index + 8 + 24, languageText.c_str(), true); index += 42 + 8; @@ -302,7 +317,7 @@ void ConfigUtils::displayMenu() { DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); DrawUtils::setFontSize(18); DrawUtils::print(16, SCREEN_HEIGHT - 8, "\ue07d Navigate "); - DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 8, "\ue001 Back", true); + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 8, "\ue000 Select", true); DrawUtils::endDraw(); redraw = false; diff --git a/src/globals.cpp b/src/globals.cpp index b2c91aa..a98989d 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -1,6 +1,7 @@ #include "globals.h" int gPreferSystemSettings = 1; +int gSkipOwnRegion = 1; int gAutoDetection = 1; int gForceSettingsEnabled = 0; Lanuages gDefaultLanguage = LANG_ENGLISH; diff --git a/src/globals.h b/src/globals.h index 5b3d5e0..511cfd5 100644 --- a/src/globals.h +++ b/src/globals.h @@ -18,6 +18,7 @@ enum Lanuages { extern int gPreferSystemSettings; +extern int gSkipOwnRegion; extern int gAutoDetection; extern Lanuages gDefaultLanguage; extern int32_t gDefaultCountry; diff --git a/src/main.cpp b/src/main.cpp index 48b95a5..ff54b2c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include "ConfigUtils.h" #include "globals.h" #include "utils/logger.h" +#include #include #include #include @@ -34,6 +35,7 @@ DECL_FUNCTION(int32_t, ACPGetLaunchMetaXml, ACPMetaXml *metaxml) { if (metaxml != nullptr) { metaxml->region = 0xFFFFFFFF; } + return result; } @@ -62,13 +64,6 @@ DECL_FUNCTION(int, UCReadSysConfig, int IOHandle, int count, struct UCSysConfig return result; } -ON_APPLICATION_ENDS() { - gCurrentLanguage = gDefaultLanguage; - gCurrentCountry = gDefaultCountry; - gCurrentProductArea = gDefaultProductArea; - deinitLogging(); -} - #define CAT_GENERAL_ROOT "root" #define CAT_GENERAL_SETTINGS "general_settings" #define CAT_TITLE_SETTINGS "title_settings" @@ -77,6 +72,7 @@ ON_APPLICATION_ENDS() { #define VAL_COUNTRY "cntry_reg" #define VAL_PRODUCT_AREA "product_area" +#define VAL_SKIP_OWN_REGION "skip_own_region" #define VAL_PREFER_SYSTEM_SETTINGS "prefer_system_settings" #define VAL_AUTO_DETECTION "auto_detection" #define VAL_DEFAULT_LANG_EUR "default_lang_eur" @@ -98,7 +94,7 @@ DECL_FUNCTION(int32_t, ACPGetTitleMetaXmlByDevice, uint32_t titleid_upper, uint3 return result; } -ON_FUNCTIONS_PATCHED() { +void bootStuff() { MCPRegion real_product_area; auto real_product_area_valid = getRealProductArea(&real_product_area); if (real_product_area_valid) { @@ -119,7 +115,7 @@ ON_FUNCTIONS_PATCHED() { } bool forceConfigMenu = false; - auto *acpMetaXml = (ACPMetaXml *) memalign(0x40, 0x4000); + auto *acpMetaXml = (ACPMetaXml *) memalign(0x40, sizeof(ACPMetaXml)); memset(acpMetaXml, 0, sizeof(ACPMetaXml)); auto regionFromXML = 0; @@ -238,8 +234,26 @@ ON_FUNCTIONS_PATCHED() { gCurrentProductArea = gDefaultProductArea; } + bool isWiiUMenu = false; + if (OSGetTitleID() == 0x0005001010040000L || // Wii U Menu JPN + OSGetTitleID() == 0x0005001010040100L || // Wii U Menu USA + OSGetTitleID() == 0x0005001010040200L) { // Wii U Menu EUR + isWiiUMenu = true; + } + + bool showMenu = !gAutoDetection; + + if (real_product_area_valid && (regionFromXML & real_product_area) == real_product_area) { + if (gSkipOwnRegion && !forceConfigMenu) { + // If the want to skip checks for own region and we were able + // to tell the region of the current title don't show the menu. + showMenu = false; + return; + } + } + // this overrides the current settings - if (forceConfigMenu || !gAutoDetection) { + if (forceConfigMenu || (!isWiiUMenu && showMenu)) { ConfigUtils::openConfigMenu(); // Save settings to storage WUPS_StoreInt(curTitleItem, VAL_LANGUAGE, gCurrentLanguage); @@ -251,8 +265,6 @@ ON_FUNCTIONS_PATCHED() { DEBUG_FUNCTION_LINE("Country will be force to %d", gDefaultCountry); DEBUG_FUNCTION_LINE("Product Area will be forced to %d", gCurrentProductArea); } - - WUPS_CloseStorage(); } ON_APPLICATION_START() { @@ -278,6 +290,10 @@ ON_APPLICATION_START() { WUPS_StoreInt(general_settings, VAL_PREFER_SYSTEM_SETTINGS, gPreferSystemSettings); } + if (WUPS_GetInt(general_settings, VAL_SKIP_OWN_REGION, (int32_t *) &gSkipOwnRegion) != WUPS_STORAGE_ERROR_SUCCESS) { + WUPS_StoreInt(general_settings, VAL_SKIP_OWN_REGION, gSkipOwnRegion); + } + if (WUPS_GetInt(general_settings, VAL_DEFAULT_LANG_EUR, (int32_t *) &gDefaultLangForEUR) != WUPS_STORAGE_ERROR_SUCCESS) { WUPS_StoreInt(general_settings, VAL_DEFAULT_LANG_EUR, gDefaultLangForEUR); } @@ -309,6 +325,10 @@ ON_APPLICATION_START() { gForceSettingsEnabled = 0; } DEBUG_FUNCTION_LINE("Start done"); + + bootStuff(); + + WUPS_CloseStorage(); } void auto_detection_changed(ConfigItemBoolean *item, bool newValue) { @@ -345,6 +365,23 @@ void prefer_system_changed(ConfigItemBoolean *item, bool newValue) { gPreferSystemSettings = newValue; } +void skip_own_region_changed(ConfigItemBoolean *item, bool newValue) { + DEBUG_FUNCTION_LINE("New value in skip_own_region_changed changed: %d", newValue); + + wups_storage_item_t *root; + if (WUPS_GetSubItem(nullptr, CAT_GENERAL_ROOT, &root) != WUPS_STORAGE_ERROR_SUCCESS) { + return; + } + + wups_storage_item_t *general_settings; + if (WUPS_GetSubItem(root, CAT_GENERAL_SETTINGS, &general_settings) != WUPS_STORAGE_ERROR_SUCCESS) { + return; + } + + WUPS_StoreInt(general_settings, VAL_SKIP_OWN_REGION, newValue); + gPreferSystemSettings = newValue; +} + void default_lang_changed(ConfigItemMultipleValues *item, uint32_t newValue) { DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configID, newValue); @@ -394,8 +431,9 @@ WUPS_GET_CONFIG() { WUPSConfigCategoryHandle cat; WUPSConfig_AddCategoryByNameHandled(config, "Settings", &cat); - WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, VAL_DEFAULT_LANG_USA, "Auto Detection", gAutoDetection, &auto_detection_changed); - WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, VAL_PREFER_SYSTEM_SETTINGS, "Prefer System Settings For Own Region", gPreferSystemSettings, &prefer_system_changed); + WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, VAL_DEFAULT_LANG_USA, "Auto detect region/language", gAutoDetection, &auto_detection_changed); + WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, VAL_PREFER_SYSTEM_SETTINGS, "Prefer system language for in-region titles", gPreferSystemSettings, &prefer_system_changed); + WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, VAL_SKIP_OWN_REGION, "Skip check for in-region titles", gSkipOwnRegion, &skip_own_region_changed); std::map eur_lang_map{ {LANG_ENGLISH, "English"}, @@ -432,7 +470,6 @@ WUPS_GET_CONFIG() { WUPSConfigItemMultipleValues_AddToCategoryHandled(config, cat, VAL_DEFAULT_LANG_USA, "Default Language for USA", default_index_usa, lang_usa_pair, number_lang_usa_values, &default_lang_changed); - return config; } @@ -582,6 +619,13 @@ DECL_FUNCTION(uint64_t, _SYSGetSystemApplicationTitleIdByProdArea, SYSTEM_APP_ID return res; } +ON_APPLICATION_ENDS() { + gCurrentLanguage = gDefaultLanguage; + gCurrentCountry = gDefaultCountry; + gCurrentProductArea = gDefaultProductArea; + deinitLogging(); +} + WUPS_MUST_REPLACE(ACPGetTitleMetaXmlByDevice, WUPS_LOADER_LIBRARY_NN_ACP, ACPGetTitleMetaXmlByDevice); WUPS_MUST_REPLACE(ACPGetLaunchMetaXml, WUPS_LOADER_LIBRARY_NN_ACP, ACPGetLaunchMetaXml); WUPS_MUST_REPLACE(MCP_GetSysProdSettings, WUPS_LOADER_LIBRARY_COREINIT, MCP_GetSysProdSettings);