diff --git a/resources/app_booter/source/main.c b/resources/app_booter/source/main.c index 23b73a11..8561e882 100644 --- a/resources/app_booter/source/main.c +++ b/resources/app_booter/source/main.c @@ -11,7 +11,7 @@ #include "sync.h" #define EXECUTABLE_MEM_ADDR 0x92000000 -#define SYSTEM_ARGV ((struct __argv *)0x90100000) +#define SYSTEM_ARGV ((struct __argv *)0x93300800) void _main(void) { diff --git a/source/gc/gc.cpp b/source/gc/gc.cpp index 9b0c01a2..2d438132 100644 --- a/source/gc/gc.cpp +++ b/source/gc/gc.cpp @@ -150,7 +150,8 @@ void DML_New_WriteOptions() // Nintendont NIN_CFG NinCfg; -u8 NinDevice; +u8 NinDevice = 0; +bool NinArgsboot = false; void Nintendont_SetOptions(const char *game, const char *gameID, u8 NMM, u8 videoSetting, bool widescreen) { NinDevice = DeviceHandle.PathToDriveType(game); @@ -192,6 +193,12 @@ void Nintendont_SetOptions(const char *game, const char *gameID, u8 NMM, u8 vide void Nintendont_WriteOptions() { + /* Newer Nintendont versions */ + if(NinArgsboot == true) + { + AddBootArgument((char*)&NinCfg, sizeof(NIN_CFG)); + return; + } /* general loader */ if(DeviceHandle.SD_Inserted()) { @@ -206,6 +213,19 @@ void Nintendont_WriteOptions() } } +bool Nintendont_Installed() +{ + for(u8 i = SD; i < MAXDEVICES; ++i) + { + const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]); + if(fsop_FileExist(dol_path) == true) + { + gprintf("Nintendont found\n"); + return true; + } + } + return false; +} bool Nintendont_GetLoader() { bool ret = false; @@ -217,6 +237,18 @@ bool Nintendont_GetLoader() { gprintf("Nintendont loaded: %s\n", dol_path); AddBootArgument(dol_path); + //search for argsboot + u32 size; + const char *dol_ptr = GetHomebrew(&size); + for(u32 i = 0; i < size; i += 0x10) + { + if(strncmp(dol_ptr + i, "argsboot", 8) == 0) + { + gprintf("Nintendont argsboot found at %08x\n", i); + NinArgsboot = true; + break; + } + } break; } } diff --git a/source/gc/gc.hpp b/source/gc/gc.hpp index 00f85047..9312323f 100644 --- a/source/gc/gc.hpp +++ b/source/gc/gc.hpp @@ -78,6 +78,7 @@ void DML_New_WriteOptions(); #define NIN_CFG_PATH "nincfg.bin" #define NIN_LOADER_PATH "%s:/apps/Nintendont/boot.dol" +bool Nintendont_Installed(); bool Nintendont_GetLoader(); void Nintendont_SetOptions(const char *game, const char *gameID, u8 NMM, u8 videoSetting, bool widescreen); void Nintendont_WriteOptions(); diff --git a/source/homebrew/homebrew.cpp b/source/homebrew/homebrew.cpp index f87556d3..f3cd6a72 100644 --- a/source/homebrew/homebrew.cpp +++ b/source/homebrew/homebrew.cpp @@ -16,9 +16,12 @@ static u8 *EXECUTE_ADDR = (u8*)0x92000000; static u8 *BOOTER_ADDR = (u8*)0x93300000; static entry BOOTER_ENTRY = (entry)BOOTER_ADDR; -static __argv *ARGS_ADDR = (__argv*)0x90100000; +static __argv *ARGS_ADDR = (__argv*)0x93300800; //more than twice as much as the appbooter, just for safety static char *CMD_ADDR = (char*)ARGS_ADDR + sizeof(struct __argv); +char *homebrew_ptr = NULL; +u32 homebrew_size = 0; + u8 *appbooter_ptr = NULL; u32 appbooter_size = 0; using namespace std; @@ -43,12 +46,18 @@ static bool IsSpecialELF(u8 *buf) return memcmp(buf, cmp1, sizeof(cmp1)) == 0 && memcmp(&buf[0x24], cmp2, sizeof(cmp2)) == 0; } -void AddBootArgument(const char * argv) +void AddBootArgument(const char *argv) { string arg(argv); Arguments.push_back(arg); } +void AddBootArgument(const char *argv, unsigned int size) +{ + string arg(argv, size); + Arguments.push_back(arg); +} + bool LoadAppBooter(const char *filepath) { u8 *tmp_ptr = fsop_ReadFile(filepath, &appbooter_size); @@ -80,10 +89,18 @@ bool LoadHomebrew(const char *filepath) { fsop_ReadFileLoc(filepath, filesize, EXECUTE_ADDR); DCFlushRange(EXECUTE_ADDR, filesize); + homebrew_ptr = (char*)EXECUTE_ADDR; + homebrew_size = filesize; } return true; } +char *GetHomebrew(unsigned int *size) +{ + *size = homebrew_size; + return homebrew_ptr; +} + static int SetupARGV() { __argv *args = ARGS_ADDR; @@ -103,7 +120,7 @@ static int SetupARGV() args->commandLine = CMD_ADDR; for(int i = 0; i < args->argc; i++) { - strcpy(&args->commandLine[position], Arguments[i].c_str()); + memcpy(&args->commandLine[position], Arguments[i].c_str(), Arguments[i].size() + 1); position += Arguments[i].size() + 1; } args->commandLine[args->length - 1] = '\0'; diff --git a/source/homebrew/homebrew.h b/source/homebrew/homebrew.h index 0656b6d1..90e90d20 100644 --- a/source/homebrew/homebrew.h +++ b/source/homebrew/homebrew.h @@ -5,8 +5,10 @@ typedef void (*entry)(void); void BootHomebrew(); -void AddBootArgument(const char * arg); -bool LoadHomebrew(const char * filepath); +void AddBootArgument(const char *argv); +void AddBootArgument(const char *argv, unsigned int size); +bool LoadHomebrew(const char *filepath); +char *GetHomebrew(unsigned int *size); bool LoadAppBooter(const char *filepath); void JumpToEntry(entry EntryPoint); void writeStub(); diff --git a/source/menu/menu.cpp b/source/menu/menu.cpp index cf322cd9..80fb17cc 100644 --- a/source/menu/menu.cpp +++ b/source/menu/menu.cpp @@ -371,6 +371,7 @@ void CMenu::init() m_plugin.init(m_pluginsDir); m_devo_installed = DEVO_Installed(m_dataDir.c_str()); + m_nintendont_installed = Nintendont_Installed(); const char *defLang = "Default"; switch (CONF_GetLanguage()) { diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index ecf3b714..7f977ad1 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -199,6 +199,7 @@ private: bool m_show_dml; bool m_sd_dm; bool m_devo_installed; + bool m_nintendont_installed; bool m_new_dml; bool m_new_dm_cfg; bool m_GameTDBLoaded; diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index a16e6860..4532ee93 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -923,7 +923,11 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) bool widescreen = m_gcfg2.getBool(id, "dm_widescreen", false); bool activity_led = m_gcfg2.getBool(id, "led", false); - u8 NMM = min((u32)m_gcfg2.getInt(id, "dml_nmm", 0), ARRAY_SIZE(CMenu::_NMM) - 1u); + if(loader == 2 && m_nintendont_installed == false) + loader = 0; + + //always enable for nintendont + u8 NMM = (loader == 2) ? 2 : min((u32)m_gcfg2.getInt(id, "dml_nmm", 0), ARRAY_SIZE(CMenu::_NMM) - 1u); NMM = (NMM == 0) ? m_cfg.getInt(GC_DOMAIN, "dml_nmm", 0) : NMM-1; //if GC disc use DIOS MIOS to launch it @@ -935,30 +939,40 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) else m_cfg.setString(GC_DOMAIN, "current_item", id); - const char *mios_wad = NULL; if(loader == 0) //auto selected { - gprintf("Auto installing MIOS\n"); - _showWaitMessage(); - if(_QF_Game(id) == true) + if(IsOnWiiU()) { - if(currentPartition == SD && (m_mios_ver != 2 || m_sd_dm == false)) - mios_wad = fmt("%s/qfsd.wad", m_miosDir.c_str()); - else if(currentPartition != SD && (m_mios_ver != 2 || m_sd_dm == true)) - mios_wad = fmt("%s/qfusb.wad", m_miosDir.c_str()); + if(m_nintendont_installed) + loader = 2; + else if(m_devo_installed) + loader = 1; } - else if(disc == false) + else { - if(currentPartition == SD && (m_mios_ver != 1 || m_sd_dm == false)) - mios_wad = fmt("%s/dml.wad", m_miosDir.c_str()); - else if(currentPartition != SD && (m_mios_ver != 1 || m_sd_dm == true)) - mios_wad = fmt("%s/dm.wad", m_miosDir.c_str()); + gprintf("Auto installing MIOS\n"); + const char *mios_wad = NULL; + _showWaitMessage(); + if(_QF_Game(id) == true) + { + if(currentPartition == SD && (m_mios_ver != 2 || m_sd_dm == false)) + mios_wad = fmt("%s/qfsd.wad", m_miosDir.c_str()); + else if(currentPartition != SD && (m_mios_ver != 2 || m_sd_dm == true)) + mios_wad = fmt("%s/qfusb.wad", m_miosDir.c_str()); + } + else if(disc == false) + { + if(currentPartition == SD && (m_mios_ver != 1 || m_sd_dm == false)) + mios_wad = fmt("%s/dml.wad", m_miosDir.c_str()); + else if(currentPartition != SD && (m_mios_ver != 1 || m_sd_dm == true)) + mios_wad = fmt("%s/dm.wad", m_miosDir.c_str()); + } + else if(m_mios_ver != 0) + mios_wad = fmt("%s/mios.wad", m_miosDir.c_str()); + if(mios_wad != NULL && fsop_FileExist(mios_wad)) + _Wad(mios_wad, true);//install mios } - else if(m_mios_ver != 0) - mios_wad = fmt("%s/mios.wad", m_miosDir.c_str()); - if(mios_wad != NULL && fsop_FileExist(mios_wad)) - _Wad(mios_wad, true);//install mios } //copy DML game from USB to SD if needed for DML if(disc == false && loader == 0 && currentPartition != SD && m_sd_dm == true && strcasestr(hdr->path, ".iso") == NULL) @@ -1072,8 +1086,8 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) } else { - Nintendont_WriteOptions(); bool ret = (Nintendont_GetLoader() && LoadAppBooter(fmt("%s/app_booter.bin", m_binsDir.c_str()))); + Nintendont_WriteOptions(); ShutdownBeforeExit(); if(ret == true) { diff --git a/source/menu/menu_main.cpp b/source/menu/menu_main.cpp index bdc951b7..99d1645b 100644 --- a/source/menu/menu_main.cpp +++ b/source/menu/menu_main.cpp @@ -96,7 +96,7 @@ start_main: m_btnMgr.show(m_mainBtnUsb); break; default: - if(m_show_dml || m_devo_installed) + if(m_show_dml || m_devo_installed || m_nintendont_installed) m_btnMgr.show(m_mainBtnDML); else if (show_channel) m_btnMgr.show(m_mainBtnChannel); @@ -355,7 +355,7 @@ int CMenu::main(void) u8 lastView = m_current_view; if(BTN_UP_PRESSED) m_current_view = COVERFLOW_USB; - else if(BTN_DOWN_PRESSED && (m_show_dml ||m_devo_installed)) + else if(BTN_DOWN_PRESSED && (m_show_dml || m_devo_installed || m_nintendont_installed)) m_current_view = COVERFLOW_DML; else if(BTN_LEFT_PRESSED && show_emu) m_current_view = COVERFLOW_PLUGIN; @@ -413,7 +413,9 @@ int CMenu::main(void) else if(m_btnMgr.selected(m_mainBtnChannel) || m_btnMgr.selected(m_mainBtnUsb) || m_btnMgr.selected(m_mainBtnDML) || m_btnMgr.selected(m_mainBtnHomebrew) || m_btnMgr.selected(m_mainBtnEmu)) { if(m_current_view == COVERFLOW_USB) - m_current_view = (m_show_dml || m_devo_installed) ? COVERFLOW_DML : (show_channel ? COVERFLOW_CHANNEL : (show_emu ? COVERFLOW_PLUGIN : ((show_homebrew && (parental_homebrew || !m_locked)) ? COVERFLOW_HOMEBREW : COVERFLOW_USB))); + m_current_view = (m_show_dml || m_devo_installed || m_nintendont_installed) ? COVERFLOW_DML : + (show_channel ? COVERFLOW_CHANNEL : (show_emu ? COVERFLOW_PLUGIN : + ((show_homebrew && (parental_homebrew || !m_locked)) ? COVERFLOW_HOMEBREW : COVERFLOW_USB))); else if(m_current_view == COVERFLOW_DML) m_current_view = show_channel ? COVERFLOW_CHANNEL : ((show_emu ? COVERFLOW_PLUGIN : (show_homebrew && (parental_homebrew || !m_locked)) ? COVERFLOW_HOMEBREW : COVERFLOW_USB)); else if(m_current_view == COVERFLOW_CHANNEL) @@ -856,7 +858,7 @@ int CMenu::main(void) m_btnMgr.show(m_mainBtnUsb); break; default: - if(m_show_dml || m_devo_installed) + if(m_show_dml || m_devo_installed || m_nintendont_installed) m_btnMgr.show(m_mainBtnDML); else if(show_channel) m_btnMgr.show(m_mainBtnChannel); diff --git a/source/menu/menu_source.cpp b/source/menu/menu_source.cpp index 16039fc3..8edea1cf 100644 --- a/source/menu/menu_source.cpp +++ b/source/menu/menu_source.cpp @@ -194,7 +194,7 @@ void CMenu::_createSFList() string source = m_source.getString(btn_selected, "source",""); if(source == "") continue; - if(source == "dml" && !m_show_dml && !m_devo_installed) + if(source == "dml" && !m_show_dml && !m_devo_installed && !m_nintendont_installed) continue; else if(source == "emunand" && !show_channel) continue; @@ -529,7 +529,7 @@ bool CMenu::_Source() } if(m_btnMgr.selected(m_sourceBtnDML)) { - if(!m_show_dml && !m_devo_installed) + if(!m_show_dml && !m_devo_installed && !m_nintendont_installed) _showSourceNotice(); else { @@ -595,7 +595,7 @@ bool CMenu::_Source() } else if(source == "dml") { - if(!m_show_dml && !m_devo_installed) + if(!m_show_dml && !m_devo_installed && !m_nintendont_installed) _showSourceNotice(); else { @@ -736,7 +736,7 @@ bool CMenu::_Source() } else if(source == "dml") { - if(m_show_dml || m_devo_installed) + if(m_show_dml || m_devo_installed || m_nintendont_installed) m_cfg.setBool(GC_DOMAIN, "source", !m_cfg.getBool(GC_DOMAIN, "source")); } else if(source == "emunand")