diff --git a/data/stub.bin b/data/stub.bin new file mode 100644 index 00000000..48712078 Binary files /dev/null and b/data/stub.bin differ diff --git a/source/homebrew/homebrew.cpp b/source/homebrew/homebrew.cpp index 9e2a5202..a19ae52c 100644 --- a/source/homebrew/homebrew.cpp +++ b/source/homebrew/homebrew.cpp @@ -17,6 +17,9 @@ using namespace std; extern const u8 app_booter_bin[]; extern const u32 app_booter_bin_size; +extern const u8 stub_bin[]; +extern const u32 stub_bin_size; + typedef void (*entrypoint) (void); extern "C" { void __exception_closeall(); } @@ -101,7 +104,7 @@ static int SetupARGV(struct __argv * args) return 0; } -int BootHomebrew() +int BootHomebrew(bool wiiflow_stub) { struct __argv args; if (!IsDollZ(homebrewbuffer)) @@ -115,6 +118,16 @@ int BootHomebrew() memmove(ARGS_ADDR, &args, sizeof(args)); DCFlushRange(ARGS_ADDR, sizeof(args) + args.length); + if(wiiflow_stub) + { + /* Clear low mem - the hard way :P */ + memset((void*)0x80000000, 0, 0x4000); + + /* Copy stub into memory */ + memcpy((void*)0x80001800, stub_bin, stub_bin_size); + DCFlushRange((void*)0x80001800, stub_bin_size); + } + /* Shutdown IOS subsystems */ u32 level = IRQ_Disable(); __IOS_ShutdownSubsystems(); diff --git a/source/homebrew/homebrew.h b/source/homebrew/homebrew.h index c7fcdc7c..7092b9b4 100644 --- a/source/homebrew/homebrew.h +++ b/source/homebrew/homebrew.h @@ -1,7 +1,7 @@ #ifndef _BOOTHOMEBREW_H_ #define _BOOTHOMEBREW_H_ -int BootHomebrew(); +int BootHomebrew(bool wiiflow_stub); void AddBootArgument(const char * arg); int LoadHomebrew(const char * filepath); diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index cf8eb591..6eea08e1 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -642,7 +642,9 @@ void CMenu::_launch(dir_discHdr *hdr) string path((char*)hdr->path, size_t(strlen((char*)hdr->path) - title.size())); vector arguments; gprintf("Game title: %s\n", title.c_str()); - if(strstr(path.c_str(), ":/") != NULL) + if(m_plugin.isMplayerCE(hdr->hdr.magic)) + arguments = m_plugin.CreateMplayerCEArguments(string(hdr->path).c_str()); + else if(strstr(path.c_str(), ":/") != NULL) { if(strstr(path.c_str(), "sd:/") == NULL) path.erase(3,1); @@ -769,6 +771,7 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool DML) void CMenu::_launchHomebrew(const char *filepath, vector arguments) { + bool wiiflow_stub = m_cfg.getBool("HOMEBREW", "return_to_wiiflow", true); Nand::Instance()->Disable_Emu(); m_reload = true; @@ -796,9 +799,12 @@ void CMenu::_launchHomebrew(const char *filepath, vector arguments) USBStorage_Deinit(); AddBootArgument(filepath); for(u32 i = 0; i < arguments.size(); ++i) + { + gprintf("Boot argument: %s\n", arguments[i].c_str()); AddBootArgument(arguments[i].c_str()); + } gprintf("Booting Homebrew application...\n"); - BootHomebrew(); + BootHomebrew(wiiflow_stub); } int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id) diff --git a/source/plugin/plugin.cpp b/source/plugin/plugin.cpp index 7e7c027a..c87c3ad3 100644 --- a/source/plugin/plugin.cpp +++ b/source/plugin/plugin.cpp @@ -12,6 +12,8 @@ #include "memory/mem2.hpp" #include "gui/text.hpp" #include "gecko/gecko.h" +#include "devicemounter/PartitionHandle.h" +#include "devicemounter/DeviceHandler.hpp" static const string emptyString; static const string emptyString2("/"); @@ -217,3 +219,49 @@ vector Plugin::ParseScummvmINI(Config &ini, string Device) } return gameHeader; } + +/* Thanks to dimok for this */ +vector Plugin::CreateMplayerCEArguments(const char *filepath) +{ + vector args; + char dst[1024]; + + int i = 0; + char device[10]; + + while(filepath[i] != ':') + { + device[i] = filepath[i]; + device[i+1] = 0; + i++; + } + + char * ptr = (char *) &filepath[i]; + + while(ptr[0] != '/' || ptr[1] == '/') + ptr++; + + if(strncmp(DeviceHandler::PathToFSName(filepath), "NTF", 3) == 0) + { + sprintf(dst, "ntfs_usb:%s", ptr); + } + else if(strncmp(device, "usb", 3) == 0) + { + sprintf(dst, "usb:%s", ptr); + } + else + { + sprintf(dst, "%s:%s", device, ptr); + } + + args.push_back(dst); + args.push_back(string("-quiet")); + return args; +} + +bool Plugin::isMplayerCE(u32 magic) +{ + if((Plugin_Pos = GetPluginPosition(magic)) >= 0) + return (Plugins[Plugin_Pos].magicWord == 0x4D504345); + return false; +} diff --git a/source/plugin/plugin.hpp b/source/plugin/plugin.hpp index dfc7c397..4cce94fb 100644 --- a/source/plugin/plugin.hpp +++ b/source/plugin/plugin.hpp @@ -43,6 +43,8 @@ public: void SetEnablePlugin(Config &cfg, u8 pos, u8 ForceMode = 0); vector GetEnabledPlugins(Config &cfg); bool UseReturnLoader(u32 magic); + bool isMplayerCE(u32 magic); + vector CreateMplayerCEArguments(const char *src); void init(string); void Cleanup(); void EndAdd();