From df76e45150bb653d0ae2609db5465606c17f2ece Mon Sep 17 00:00:00 2001 From: wiidev Date: Sun, 1 Jan 2023 17:00:35 +0000 Subject: [PATCH] Add SD card mode - This allows you to play your Wii games from an SD card - It currently only supports 1 partition - I've tested it with a 256GB Amazon Basics microSDXC card --- Languages/czech.lang | 6 + Languages/danish.lang | 6 + Languages/dutch.lang | 6 + Languages/english.lang | 6 + Languages/finnish.lang | 6 + Languages/french.lang | 6 + Languages/german.lang | 6 + Languages/greek.lang | 6 + Languages/hungarian.lang | 6 + Languages/italian.lang | 6 + Languages/japanese.lang | 6 + Languages/korean.lang | 6 + Languages/norwegian.lang | 6 + Languages/polish.lang | 6 + Languages/portuguese_br.lang | 6 + Languages/portuguese_pt.lang | 6 + Languages/russian.lang | 6 + Languages/schinese.lang | 6 + Languages/spanish.lang | 6 + Languages/swedish.lang | 6 + Languages/tchinese.lang | 6 + Languages/thai.lang | 6 + Languages/turkish.lang | 6 + source/Controls/DeviceHandler.cpp | 6 +- source/Controls/DeviceHandler.hpp | 12 +- source/Controls/PartitionHandle.cpp | 2 +- source/StartUpProcess.cpp | 57 +++++-- source/StartUpProcess.h | 2 + source/cache/cache.cpp | 15 +- source/libs/libwbfs/libwbfs.h | 5 +- source/libs/libwbfs/wiidisc.c | 180 ++++++++++++----------- source/menu/GameBrowseMenu.cpp | 7 +- source/menu/menu_install.cpp | 4 +- source/prompts/PromptWindows.cpp | 14 +- source/settings/CSettings.cpp | 2 +- source/settings/CSettings.h | 1 + source/settings/menus/HardDriveSM.cpp | 140 ++++++++++++------ source/settings/menus/HardDriveSM.hpp | 1 + source/settings/menus/LoaderSettings.cpp | 10 +- source/settings/meta.cpp | 6 +- source/system/IosLoader.cpp | 6 +- source/usbloader/GameBooter.cpp | 58 ++++++-- source/usbloader/GameList.cpp | 2 +- source/usbloader/GameList.h | 1 + source/usbloader/MountGamePartition.cpp | 63 ++++++-- source/usbloader/frag.c | 13 +- source/usbloader/frag.h | 4 +- source/usbloader/sdhc.c | 2 +- source/usbloader/sdhc.h | 1 - source/usbloader/wbfs.cpp | 58 +++++--- source/usbloader/wbfs/wbfs_base.cpp | 2 +- source/usbloader/wbfs/wbfs_fat.cpp | 20 ++- source/usbloader/wbfs/wbfs_wbfs.cpp | 5 +- source/wad/nandtitle.cpp | 1 - svnrev.sh | 1 + 55 files changed, 613 insertions(+), 226 deletions(-) diff --git a/Languages/czech.lang b/Languages/czech.lang index 8f242671..492e9e27 100644 --- a/Languages/czech.lang +++ b/Languages/czech.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Zbývá:" diff --git a/Languages/danish.lang b/Languages/danish.lang index 06006847..3a57d8df 100644 --- a/Languages/danish.lang +++ b/Languages/danish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SD-kortet kunne ikke tilgås." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD GameCube Spil Sti" @@ -2206,6 +2209,9 @@ msgstr "Dette spil har flere disks. Vælg venligst disken der skal startes." msgid "This path must be on SD!" msgstr "Denne sti skal være på SD!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tid tilbage:" diff --git a/Languages/dutch.lang b/Languages/dutch.lang index 9499c990..95008b6f 100644 --- a/Languages/dutch.lang +++ b/Languages/dutch.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "Geen toegang tot SD kaart." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD GameCube Spellen Pad" @@ -2206,6 +2209,9 @@ msgstr "Dit spel heeft meerdere disks. Geef aub aan welke er gestart dient te wo msgid "This path must be on SD!" msgstr "Dit pad moet op de SD kaart zijn!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tijd resterend:" diff --git a/Languages/english.lang b/Languages/english.lang index 909d3226..b2af19e3 100644 --- a/Languages/english.lang +++ b/Languages/english.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "" diff --git a/Languages/finnish.lang b/Languages/finnish.lang index f9975d39..a7689833 100644 --- a/Languages/finnish.lang +++ b/Languages/finnish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Aikaa jäljellä:" diff --git a/Languages/french.lang b/Languages/french.lang index f63bfb52..fa989783 100644 --- a/Languages/french.lang +++ b/Languages/french.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "Impossible d'accéder à la carte SD." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "Dossier GameCube sur la carte SD" @@ -2206,6 +2209,9 @@ msgstr "Ce jeu a plusieurs disques, choisissez celui que vous souhaitez lancer." msgid "This path must be on SD!" msgstr "Ce chemin doit être situé sur la carte SD !" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Fini dans:" diff --git a/Languages/german.lang b/Languages/german.lang index 6ead166c..a95572de 100644 --- a/Languages/german.lang +++ b/Languages/german.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "Auf die SD konnte nicht zugegriffen werden." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD GameCube Spiele" @@ -2206,6 +2209,9 @@ msgstr "Dieses Spiel hat mehrere Disks. Bitte wähle, welche Disk gestartet werd msgid "This path must be on SD!" msgstr "Dieser Pfad muss auf der SD sein!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Noch:" diff --git a/Languages/greek.lang b/Languages/greek.lang index 1930a488..66ba37d6 100644 --- a/Languages/greek.lang +++ b/Languages/greek.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "Μη προσπελάσιμη SD." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "Τοποθεσία/μονοπάτι τίτλων GameCube στην κάρτα SD" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "Το μονοπάτι αυτό πρέπει να κατευθύνει σε αρχείο στην κάρτα SD!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Χρόνος που απομένει:" diff --git a/Languages/hungarian.lang b/Languages/hungarian.lang index 565edfac..e547ab8e 100644 --- a/Languages/hungarian.lang +++ b/Languages/hungarian.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Hátralevõ idõ" diff --git a/Languages/italian.lang b/Languages/italian.lang index 89c6832e..83697d5d 100644 --- a/Languages/italian.lang +++ b/Languages/italian.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SD inacessibile." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "Percorso giochi Gamecube su SD" @@ -2206,6 +2209,9 @@ msgstr "Questo gioco contiene più di un disco. Selezione quello da avviare." msgid "This path must be on SD!" msgstr "Questo percorso deve essere sulla SD!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tempo rimasto:" diff --git a/Languages/japanese.lang b/Languages/japanese.lang index 8e3be54a..2f44fc71 100644 --- a/Languages/japanese.lang +++ b/Languages/japanese.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SDカードにアクセス出来ません" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD GCゲーム" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "このパスはSDにないといけません!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "残り時間:" diff --git a/Languages/korean.lang b/Languages/korean.lang index a908aa9e..c9381883 100644 --- a/Languages/korean.lang +++ b/Languages/korean.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SD 카드에 접속 할 수 없습니다." +msgid "SD Card Mode" +msgstr "SD 카드 모드" + msgid "SD GameCube Games Path" msgstr "SD 게임큐브 게임 경로" @@ -2206,6 +2209,9 @@ msgstr "이 게임에는 여러 개의 디스크가 있습니다. 실행할 디 msgid "This path must be on SD!" msgstr "이 경로는 SD에 있어야 합니다!" +msgid "This setting doesn't work in SD card mode." +msgstr "이 설정은 SD 카드 모드에서 작동하지 않습니다." + msgid "Time left:" msgstr "시간 남음:" diff --git a/Languages/norwegian.lang b/Languages/norwegian.lang index b08ca2bc..df1a4b82 100644 --- a/Languages/norwegian.lang +++ b/Languages/norwegian.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tid igjen:" diff --git a/Languages/polish.lang b/Languages/polish.lang index 86eeac94..b941fb2a 100644 --- a/Languages/polish.lang +++ b/Languages/polish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Czas pozostaly" diff --git a/Languages/portuguese_br.lang b/Languages/portuguese_br.lang index 03262560..c6dd041f 100644 --- a/Languages/portuguese_br.lang +++ b/Languages/portuguese_br.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "Este Cartão SD não pode ser acessado" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "Pasta de jogos de GC no Cartão" @@ -2206,6 +2209,9 @@ msgstr "Esse jogo utiliza vários discos. Escolha o disco a iniciar" msgid "This path must be on SD!" msgstr "Essa pasta precisa estar no Cartão SD!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Restam:" diff --git a/Languages/portuguese_pt.lang b/Languages/portuguese_pt.lang index e7c828ac..972a9e5b 100644 --- a/Languages/portuguese_pt.lang +++ b/Languages/portuguese_pt.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tempo rem:" diff --git a/Languages/russian.lang b/Languages/russian.lang index acfd1d81..e331295e 100644 --- a/Languages/russian.lang +++ b/Languages/russian.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Осталось времени:" diff --git a/Languages/schinese.lang b/Languages/schinese.lang index d75f55eb..3209df94 100644 --- a/Languages/schinese.lang +++ b/Languages/schinese.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SD 卡不能访问。" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD GameCube 游戏路径" @@ -2206,6 +2209,9 @@ msgstr "该游戏有多张光盘。请选择想要加载的光盘。" msgid "This path must be on SD!" msgstr "该路径必须位于 SD 卡!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "剩余时间:" diff --git a/Languages/spanish.lang b/Languages/spanish.lang index 116ec77d..e7b0843e 100644 --- a/Languages/spanish.lang +++ b/Languages/spanish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "No se puede acceder a tarjeta SD." +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "Ruta de juegos GameCube en SD" @@ -2206,6 +2209,9 @@ msgstr "Este juego posee varios discos. Por favor, elige el que deseas cargar." msgid "This path must be on SD!" msgstr "¡Esta ruta debe estar en la SD!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Quedan:" diff --git a/Languages/swedish.lang b/Languages/swedish.lang index 904018ac..873a4a0a 100644 --- a/Languages/swedish.lang +++ b/Languages/swedish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Tid kvar:" diff --git a/Languages/tchinese.lang b/Languages/tchinese.lang index 77eb1818..3d6c7e2f 100644 --- a/Languages/tchinese.lang +++ b/Languages/tchinese.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "SD卡無法存取" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "SD卡 GameCube遊戲路徑" @@ -2206,6 +2209,9 @@ msgstr "此遊戲為多重光碟。請選擇光碟啟動。" msgid "This path must be on SD!" msgstr "此路徑必須是在SD卡上!" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "剩餘時間:" diff --git a/Languages/thai.lang b/Languages/thai.lang index 990da475..6a9ded5a 100644 --- a/Languages/thai.lang +++ b/Languages/thai.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "เหลือเวลาอีก:" diff --git a/Languages/turkish.lang b/Languages/turkish.lang index 815eab3e..450d7f2d 100644 --- a/Languages/turkish.lang +++ b/Languages/turkish.lang @@ -1920,6 +1920,9 @@ msgstr "" msgid "SD Card could not be accessed." msgstr "" +msgid "SD Card Mode" +msgstr "" + msgid "SD GameCube Games Path" msgstr "" @@ -2206,6 +2209,9 @@ msgstr "" msgid "This path must be on SD!" msgstr "" +msgid "This setting doesn't work in SD card mode." +msgstr "" + msgid "Time left:" msgstr "Kalan zaman:" diff --git a/source/Controls/DeviceHandler.cpp b/source/Controls/DeviceHandler.cpp index df8285d2..b36f9188 100644 --- a/source/Controls/DeviceHandler.cpp +++ b/source/Controls/DeviceHandler.cpp @@ -30,8 +30,6 @@ #include #include #include -#include "settings/CSettings.h" -#include "usbloader/usbstorage2.h" #include "DeviceHandler.hpp" #include "usbloader/wbfs.h" #include "system/IosLoader.h" @@ -120,7 +118,7 @@ bool DeviceHandler::IsInserted(int dev) void DeviceHandler::UnMount(int dev) { - if(dev == SD) + if(dev == SD && !Settings.SDMode) UnMountSD(); else if(dev >= USB1 && dev <= USB8) @@ -130,7 +128,7 @@ void DeviceHandler::UnMount(int dev) bool DeviceHandler::MountSD() { if(!sd) - sd = new PartitionHandle(&__io_wiisd); + sd = new PartitionHandle(GetSDInterface()); if(sd->GetPartitionCount() < 1) { diff --git a/source/Controls/DeviceHandler.hpp b/source/Controls/DeviceHandler.hpp index 5b4261c2..871c7d0e 100644 --- a/source/Controls/DeviceHandler.hpp +++ b/source/Controls/DeviceHandler.hpp @@ -26,8 +26,13 @@ #ifndef DEVICE_HANDLER_HPP_ #define DEVICE_HANDLER_HPP_ +#include +#include "usbloader/sdhc.h" #include "PartitionHandle.h" #include "usbloader/usbstorage2.h" +#include "settings/CSettings.h" + +extern const DISC_INTERFACE __io_sdhc; /** * libogc device names. @@ -81,7 +86,7 @@ class DeviceHandler bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; } bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; } bool USB1_Inserted() { if(usb1) return usb1->IsInserted(); return false; } - void UnMountSD() { if(sd) delete sd; sd = NULL; } + void UnMountSD() { if(sd) delete sd; sd = NULL; SDHC_Close(); } void UnMountUSB(int pos); void UnMountAllUSB(); PartitionHandle * GetSDHandle() const { return sd; } @@ -90,6 +95,7 @@ class DeviceHandler PartitionHandle * GetUSBHandleFromPartition(int part) const; static const DISC_INTERFACE *GetUSB0Interface() { return (IOS_GetVersion() >= 200) ? &__io_usbstorage2_port0 : &__io_usbstorage; } static const DISC_INTERFACE *GetUSB1Interface() { return (IOS_GetVersion() >= 200) ? &__io_usbstorage2_port1 : NULL; } + static const DISC_INTERFACE *GetSDInterface() { return (IOS_GetVersion() >= 200 && Settings.SDMode) ? &__io_sdhc : &__io_wiisd; } static int GetFilesystemType(int dev); static const char * GetFSName(int dev); static int PathToDriveType(const char * path); @@ -99,15 +105,13 @@ class DeviceHandler static u16 GetUSBPartitionCount(); static int PartitionToPortPartition(int part); private: - DeviceHandler() : sd(0), gca(0), gcb(0), usb0(0), usb1(0) { } + DeviceHandler() : sd(0), usb0(0), usb1(0) { } ~DeviceHandler(); bool MountUSB(int part); static DeviceHandler *instance; PartitionHandle * sd; - PartitionHandle * gca; - PartitionHandle * gcb; PartitionHandle * usb0; PartitionHandle * usb1; }; diff --git a/source/Controls/PartitionHandle.cpp b/source/Controls/PartitionHandle.cpp index 8d9e9848..93c647c9 100644 --- a/source/Controls/PartitionHandle.cpp +++ b/source/Controls/PartitionHandle.cpp @@ -92,7 +92,7 @@ PartitionHandle::PartitionHandle(const DISC_INTERFACE *discio) PartitionHandle::~PartitionHandle() { - UnMountAll(); + UnMountAll(); //shutdown device interface->shutdown(); diff --git a/source/StartUpProcess.cpp b/source/StartUpProcess.cpp index 678abe4b..42a7054c 100644 --- a/source/StartUpProcess.cpp +++ b/source/StartUpProcess.cpp @@ -26,8 +26,11 @@ #include "sys.h" #include "svnrev.h" #include "gitver.h" +#include "usbloader/sdhc.h" +#include "settings/meta.h" extern bool isWiiVC; // in sys.cpp +extern u8 sdhc_mode_sd; StartUpProcess::StartUpProcess() { @@ -59,11 +62,10 @@ StartUpProcess::StartUpProcess() versionTxt->SetTextf("v3.0 Rev. %s (%s)", GetRev(), commitID()); #endif -#if 1 // enable if you release a modded version - enabled by default to differentiate official releases - versionTxt->SetTextf("v3.0 Rev. %s mod (%s)", GetRev(), commitID()); -#endif - - cancelTxt = new GuiText("Press B to cancel", 18, (GXColor){255, 255, 255, 255}); + if (strncmp(Settings.ConfigPath, "sd", 2) == 0) + cancelTxt = new GuiText("Press B to cancel or A to enable SD card mode", 22, (GXColor){255, 255, 255, 255}); + else + cancelTxt = new GuiText("Press B to cancel", 22, (GXColor){255, 255, 255, 255}); cancelTxt->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE); cancelTxt->SetPosition(screenwidth / 2, screenheight / 2 + 90); @@ -73,6 +75,13 @@ StartUpProcess::StartUpProcess() cancelBtn = new GuiButton(0, 0); cancelBtn->SetTrigger(trigB); + trigA = new GuiTrigger; + trigA->SetButtonOnlyTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + + sdmodeBtn = new GuiButton(0, 0); + if (strncmp(Settings.ConfigPath, "sd", 2) == 0) + sdmodeBtn->SetTrigger(trigA); + drawCancel = false; } @@ -86,7 +95,9 @@ StartUpProcess::~StartUpProcess() delete versionTxt; delete cancelTxt; delete cancelBtn; + delete sdmodeBtn; delete trigB; + delete trigA; } int StartUpProcess::ParseArguments(int argc, char *argv[]) @@ -131,6 +142,17 @@ int StartUpProcess::ParseArguments(int argc, char *argv[]) Settings.USBAutoMount = LIMIT(atoi(ptr + strlen("-mountusb=")), 0, 1); } + if (strncmp(Settings.ConfigPath, "sd", 2) == 0) + { + ptr = strcasestr(argv[i], "-sdmode="); + if (ptr) + { + Settings.SDMode = LIMIT(atoi(ptr + strlen("-sdmode=")), 0, 1); + if (Settings.SDMode) + sdhc_mode_sd = 1; + } + } + if (strlen(argv[i]) == 6 && strchr(argv[i], '=') == 0 && strchr(argv[i], '-') == 0) quickBoot = i; } @@ -208,11 +230,21 @@ bool StartUpProcess::USBSpinUp() UpdatePads(); for (int i = 0; i < 4; ++i) + { cancelBtn->Update(&userInput[i]); + sdmodeBtn->Update(&userInput[i]); + } if (cancelBtn->GetState() == STATE_CLICKED) break; + if (sdmodeBtn->GetState() == STATE_CLICKED) + { + Settings.SDMode = ON; + sdhc_mode_sd = 1; + break; + } + messageTxt->SetTextf("Waiting for HDD: %i sec left\n", 20 - (int)countDown.elapsed()); Draw(); usleep(50000); @@ -275,7 +307,7 @@ int StartUpProcess::Execute(bool quickGameBoot) gprintf("Current IOS: %d - have AHB access: %s\n", Settings.EntryIOS, AHBPROT_DISABLED ? "yes" : "no"); // Reload to a cIOS if we're using both USB ports - if (Settings.USBPort == 2) + if (Settings.USBPort == 2 && !Settings.SDMode) LoadIOS(Settings.LoaderIOS, false); // Reload to a cIOS if required (old forwarder?) or requested @@ -291,7 +323,7 @@ int StartUpProcess::Execute(bool quickGameBoot) // Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel bool USBSuccess = false; - if (Settings.USBAutoMount == ON && !isWiiVC) + if (Settings.USBAutoMount == ON && !isWiiVC && !Settings.SDMode) { SetTextf("Initializing USB devices\n"); if (USBSpinUp()) @@ -344,18 +376,21 @@ int StartUpProcess::Execute(bool quickGameBoot) SetupPads(); DeviceHandler::Instance()->MountSD(); - if (Settings.USBAutoMount == ON && USBSuccess) + if (Settings.USBAutoMount == ON && !Settings.SDMode && USBSuccess) { if (USBSpinUp()) DeviceHandler::Instance()->MountAllUSB(false); } } - if (!IosLoader::IsHermesIOS() && !IosLoader::IsD2X()) + if (sdhc_mode_sd) + editMetaArguments(); + + if (!IosLoader::IsHermesIOS() && !IosLoader::IsD2X() && !Settings.SDMode) { Settings.USBPort = 0; } - else if (Settings.USBPort == 1 && USBStorage2_GetPort() != Settings.USBPort) + else if (Settings.USBPort == 1 && USBStorage2_GetPort() != Settings.USBPort && !Settings.SDMode) { if (Settings.USBAutoMount == ON && !isWiiVC) { @@ -364,7 +399,7 @@ int StartUpProcess::Execute(bool quickGameBoot) DeviceHandler::Instance()->MountAllUSB(); } } - else if (Settings.USBPort == 2) + else if (Settings.USBPort == 2 && !Settings.SDMode) { if (Settings.USBAutoMount == ON && !isWiiVC) { diff --git a/source/StartUpProcess.h b/source/StartUpProcess.h index ea962e3f..dca9366c 100644 --- a/source/StartUpProcess.h +++ b/source/StartUpProcess.h @@ -30,7 +30,9 @@ private: GuiText *versionTxt; GuiText *cancelTxt; GuiButton *cancelBtn; + GuiButton *sdmodeBtn; GuiTrigger *trigB; + GuiTrigger *trigA; }; #endif diff --git a/source/cache/cache.cpp b/source/cache/cache.cpp index 9392c1fe..51e7becb 100644 --- a/source/cache/cache.cpp +++ b/source/cache/cache.cpp @@ -57,13 +57,22 @@ bool isCacheCurrent() std::string list; // GameCube - snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubePath); - GetDirectoryList(filepath, list); + if (!Settings.SDMode) + { + snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubePath); + GetDirectoryList(filepath, list); + } snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubeSDPath); GetDirectoryList(filepath, list); // Wii - GetListWBFS(list); + if (Settings.SDMode) + { + snprintf(filepath, sizeof(filepath), "sd:/wbfs"); + GetDirectoryList(filepath, list); + } + else + GetListWBFS(list); // EmuNAND snprintf(filepath, sizeof(filepath), "%s/title/00010001", Settings.NandEmuChanPath); diff --git a/source/libs/libwbfs/libwbfs.h b/source/libs/libwbfs/libwbfs.h index b3accdc2..7e632052 100644 --- a/source/libs/libwbfs/libwbfs.h +++ b/source/libs/libwbfs/libwbfs.h @@ -13,9 +13,8 @@ extern "C" enum { - WBFS_DEVICE_USB = 1, /* USB device */ - WBFS_DEVICE_SDHC - /* SDHC device */ + WBFS_DEVICE_SDHC = 0, /* SDHC device */ + WBFS_DEVICE_USB = 1 /* USB device */ }; typedef u32 be32_t; diff --git a/source/libs/libwbfs/wiidisc.c b/source/libs/libwbfs/wiidisc.c index 4e2dc8c8..f63c0f4d 100644 --- a/source/libs/libwbfs/wiidisc.c +++ b/source/libs/libwbfs/wiidisc.c @@ -10,21 +10,20 @@ void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len); void _decrypt_title_key(u8 *tik, u8 *title_key) { - u8 common_key[16] = { 0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7 }; - u8 korean_key[16]={ 0x63, 0xb8, 0x2b, 0xb4, 0xf4, 0x61, 0x4e, 0x2e, 0x13, 0xf2, 0xfe, 0xfb, 0xba, 0x4c, 0x9b, 0x7e }; //korean common key + u8 common_key[16] = {0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7}; + u8 korean_key[16] = {0x63, 0xb8, 0x2b, 0xb4, 0xf4, 0x61, 0x4e, 0x2e, 0x13, 0xf2, 0xfe, 0xfb, 0xba, 0x4c, 0x9b, 0x7e}; // korean common key u8 iv[16]; - wbfs_memset( iv, 0, sizeof iv ); - wbfs_memcpy( iv, tik + 0x01dc, 8 ); + wbfs_memset(iv, 0, sizeof iv); + wbfs_memcpy(iv, tik + 0x01dc, 8); - //check byte 0x1f1 in ticket to determine whether or not to use Korean Common Key. - //if value = 0x01, use Korean Common Key, else just use regular one -dmm - //Also check the GameID region code as some channels are using wrong ticket with 0x01 -Cyan - if(tik[0x01f1] == 0x01 && (tik[0x01e3] == 'K' || tik[0x01e3] == 'Q' || tik[0x01e3] == 'T')){ - aes_set_key(korean_key); - } else { - aes_set_key(common_key); - } + // Check byte 0x1f1 in ticket to determine whether or not to use Korean Common Key. + // If value = 0x01, use Korean Common Key, else just use regular one -dmm + // Also check the GameID region code as some channels are using wrong ticket with 0x01 -Cyan + if (tik[0x01f1] == 0x01 && (tik[0x01e3] == 'K' || tik[0x01e3] == 'Q' || tik[0x01e3] == 'T')) + aes_set_key(korean_key); + else + aes_set_key(common_key); aes_decrypt(iv, tik + 0x01bf, title_key, 16); } @@ -34,10 +33,11 @@ static void disc_read(wiidisc_t *d, u32 offset, u8 *data, u32 len) if (data) { int ret = 0; - if (len == 0) return; + if (len == 0) + return; ret = d->read(d->fp, offset, len, data); if (ret) - wbfs_fatal( "error reading disc" ); + wbfs_fatal("error reading disc"); } if (d->sector_usage_table) { @@ -46,7 +46,8 @@ static void disc_read(wiidisc_t *d, u32 offset, u8 *data, u32 len) { d->sector_usage_table[blockno] = 1; blockno += 1; - if (len > 0x8000) len -= 0x8000; + if (len > 0x8000) + len -= 0x8000; } while (len > 0x8000); } } @@ -58,10 +59,11 @@ static void partition_raw_read(wiidisc_t *d, u32 offset, u8 *data, u32 len) static void partition_read_block(wiidisc_t *d, u32 blockno, u8 *block) { - u8*raw = d->tmp_buffer; + u8 *raw = d->tmp_buffer; u8 iv[16]; u32 offset; - if (d->sector_usage_table) d->sector_usage_table[d->partition_block + blockno] = 1; + if (d->sector_usage_table) + d->sector_usage_table[d->partition_block + blockno] = 1; offset = d->partition_data_offset + ((0x8000 >> 2) * blockno); partition_raw_read(d, offset, raw, 0x8000); @@ -76,19 +78,22 @@ static void partition_read(wiidisc_t *d, u32 offset, u8 *data, u32 len, int fake u8 *block = d->tmp_buffer2; u32 offset_in_block; u32 len_in_block; - if (fake && d->sector_usage_table == 0) return; + if (fake && d->sector_usage_table == 0) + return; while (len) { offset_in_block = offset % (0x7c00 >> 2); len_in_block = 0x7c00 - (offset_in_block << 2); - if (len_in_block > len) len_in_block = len; + if (len_in_block > len) + len_in_block = len; if (!fake) { partition_read_block(d, offset / (0x7c00 >> 2), block); - wbfs_memcpy( data, block + ( offset_in_block << 2 ), len_in_block ); + wbfs_memcpy(data, block + (offset_in_block << 2), len_in_block); } - else d->sector_usage_table[d->partition_block + (offset / (0x7c00 >> 2))] = 1; + else + d->sector_usage_table[d->partition_block + (offset / (0x7c00 >> 2))] = 1; data += len_in_block; offset += len_in_block >> 2; len -= len_in_block; @@ -129,24 +134,25 @@ static u32 do_fst(wiidisc_t *d, u8 *fst, const char *names, u32 i) if (d->extract_pathname && strcasecmp(name, d->extract_pathname) == 0) { - d->extracted_buffer = wbfs_ioalloc( size ); + d->extracted_buffer = wbfs_ioalloc(size); d->extracted_size = size; partition_read(d, offset, d->extracted_buffer, size, 0); } - else partition_read(d, offset, 0, size, 1); + else + partition_read(d, offset, 0, size, 1); return i + 1; } } -static void do_files(wiidisc_t*d) +static void do_files(wiidisc_t *d) { - u8 *b = wbfs_ioalloc( 0x480 ); // XXX: determine actual header size + u8 *b = wbfs_ioalloc(0x480); // XXX: determine actual header size u32 dol_offset; u32 fst_offset; u32 fst_size; u32 apl_offset; u32 apl_size; - u8 *apl_header = wbfs_ioalloc( 0x20 ); + u8 *apl_header = wbfs_ioalloc(0x20); u8 *fst; u32 n_files; partition_read(d, 0, b, 0x480, 0); @@ -159,18 +165,18 @@ static void do_files(wiidisc_t*d) partition_read(d, apl_offset, apl_header, 0x20, 0); apl_size = 0x20 + wbfs_be32(apl_header + 0x14) + wbfs_be32(apl_header + 0x18); // fake read dol and partition - if (apl_size) partition_read(d, apl_offset, 0, apl_size, 1); + if (apl_size) + partition_read(d, apl_offset, 0, apl_size, 1); partition_read(d, dol_offset, 0, (fst_offset - dol_offset) << 2, 1); if (fst_size) { - fst = wbfs_ioalloc( fst_size ); + fst = wbfs_ioalloc(fst_size); if (fst == 0) - wbfs_fatal( "malloc fst" ); + wbfs_fatal("malloc fst"); partition_read(d, fst_offset, fst, fst_size, 0); n_files = wbfs_be32(fst + 8); - if (d->extract_pathname && strcmp(d->extract_pathname, "FST") == 0) { // if empty pathname requested return fst @@ -183,19 +189,21 @@ static void do_files(wiidisc_t*d) if (12 * n_files <= fst_size) { - if (n_files > 1) do_fst(d, fst, (char *) fst + 12 * n_files, 0); + if (n_files > 1) + do_fst(d, fst, (char *)fst + 12 * n_files, 0); } - if (fst != d->extracted_buffer) wbfs_iofree( fst ); + if (fst != d->extracted_buffer) + wbfs_iofree(fst); } - wbfs_iofree( b ); - wbfs_iofree( apl_header ); + wbfs_iofree(b); + wbfs_iofree(apl_header); } -static void do_partition(wiidisc_t*d) +static void do_partition(wiidisc_t *d) { - u8 *tik = wbfs_ioalloc( 0x2a4 ); - u8 *b = wbfs_ioalloc( 0x1c ); + u8 *tik = wbfs_ioalloc(0x2a4); + u8 *b = wbfs_ioalloc(0x1c); u64 tmd_offset; u32 tmd_size; u8 *tmd; @@ -215,54 +223,54 @@ static void do_partition(wiidisc_t*d) h3_offset = wbfs_be32(b + 0x10); d->partition_data_offset = wbfs_be32(b + 0x14); d->partition_block = (d->partition_raw_offset + d->partition_data_offset) >> 13; - tmd = wbfs_ioalloc( tmd_size ); + tmd = wbfs_ioalloc(tmd_size); if (tmd == 0) - wbfs_fatal( "malloc tmd" ); + wbfs_fatal("malloc tmd"); partition_raw_read(d, tmd_offset, tmd, tmd_size); - if(d->extract_pathname && strcmp(d->extract_pathname, "TMD") == 0 && !d->extracted_buffer) + if (d->extract_pathname && strcmp(d->extract_pathname, "TMD") == 0 && !d->extracted_buffer) { d->extracted_buffer = tmd; d->extracted_size = tmd_size; } - cert = wbfs_ioalloc( cert_size ); + cert = wbfs_ioalloc(cert_size); if (cert == 0) - wbfs_fatal( "malloc cert" ); + wbfs_fatal("malloc cert"); partition_raw_read(d, cert_offset, cert, cert_size); _decrypt_title_key(tik, d->disc_key); partition_raw_read(d, h3_offset, 0, 0x18000); - wbfs_iofree( b ); - wbfs_iofree( tik ); - wbfs_iofree( cert ); + wbfs_iofree(b); + wbfs_iofree(tik); + wbfs_iofree(cert); if(tmd != d->extracted_buffer) - wbfs_iofree( tmd ); - + wbfs_iofree(tmd); do_files(d); - } + static int test_parition_skip(u32 partition_type, partition_selector_t part_sel) { switch (part_sel) { - case ALL_PARTITIONS: - return 0; - case REMOVE_UPDATE_PARTITION: - return (partition_type == 1); - case ONLY_GAME_PARTITION: - return (partition_type != 0); - default: - return (partition_type != part_sel); + case ALL_PARTITIONS: + return 0; + case REMOVE_UPDATE_PARTITION: + return (partition_type == 1); + case ONLY_GAME_PARTITION: + return (partition_type != 0); + default: + return (partition_type != part_sel); } } -static void do_disc(wiidisc_t*d) + +static void do_disc(wiidisc_t *d) { - u8 *b = wbfs_ioalloc( 0x100 ); + u8 *b = wbfs_ioalloc(0x100); u64 partition_offset[32]; // XXX: don't know the real maximum - u64 partition_type[32]; // XXX: don't know the real maximum + u64 partition_type[32]; // XXX: don't know the real maximum u32 n_partitions; u32 magic; u32 i; @@ -270,8 +278,8 @@ static void do_disc(wiidisc_t*d) magic = wbfs_be32(b + 24); if (magic != 0x5D1C9EA3) { - wbfs_iofree( b ); - wbfs_error( "not a wii disc" ); + wbfs_iofree(b); + wbfs_error("not a wii disc"); return; } disc_read(d, 0x40000 >> 2, b, 0x100); @@ -285,34 +293,38 @@ static void do_disc(wiidisc_t*d) for (i = 0; i < n_partitions; i++) { d->partition_raw_offset = partition_offset[i]; - if (!test_parition_skip(partition_type[i], d->part_sel)) do_partition(d); + if (!test_parition_skip(partition_type[i], d->part_sel)) + do_partition(d); } - wbfs_iofree( b ); + wbfs_iofree(b); } -wiidisc_t *wd_open_disc(read_wiidisc_callback_t read, void*fp) +wiidisc_t *wd_open_disc(read_wiidisc_callback_t read, void *fp) { - wiidisc_t *d = wbfs_malloc( sizeof( wiidisc_t ) ); - if (!d) return 0; - wbfs_memset( d, 0, sizeof( wiidisc_t ) ); + wiidisc_t *d = wbfs_malloc(sizeof(wiidisc_t)); + if (!d) + return 0; + wbfs_memset(d, 0, sizeof(wiidisc_t)); d->read = read; d->fp = fp; d->part_sel = ALL_PARTITIONS; - d->tmp_buffer = wbfs_ioalloc( 0x8000 ); - d->tmp_buffer2 = wbfs_malloc( 0x8000 ); + d->tmp_buffer = wbfs_ioalloc(0x8000); + d->tmp_buffer2 = wbfs_malloc(0x8000); return d; } + void wd_close_disc(wiidisc_t *d) { - wbfs_iofree( d->tmp_buffer ); - wbfs_free( d->tmp_buffer2 ); - wbfs_free( d ); + wbfs_iofree(d->tmp_buffer); + wbfs_free(d->tmp_buffer2); + wbfs_free(d); } + // returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error // XXX pathname not implemented. files are extracted by their name. // first file found with that name is returned. -u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname) +u8 *wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname) { u8 *retval = 0; d->extract_pathname = pathname; @@ -325,27 +337,28 @@ u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pa return retval; } -void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8* usage_table) +void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8 *usage_table) { d->sector_usage_table = usage_table; - wbfs_memset( usage_table, 0, 143432*2 ); + wbfs_memset(usage_table, 0, 143432 * 2); d->part_sel = selector; do_disc(d); d->part_sel = ALL_PARTITIONS; d->sector_usage_table = 0; } -void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* partition_table) +void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8 *partition_table) { u8 *b = partition_table; u32 partition_offset; u32 partition_type; u32 n_partitions, i, j; u32 *b32; - if (selector == ALL_PARTITIONS) return; + if (selector == ALL_PARTITIONS) + return; n_partitions = wbfs_be32(b); if (wbfs_be32(b + 4) - (0x40000 >> 2) > 0x50) - wbfs_fatal( "cannot modify this partition table. Please report the bug." ); + wbfs_fatal("cannot modify this partition table. Please report the bug."); b += (wbfs_be32(b + 4) - (0x40000 >> 2)) * 4; j = 0; @@ -355,13 +368,12 @@ void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* par partition_type = wbfs_be32(b + 8 * i + 4); if (!test_parition_skip(partition_type, selector)) { - b32 = (u32*) (b + 8 * j); - b32[0] = wbfs_htonl( partition_offset ); - b32[1] = wbfs_htonl( partition_type ); + b32 = (u32 *)(b + 8 * j); + b32[0] = wbfs_htonl(partition_offset); + b32[1] = wbfs_htonl(partition_type); j++; } } - b32 = (u32*) (partition_table); - *b32 = wbfs_htonl( j ); + b32 = (u32 *)(partition_table); + *b32 = wbfs_htonl(j); } - diff --git a/source/menu/GameBrowseMenu.cpp b/source/menu/GameBrowseMenu.cpp index 0d2d5052..6a02a77b 100644 --- a/source/menu/GameBrowseMenu.cpp +++ b/source/menu/GameBrowseMenu.cpp @@ -962,7 +962,7 @@ int GameBrowseMenu::MainLoop() this->SetState(STATE_DISABLED); if (!(Settings.LoaderMode & MODE_WIIGAMES) && (gameList.GameCount() == 0)) { - if (WBFS_ReInit(WBFS_DEVICE_USB) < 0) + if (WBFS_ReInit(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB) < 0) ShowError(tr("Failed to initialize the USB storage device.")); else { @@ -1339,16 +1339,17 @@ int GameBrowseMenu::MainLoop() if((Settings.LoaderMode & MODE_WIIGAMES) && (gameList.GameCount() == 0)) { - s32 wbfsinit = WBFS_Init(WBFS_DEVICE_USB); + s32 wbfsinit = WBFS_Init(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); if (wbfsinit < 0) { + // This shouldn't ever fail in SD card mode ShowError("%s %s", tr( "USB Device not initialized." ), tr("Switching to channel list mode.")); Settings.LoaderMode &= ~MODE_WIIGAMES; Settings.LoaderMode |= MODE_NANDCHANNELS; } else { - WBFS_ReInit(WBFS_DEVICE_USB); + WBFS_ReInit(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); } gameList.ReadGameList(true); diff --git a/source/menu/menu_install.cpp b/source/menu/menu_install.cpp index 498f38e2..e8738eb6 100644 --- a/source/menu/menu_install.cpp +++ b/source/menu/menu_install.cpp @@ -73,8 +73,8 @@ int MenuGCInstall() gcDumper.SetCompressed(Settings.GCInstallAligned); //! If a different main path than the SD path is selected ask where to install - int destination = 1; - if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0) + int destination = Settings.SDMode ? 2 : 1; + if(!Settings.SDMode && strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0) destination = WindowPrompt(tr("Where should the game be installed to?"), 0, tr("Main Path"), tr("SD Path"), tr("Cancel")); if(!destination) return MENU_DISCLIST; diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index 36c450ac..861e89be 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -1141,12 +1141,20 @@ int DiscWait(const char *title, const char *msg, const char *btn1Label, const ch do { gprintf("%i\n", (int) (timenow-starttime)); - ret = WBFS_Init(WBFS_DEVICE_USB); + ret = WBFS_Init(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); if (ret >= 0) break; timerTxt.SetTextf("%i %s", (int) (30-(timenow-starttime)), tr( "seconds left" )); - DeviceHandler::Instance()->UnMountAllUSB(); - DeviceHandler::Instance()->MountAllUSB(); + if (Settings.SDMode) + { + DeviceHandler::Instance()->UnMountSD(); + DeviceHandler::Instance()->MountSD(); + } + else + { + DeviceHandler::Instance()->UnMountAllUSB(); + DeviceHandler::Instance()->MountAllUSB(); + } timenow = time(0); } while (timenow-starttime < 30); diff --git a/source/settings/CSettings.cpp b/source/settings/CSettings.cpp index 24adb124..cde66efe 100644 --- a/source/settings/CSettings.cpp +++ b/source/settings/CSettings.cpp @@ -881,7 +881,7 @@ bool CSettings::SetSetting(char *name, char *value) } else if(strcmp(name, "NandEmuMode") == 0) { - NandEmuMode = atoi(value); + NandEmuMode = SDMode ? EMUNAND_OFF : atoi(value); } else if(strcmp(name, "NandEmuChanMode") == 0) { diff --git a/source/settings/CSettings.h b/source/settings/CSettings.h index 52293449..7fa61a72 100644 --- a/source/settings/CSettings.h +++ b/source/settings/CSettings.h @@ -247,6 +247,7 @@ class CSettings // These variables are not saved to the settings file bool FirstTimeRun; bool skipSaving; + short SDMode; protected: bool ValidVersion(FILE * file); bool ValidateURL(char *value, int type = 0); diff --git a/source/settings/menus/HardDriveSM.cpp b/source/settings/menus/HardDriveSM.cpp index 18af0f84..27f08d11 100644 --- a/source/settings/menus/HardDriveSM.cpp +++ b/source/settings/menus/HardDriveSM.cpp @@ -36,6 +36,9 @@ #include "system/IosLoader.h" #include "wad/nandtitle.h" #include "utils/tools.h" +#include "FileOperations/fileops.h" +#include "gecko.h" +#include "sys.h" static const char * OnOffText[] = { @@ -75,6 +78,8 @@ HardDriveSM::HardDriveSM() int Idx = 0; Options->SetName(Idx++, "%s", tr( "Game/Install Partition" )); Options->SetName(Idx++, "%s", tr( "Multiple Partitions" )); + if (strncmp(Settings.ConfigPath, "sd", 2) == 0) + Options->SetName(Idx++, "%s", tr( "SD Card Mode" )); Options->SetName(Idx++, "%s", tr( "USB Port" )); Options->SetName(Idx++, "%s", tr( "Mount USB at launch" )); Options->SetName(Idx++, "%s", tr( "Install Directories" )); @@ -86,6 +91,7 @@ HardDriveSM::HardDriveSM() OldSettingsPartition = Settings.partition; OldSettingsMultiplePartitions = Settings.MultiplePartitions; + OldSettingsSDMode = Settings.SDMode; NewSettingsUSBPort = Settings.USBPort; oldSettingsUSBAutoMount = Settings.USBAutoMount; @@ -94,41 +100,53 @@ HardDriveSM::HardDriveSM() HardDriveSM::~HardDriveSM() { + gprintf("Quit HDD settings: %i\n", Settings.SDMode); //! if partition has changed, Reinitialize it if (Settings.partition != OldSettingsPartition || Settings.MultiplePartitions != OldSettingsMultiplePartitions || - Settings.USBPort != NewSettingsUSBPort || - Settings.USBAutoMount != oldSettingsUSBAutoMount) + Settings.USBPort != NewSettingsUSBPort || + Settings.USBAutoMount != oldSettingsUSBAutoMount || + Settings.SDMode != OldSettingsSDMode) { - WBFS_CloseAll(); - - if(Settings.USBPort != NewSettingsUSBPort) + if(!Settings.SDMode) { - DeviceHandler::Instance()->UnMountAllUSB(); - Settings.USBPort = NewSettingsUSBPort; - DeviceHandler::Instance()->MountAllUSB(); + WBFS_CloseAll(); - if(Settings.partition >= DeviceHandler::GetUSBPartitionCount()) - Settings.partition = 0; + if(Settings.USBPort != NewSettingsUSBPort) + { + DeviceHandler::Instance()->UnMountAllUSB(); + Settings.USBPort = NewSettingsUSBPort; + DeviceHandler::Instance()->MountAllUSB(); - // set -1 to edit meta.xml arguments - NewSettingsUSBPort = -1; + if(Settings.partition >= DeviceHandler::GetUSBPartitionCount()) + Settings.partition = 0; + + // set -1 to edit meta.xml arguments + NewSettingsUSBPort = -1; + } + + WBFS_Init(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); + if(Settings.MultiplePartitions) + WBFS_OpenAll(); + else + WBFS_OpenPart(Settings.partition); + + //! Reload the new game titles + gameList.ReadGameList(); + gameList.LoadUnfiltered(); } - - WBFS_Init(WBFS_DEVICE_USB); - if(Settings.MultiplePartitions) - WBFS_OpenAll(); - else - WBFS_OpenPart(Settings.partition); - - //! Reload the new game titles - gameList.ReadGameList(); - gameList.LoadUnfiltered(); - if(oldSettingsUSBAutoMount != Settings.USBAutoMount || NewSettingsUSBPort == -1) + if(oldSettingsUSBAutoMount != Settings.USBAutoMount || NewSettingsUSBPort == -1 || OldSettingsSDMode != Settings.SDMode) { // edit meta.xml arguments editMetaArguments(); + gprintf("Updated meta.xml\n"); + } + if(OldSettingsSDMode != Settings.SDMode) + { + Settings.NandEmuMode = EMUNAND_OFF; + RemoveDirectory(Settings.GameHeaderCachePath); + RebootApp(); } } } @@ -138,18 +156,29 @@ void HardDriveSM::SetOptionValues() int Idx = 0; //! Settings: Game/Install Partition - PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); - int checkPart = DeviceHandler::PartitionToPortPartition(Settings.partition); + PartitionHandle *handle; + int checkPart = 0; + if (!Settings.SDMode) + { + handle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); + checkPart = DeviceHandler::PartitionToPortPartition(Settings.partition); + } + else + handle = DeviceHandler::Instance()->GetSDHandle(); //! Get the partition name and it's size in GB's - if(usbHandle) - Options->SetValue(Idx++, "%s (%.2fGB)", usbHandle->GetFSName(checkPart), usbHandle->GetSize(checkPart)/GB_SIZE); + if (handle) + Options->SetValue(Idx++, "%s (%.2fGB)", handle->GetFSName(checkPart), handle->GetSize(checkPart)/GB_SIZE); else Options->SetValue(Idx++, tr("Not Initialized")); //! Settings: Multiple Partitions Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.MultiplePartitions] )); + //! Settings: SD Card Mode + if (strncmp(Settings.ConfigPath, "sd", 2) == 0) + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.SDMode] )); + //! Settings: USB Port if(NewSettingsUSBPort == 2) Options->SetValue(Idx++, tr("Both Ports")); @@ -195,10 +224,18 @@ int HardDriveSM::GetMenuInternal() //! Settings: Game/Install Partition if (ret == ++Idx) { - // Init the USB device if mounted after launch. - PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); - if(usbHandle == NULL) - DeviceHandler::Instance()->MountAllUSB(true); + PartitionHandle *handle; + if (Settings.SDMode) + { + handle = DeviceHandler::Instance()->GetSDHandle(); + } + else + { + // Init the USB device if mounted after launch + handle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); + if (handle == NULL) + DeviceHandler::Instance()->MountAllUSB(true); + } // Select the next valid partition, even if that's the same one int fs_type = 0; @@ -206,12 +243,20 @@ int HardDriveSM::GetMenuInternal() int retries = 20; do { - Settings.partition = (Settings.partition + 1) % DeviceHandler::GetUSBPartitionCount(); - fs_type = DeviceHandler::GetFilesystemType(USB1+Settings.partition); + if (Settings.SDMode) + { + Settings.partition = 0; + fs_type = DeviceHandler::GetFilesystemType(SD); + } + else + { + Settings.partition = (Settings.partition + 1) % DeviceHandler::GetUSBPartitionCount(); + fs_type = DeviceHandler::GetFilesystemType(USB1+Settings.partition); + } } while (!IsValidPartition(fs_type, ios) && --retries > 0); - if(fs_type == PART_FS_FAT && Settings.GameSplit == GAMESPLIT_NONE) + if (fs_type == PART_FS_FAT && Settings.GameSplit == GAMESPLIT_NONE) Settings.GameSplit = GAMESPLIT_4GB; } @@ -221,6 +266,12 @@ int HardDriveSM::GetMenuInternal() if (++Settings.MultiplePartitions >= MAX_ON_OFF) Settings.MultiplePartitions = 0; } + //! Settings: SD Card Mode + else if (strncmp(Settings.ConfigPath, "sd", 2) == 0 && ret == ++Idx) + { + if (++Settings.SDMode >= MAX_ON_OFF) Settings.SDMode = 0; + } + //! Settings: USB Port else if (ret == ++Idx) { @@ -252,7 +303,7 @@ int HardDriveSM::GetMenuInternal() { if (++Settings.GameSplit >= GAMESPLIT_MAX) { - if(DeviceHandler::GetFilesystemType(USB1+Settings.partition) == PART_FS_FAT) + if (DeviceHandler::GetFilesystemType(Settings.SDMode ? SD : USB1+Settings.partition) == PART_FS_FAT) Settings.GameSplit = GAMESPLIT_2GB; else Settings.GameSplit = GAMESPLIT_NONE; @@ -293,20 +344,25 @@ int HardDriveSM::GetMenuInternal() else if (ret == ++Idx ) { int choice = WindowPrompt(0, tr("Do you want to sync free space info sector on all FAT32 partitions?"), tr("Yes"), tr("Cancel")); - if(choice) + if (choice) { StartProgress(tr("Synchronizing..."), tr("Please wait..."), 0, false, false); - int partCount = DeviceHandler::GetUSBPartitionCount(); - for(int i = 0; i < partCount; ++i) + int partCount = Settings.SDMode ? 1 : DeviceHandler::GetUSBPartitionCount(); + for (int i = 0; i < partCount; ++i) { ShowProgress(i, partCount); - if(DeviceHandler::GetFilesystemType(USB1+i) == PART_FS_FAT) + if (DeviceHandler::GetFilesystemType(Settings.SDMode ? SD : USB1+i) == PART_FS_FAT) { - PartitionHandle *usb = DeviceHandler::Instance()->GetUSBHandleFromPartition(i); - if(!usb) continue; + PartitionHandle *handle; + if (Settings.SDMode) + handle = DeviceHandler::Instance()->GetSDHandle(); + else + handle = DeviceHandler::Instance()->GetUSBHandleFromPartition(i); + if (!handle) + continue; struct statvfs stats; char drive[20]; - snprintf(drive, sizeof(drive), "%s:/", usb->MountName(i)); + snprintf(drive, sizeof(drive), "%s:/", handle->MountName(i)); memset(&stats, 0, sizeof(stats)); memcpy(&stats.f_flag, "SCAN", 4); statvfs(drive, &stats); diff --git a/source/settings/menus/HardDriveSM.hpp b/source/settings/menus/HardDriveSM.hpp index ad97f903..be0be1b6 100644 --- a/source/settings/menus/HardDriveSM.hpp +++ b/source/settings/menus/HardDriveSM.hpp @@ -37,6 +37,7 @@ class HardDriveSM : public SettingsMenu int OldSettingsPartition; int OldSettingsMultiplePartitions; + int OldSettingsSDMode; int oldSettingsUSBAutoMount; int NewSettingsUSBPort; diff --git a/source/settings/menus/LoaderSettings.cpp b/source/settings/menus/LoaderSettings.cpp index 5f3702ab..892cdc4f 100644 --- a/source/settings/menus/LoaderSettings.cpp +++ b/source/settings/menus/LoaderSettings.cpp @@ -234,7 +234,7 @@ LoaderSettings::~LoaderSettings() { if(Settings.LoaderMode & MODE_WIIGAMES && (gameList.GameCount() == 0)) { - WBFS_ReInit(WBFS_DEVICE_USB); + WBFS_ReInit(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); gameList.ReadGameList(); } @@ -774,7 +774,13 @@ int LoaderSettings::GetMenuInternal() //! Settings: EmuNAND Save Mode else if (ret == ++Idx ) { - if (Settings.AutoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(Settings.cios)) + if (Settings.SDMode) + { + // D2X can't load a game from an SD and save to an SD at the same time + WindowPrompt(tr("Warning:"), tr("This setting doesn't work in SD card mode."), tr("OK")); + Settings.NandEmuMode = EMUNAND_OFF; + } + else if (Settings.AutoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(Settings.cios)) { WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK")); Settings.NandEmuMode = EMUNAND_OFF; diff --git a/source/settings/meta.cpp b/source/settings/meta.cpp index 27cac0ee..d0141977 100644 --- a/source/settings/meta.cpp +++ b/source/settings/meta.cpp @@ -42,6 +42,8 @@ int updateMetaXML() MetaXML.SetArgument(line); snprintf(line, sizeof(line), "--mountusb=%d", Settings.USBAutoMount); MetaXML.SetArgument(line); + snprintf(line, sizeof(line), "--sdmode=%d", Settings.SDMode); + MetaXML.SetArgument(line); snprintf(line, sizeof(line), "3.0 r%s", GetRev()); MetaXML.SetVersion(line); @@ -96,7 +98,9 @@ int editMetaArguments() fputs(line, destination); snprintf(line, max_line_size, " --mountusb=%d\n", Settings.USBAutoMount); fputs(line, destination); - + snprintf(line, max_line_size, " --sdmode=%d\n", Settings.SDMode); + fputs(line, destination); + while (strstr(line, "") == NULL) { fgets(line, max_line_size, source); // advance one line diff --git a/source/system/IosLoader.cpp b/source/system/IosLoader.cpp index 11a2f851..45b0883d 100644 --- a/source/system/IosLoader.cpp +++ b/source/system/IosLoader.cpp @@ -22,6 +22,7 @@ #include "libs/libruntimeiospatch/runtimeiospatch.h" extern u32 hdd_sector_size[2]; +extern u8 sdhc_mode_sd; /* * Buffer variables for the IOS info to avoid loading it several times @@ -173,14 +174,17 @@ s32 IosLoader::LoadGameCios(s32 ios) // Unmount fat before reloading IOS. WBFS_CloseAll(); WDVD_Close(); + DeviceHandler::Instance()->UnMountSD(); DeviceHandler::DestroyInstance(); USBStorage2_Deinit(); ret = ReloadIosSafe(ios); // Remount devices after reloading IOS. + sdhc_mode_sd = 0; DeviceHandler::Instance()->MountSD(); - DeviceHandler::Instance()->MountAllUSB(true); + if (!Settings.SDMode) + DeviceHandler::Instance()->MountAllUSB(true); Disc_Init(); return ret; diff --git a/source/usbloader/GameBooter.cpp b/source/usbloader/GameBooter.cpp index f7acb544..324bda6d 100644 --- a/source/usbloader/GameBooter.cpp +++ b/source/usbloader/GameBooter.cpp @@ -59,6 +59,7 @@ #include "neek.hpp" #include "lstub.h" #include "xml/GameTDB.hpp" +#include "usbloader/sdhc.h" #include "wad/nandtitle.h" /* GCC 11 false positives */ @@ -72,6 +73,7 @@ u32 AppEntrypoint = 0; extern bool isWiiVC; // in sys.cpp extern u32 hdd_sector_size[2]; +extern u8 sdhc_mode_sd; extern std::vector d2x_list; extern "C" { @@ -136,7 +138,7 @@ int GameBooter::BootGCMode(struct discHdr *gameHdr) u32 GameBooter::BootPartition(char *dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset) { - gprintf("booting partition IOS %u r%u\n", IOS_GetVersion(), IOS_GetRevision()); + gprintf("Booting partition IOS %u r%u\n", IOS_GetVersion(), IOS_GetRevision()); entry_point p_entry; s32 ret; u64 offset; @@ -207,6 +209,7 @@ void GameBooter::SetupNandEmu(u8 NandEmuMode, const char *NandEmuPath, struct di } else { + //! Can't play from an SD card while saving to an SD card with bases other than 56 & 57 DeviceHandler::Instance()->UnMountSD(); } @@ -222,7 +225,7 @@ int GameBooter::SetupDisc(struct discHdr &gameHeader) { if (gameHeader.type == TYPE_GAME_WII_DISC) { - gprintf("\tloading DVD\n"); + gprintf("Loading DVD\n"); return Disc_Open(); } @@ -243,10 +246,10 @@ int GameBooter::SetupDisc(struct discHdr &gameHeader) gprintf("%d\n", ret); if (ret < 0) return ret; - ret = set_frag_list(gameHeader.id); + ret = set_frag_list(gameHeader.id, Settings.SDMode); if (ret < 0) return ret; - gprintf("\tUSB set to game\n"); + gprintf("%s set to game\n", Settings.SDMode ? "SD" : "USB"); } gprintf("Disc_Open()..."); @@ -286,7 +289,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) struct discHdr gameHeader; memcpy(&gameHeader, gameHdr, sizeof(struct discHdr)); - gprintf("\tBoot Game: %s (%.6s)\n", gameHeader.title, gameHeader.id); + gprintf("Boot Game: %s (%.6s)\n", gameHeader.title, gameHeader.id); // Load the HBC from NAND instead of from the homebrew browser if (memcmp(gameHeader.id, "JODI", 4) == 0) @@ -323,7 +326,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) u64 returnToChoice = strlen(Settings.returnTo) > 0 ? (game_cfg->returnTo ? NandTitles.FindU32(Settings.returnTo) : 0) : 0; u8 NandEmuMode = OFF; const char *NandEmuPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuPath : game_cfg->NandEmuPath.c_str(); - if (gameHeader.type == TYPE_GAME_WII_IMG) + if (gameHeader.type == TYPE_GAME_WII_IMG && !Settings.SDMode) NandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuMode : game_cfg->NandEmuMode; if (gameHeader.type == TYPE_GAME_EMUNANDCHAN) { @@ -422,6 +425,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) ++cios; } + bool sdEmuNAND = false; gprintf("Requested IOS: %d\n", requestedIOS); // Workaround for SpongeBobs Boating Bash if (memcmp(gameHeader.id, "SBV", 3) == 0) @@ -432,10 +436,25 @@ int GameBooter::BootGame(struct discHdr *gameHdr) if (isWiiU()) requestedIOS = 58; else + // Saves will go to NAND in SD card mode if using base 38 requestedIOS = IosLoader::GetD2XIOS(58) ? 58 : 38; gprintf("Applied SpongeBob workaround\n"); } } + // The d2x cIOS can only save to SD cards with bases 56-60 + else if ((strncmp(NandEmuPath, "sd", 2) == 0 && NandEmuMode > EMUNAND_OFF) || Settings.SDMode) + { + for (auto cios = d2x_list.begin(); cios != d2x_list.end();) + { + if (cios->base < 56 || cios->base > 60) + { + cios = d2x_list.erase(cios); + sdEmuNAND = true; + } + else + ++cios; + } + } // Check if there's any cIOS options remaining if (d2x_list.size()) @@ -461,7 +480,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) requestedIOS = cios->base; iosChoice = cios->slot; } - gprintf("Next best IOS: %d\n", requestedIOS); + gprintf("Next best IOS: %d%s\n", requestedIOS, sdEmuNAND ? " (restricted to 56-60)" : ""); } gprintf("Boot with IOS: %d base %d\n", iosChoice, requestedIOS); } @@ -469,7 +488,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) } AppCleanUp(); - gprintf("\tSettings.partition: %d\n", Settings.partition); + gprintf("Settings.partition: %d\n", Settings.partition); s32 ret = -1; @@ -488,6 +507,13 @@ int GameBooter::BootGame(struct discHdr *gameHdr) if (MountGamePartition(false) < 0) return -1; } + //! Boot with custom SD code, otherwise the game ID won't match + else if (sdhc_mode_sd) + { + DeviceHandler::Instance()->UnMountSD(); + sdhc_mode_sd = 0; + DeviceHandler::Instance()->MountSD(); + } //! Modify Wii Message Board to display the game starting here (before NAND Emu) if (Settings.PlaylogUpdate) @@ -553,8 +579,16 @@ int GameBooter::BootGame(struct discHdr *gameHdr) { //! Setup IOS reload block enable_ES_ioctlv_vector(); - if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS) - mload_close(); + if (Settings.SDMode) + { + if (gameList.GetGameFSSD() == PART_FS_WBFS) + mload_close(); + } + else + { + if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS) + mload_close(); + } } } else if (IosLoader::IsD2X(iosChoice)) @@ -583,7 +617,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) //! Load main.dol or alternative dol into memory, start the game apploader and get game entrypoint if (gameHeader.tid == 0) { - gprintf("\tGame Boot\n"); + gprintf("Game Boot\n"); AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, alternatedol, alternatedoloffset); // Reading of game is done we can close devices now ShutDownDevices(usbport); @@ -592,7 +626,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) { //! shutdown now and avoid later crashes with free if memory gets overwritten by channel ShutDownDevices(DeviceHandler::PartitionToUSBPort(std::max(atoi(NandEmuPath + 3) - 1, 0))); - gprintf("\tChannel Boot\n"); + gprintf("Channel Boot\n"); /* Setup video mode */ Disc_SelectVMode(videoChoice, false, NULL, NULL); // Load dol diff --git a/source/usbloader/GameList.cpp b/source/usbloader/GameList.cpp index 2071bc7c..f9cafc3a 100644 --- a/source/usbloader/GameList.cpp +++ b/source/usbloader/GameList.cpp @@ -188,7 +188,7 @@ int GameList::ReadGameList(bool use_cache) int cnt = 0; - if (!Settings.MultiplePartitions) + if (Settings.SDMode || !Settings.MultiplePartitions) { cnt = InternalReadList(Settings.partition); } diff --git a/source/usbloader/GameList.h b/source/usbloader/GameList.h index 55a12218..e9a7efbc 100644 --- a/source/usbloader/GameList.h +++ b/source/usbloader/GameList.h @@ -33,6 +33,7 @@ class GameList struct discHdr * GetCurrentSelected() const { return operator[](selectedGame); } int GetPartitionNumber(const u8 *gameid) const; int GetGameFS(const u8 *gameID) const { return DeviceHandler::Instance()->GetFilesystemType(USB1+GetPartitionNumber(gameID)); } + int GetGameFSSD() const { return DeviceHandler::Instance()->GetFilesystemType(SD); } void RemovePartition(int part_num); std::vector &GetFilteredList(void) { return FilteredList; } std::vector &GetFullGameList(void) { return FullGameList; } diff --git a/source/usbloader/MountGamePartition.cpp b/source/usbloader/MountGamePartition.cpp index f42db9b5..e377a22a 100644 --- a/source/usbloader/MountGamePartition.cpp +++ b/source/usbloader/MountGamePartition.cpp @@ -77,6 +77,43 @@ static int FindGamePartition() return -1; } +static int FindGamePartitionSD() +{ + // Check for a WBFS partition first in case IOS249 Rev < 18 + if (DeviceHandler::GetFilesystemType(0) == PART_FS_WBFS) + { + if (WBFS_OpenPart(0) == 0) + { + GameTitles.SortTitleList(); + Settings.partition = 0; + return 0; + } + } + + if (IosLoader::IsWaninkokoIOS() && NandTitles.VersionOf(TITLE_ID(1, IOS_GetVersion())) < 18) + return -1; + + // Check if it's a FAT/NTFS/EXT partition and if it's got games on it + if (DeviceHandler::GetFilesystemType(0) == PART_FS_NTFS || DeviceHandler::GetFilesystemType(0) == PART_FS_FAT || DeviceHandler::GetFilesystemType(0) == PART_FS_EXT) + { + if (WBFS_OpenPart(0) == 0) + { + u32 count; + // Get the game count... + WBFS_GetCount(0, &count); + if (count > 0) + { + GameTitles.SortTitleList(); + Settings.partition = 0; + return 0; + } + WBFS_Close(0); + } + } + + return -1; +} + static int PartitionChoice() { int ret = -1; @@ -127,13 +164,13 @@ int MountGamePartition(bool ShowGUI) s32 ret = -1; gprintf("MountGamePartition()\n"); - s32 wbfsinit = WBFS_Init(WBFS_DEVICE_USB); + s32 wbfsinit = WBFS_Init(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB); if (wbfsinit < 0) { - if(Settings.LoaderMode & MODE_WIIGAMES) + if (Settings.LoaderMode & MODE_WIIGAMES) { - if(ShowGUI) + if (ShowGUI) ShowError("%s %s", tr( "USB Device not initialized." ), tr("Switching to channel list mode.")); Settings.LoaderMode &= ~MODE_WIIGAMES; @@ -142,19 +179,21 @@ int MountGamePartition(bool ShowGUI) } else { - if(Settings.MultiplePartitions) + if (Settings.SDMode) + ret = WBFS_OpenPart(Settings.partition); + else if (Settings.MultiplePartitions) ret = WBFS_OpenAll(); - else if(!Settings.FirstTimeRun) + else if (!Settings.FirstTimeRun) ret = WBFS_OpenPart(Settings.partition); - if(Settings.LoaderMode & MODE_WIIGAMES) + if (Settings.LoaderMode & MODE_WIIGAMES) { - if(ret < 0) - ret = FindGamePartition(); + if (ret < 0) + ret = Settings.SDMode ? FindGamePartitionSD() : FindGamePartition(); - if(ret < 0) + if (ret < 0) { - if(ShowGUI) + if (ShowGUI && !Settings.SDMode) PartitionChoice(); else Settings.LoaderMode = MODE_NANDCHANNELS; @@ -166,12 +205,12 @@ int MountGamePartition(bool ShowGUI) ret = Disc_Init(); if (ret < 0) { - if(ShowGUI) + if (ShowGUI) WindowPrompt(tr( "Error !" ), tr( "Could not initialize DIP module!" ), tr( "OK" )); Sys_LoadMenu(); } - if(ShowGUI && Settings.CacheCheck && !isCacheCurrent()) + if (ShowGUI && Settings.CacheCheck && !isCacheCurrent()) ResetGameHeaderCache(); gameList.LoadUnfiltered(); diff --git a/source/usbloader/frag.c b/source/usbloader/frag.c index 2d36e93c..eca066d8 100644 --- a/source/usbloader/frag.c +++ b/source/usbloader/frag.c @@ -159,7 +159,7 @@ int frag_remap(FragList *ff, FragList *log, FragList *phy) return 0; } -int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 lba_offset, const u32 hdd_sector_size) +int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 lba_offset, const u32 sector_size) { struct stat st; FragList *fs = NULL; @@ -218,7 +218,7 @@ int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 // if wbfs file format, remap. wbfs_disc_t *d = WBFS_OpenDisc(id); if (!d) { ret_val = -4; WBFS_CloseDisc(d); goto out; } - ret = wbfs_get_fragments(d, &frag_append, fs, hdd_sector_size); + ret = wbfs_get_fragments(d, &frag_append, fs, sector_size); WBFS_CloseDisc(d); if (ret) { ret_val = -5; goto out; } } @@ -232,7 +232,7 @@ int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 wbfs_disc_t *d = WBFS_OpenDisc(id); if (!d) { ret_val = -4; goto out; } frag_init(fw, MAX_FRAG); - ret = wbfs_get_fragments(d, &frag_append, fw, hdd_sector_size); + ret = wbfs_get_fragments(d, &frag_append, fw, sector_size); if (ret) { ret_val = -5; goto out; } WBFS_CloseDisc(d); // DEBUG: frag_list->num = MAX_FRAG-10; // stress test @@ -262,17 +262,16 @@ int get_frag_list(u8 *id) return WBFS_GetFragList(id); } -int set_frag_list(u8 *id) +int set_frag_list(u8 *id, bool sd_only) { - if (frag_list == NULL) { + if (frag_list == NULL) return -2; - } // (+1 for header which is same size as fragment) int size = sizeof(Fragment) * (frag_list->num + 1); gprintf("Calling WDVD_SetFragList, frag list size %d\n", size); - int ret = WDVD_SetFragList(WBFS_MIN_DEVICE, frag_list, size); + int ret = WDVD_SetFragList(sd_only ? 2 : WBFS_DEVICE_USB, frag_list, size); free(frag_list); frag_list = NULL; diff --git a/source/usbloader/frag.h b/source/usbloader/frag.h index 57c7fedb..1e038700 100644 --- a/source/usbloader/frag.h +++ b/source/usbloader/frag.h @@ -39,9 +39,9 @@ int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u3 int frag_remap(FragList *ff, FragList *log, FragList *phy); -int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 lba_offset, const u32 hdd_sector_size); +int get_frag_list_for_file(char *fname, u8 *id, const u8 wbfs_part_fs, const u32 lba_offset, const u32 sector_size); int get_frag_list(u8 *id); -int set_frag_list(u8 *id); +int set_frag_list(u8 *id, bool sd_only); #ifdef __cplusplus } diff --git a/source/usbloader/sdhc.c b/source/usbloader/sdhc.c index af05f095..d5400547 100644 --- a/source/usbloader/sdhc.c +++ b/source/usbloader/sdhc.c @@ -14,7 +14,7 @@ #define SDHC_HEAPSIZE 0x8000 #define SDHC_MEM2_SIZE 0x10000 -int sdhc_mode_sd = 0; +u8 sdhc_mode_sd = 0; /* Variables */ static char fs[] ATTRIBUTE_ALIGN( 32 ) = "/dev/sdio/sdhc"; diff --git a/source/usbloader/sdhc.h b/source/usbloader/sdhc.h index 5d3d4bb9..f78b9677 100644 --- a/source/usbloader/sdhc.h +++ b/source/usbloader/sdhc.h @@ -14,7 +14,6 @@ extern "C" bool SDHC_Close(void); bool SDHC_ReadSectors(u32, u32, void *); bool SDHC_WriteSectors(u32, u32, void *); - extern int sdhc_mode_sd; #ifdef __cplusplus } diff --git a/source/usbloader/wbfs.cpp b/source/usbloader/wbfs.cpp index d0500a54..a788d159 100644 --- a/source/usbloader/wbfs.cpp +++ b/source/usbloader/wbfs.cpp @@ -11,6 +11,7 @@ #include "usbloader/wbfs/wbfs_fat.h" #include "usbloader/wbfs/wbfs_ntfs.h" #include "usbloader/wbfs/wbfs_ext.h" +#include "settings/CSettings.h" #include "usbloader/GameList.h" #include "menu/menus.h" @@ -51,14 +52,22 @@ s32 WBFS_Init(u32 device) s32 WBFS_ReInit(u32 device) { WBFS_CloseAll(); - DeviceHandler::Instance()->UnMountAllUSB(); - DeviceHandler::Instance()->MountAllUSB(); + if (device == WBFS_DEVICE_SDHC) + { + DeviceHandler::Instance()->UnMountSD(); + DeviceHandler::Instance()->MountSD(); + } + else + { + DeviceHandler::Instance()->UnMountAllUSB(); + DeviceHandler::Instance()->MountAllUSB(); + } s32 ret = -1; - if(Settings.MultiplePartitions) - ret = WBFS_OpenAll(); - else + if (device == WBFS_DEVICE_SDHC || !Settings.MultiplePartitions) ret = WBFS_OpenPart(Settings.partition); + else + ret = WBFS_OpenAll(); return ret; } @@ -79,9 +88,20 @@ s32 WBFS_OpenAll() s32 WBFS_OpenPart(int part_num) { - PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(part_num); - if(!usbHandle || part_num < 0 || part_num >= DeviceHandler::GetUSBPartitionCount()) - return -1; + PartitionHandle *handle; + + if (Settings.SDMode) + { + handle = DeviceHandler::Instance()->GetSDHandle(); + if(!handle || part_num < 0) + return -1; + } + else + { + handle = DeviceHandler::Instance()->GetUSBHandleFromPartition(part_num); + if(!handle || part_num < 0 || part_num >= DeviceHandler::GetUSBPartitionCount()) + return -1; + } // close WBFS_Close(part_num); @@ -89,26 +109,26 @@ s32 WBFS_OpenPart(int part_num) if(part_num >= (int) WbfsList.size()) WbfsList.resize(part_num+1); - int portPart = DeviceHandler::PartitionToPortPartition(part_num); - int usbPort = DeviceHandler::PartitionToUSBPort(part_num); + int portPart = Settings.SDMode ? 0 : DeviceHandler::PartitionToPortPartition(part_num); + int usbPort = Settings.SDMode ? 0 : DeviceHandler::PartitionToUSBPort(part_num); - gprintf("\tWBFS_OpenPart: filesystem: %s, start sector %u, sector count: %u\n", usbHandle->GetFSName(portPart), usbHandle->GetLBAStart(portPart), usbHandle->GetSecCount(portPart)); + gprintf("\tWBFS_OpenPart: filesystem: %s, start sector %u, sector count: %u\n", handle->GetFSName(portPart), handle->GetLBAStart(portPart), handle->GetSecCount(portPart)); - if (strncmp(usbHandle->GetFSName(portPart), "FAT", 3) == 0) + if (strncmp(handle->GetFSName(portPart), "FAT", 3) == 0) { - WbfsList[part_num] = new Wbfs_Fat(usbHandle->GetLBAStart(portPart), usbHandle->GetSecCount(portPart), part_num, usbPort); + WbfsList[part_num] = new Wbfs_Fat(handle->GetLBAStart(portPart), handle->GetSecCount(portPart), part_num, usbPort); } - else if (strncmp(usbHandle->GetFSName(portPart), "NTFS", 4) == 0) + else if (strncmp(handle->GetFSName(portPart), "NTFS", 4) == 0) { - WbfsList[part_num] = new Wbfs_Ntfs(usbHandle->GetLBAStart(portPart), usbHandle->GetSecCount(portPart), part_num, usbPort); + WbfsList[part_num] = new Wbfs_Ntfs(handle->GetLBAStart(portPart), handle->GetSecCount(portPart), part_num, usbPort); } - else if (strncmp(usbHandle->GetFSName(portPart), "LINUX", 5) == 0) + else if (strncmp(handle->GetFSName(portPart), "LINUX", 5) == 0) { - WbfsList[part_num] = new Wbfs_Ext(usbHandle->GetLBAStart(portPart), usbHandle->GetSecCount(portPart), part_num, usbPort); + WbfsList[part_num] = new Wbfs_Ext(handle->GetLBAStart(portPart), handle->GetSecCount(portPart), part_num, usbPort); } - else if (strncmp(usbHandle->GetFSName(portPart), "WBFS", 4) == 0) + else if (strncmp(handle->GetFSName(portPart), "WBFS", 4) == 0) { - WbfsList[part_num] = new Wbfs_Wbfs(usbHandle->GetLBAStart(portPart), usbHandle->GetSecCount(portPart), part_num, usbPort); + WbfsList[part_num] = new Wbfs_Wbfs(handle->GetLBAStart(portPart), handle->GetSecCount(portPart), part_num, usbPort); } else { diff --git a/source/usbloader/wbfs/wbfs_base.cpp b/source/usbloader/wbfs/wbfs_base.cpp index 94112d6a..f892a652 100644 --- a/source/usbloader/wbfs/wbfs_base.cpp +++ b/source/usbloader/wbfs/wbfs_base.cpp @@ -22,7 +22,7 @@ s32 Wbfs::Init(u32 device) { s32 ret; - switch (WBFS_DEVICE_USB) + switch (device) { case WBFS_DEVICE_USB: /* Initialize USB storage */ diff --git a/source/usbloader/wbfs/wbfs_fat.cpp b/source/usbloader/wbfs/wbfs_fat.cpp index c89641d2..854a454c 100644 --- a/source/usbloader/wbfs/wbfs_fat.cpp +++ b/source/usbloader/wbfs/wbfs_fat.cpp @@ -59,7 +59,18 @@ s32 Wbfs_Fat::Open() { Close(); - if(partition < (u32) DeviceHandler::GetUSBPartitionCount()) + if (Settings.SDMode) + { + PartitionHandle *sdHandle = DeviceHandler::Instance()->GetSDHandle(); + if (lba == sdHandle->GetLBAStart(0)) + { + snprintf(wbfs_fs_drive, sizeof(wbfs_fs_drive), "sd:"); + return 0; + } + return -1; + } + + if (partition < (u32)DeviceHandler::GetUSBPartitionCount()) { PartitionHandle *usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(partition); int portPart = DeviceHandler::PartitionToPortPartition(partition); @@ -762,8 +773,11 @@ wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path) // 1 cluster less than 4gb u64 OPT_split_size = 4LL * 1024 * 1024 * 1024 - 32 * 1024; - if(Settings.GameSplit == GAMESPLIT_NONE && DeviceHandler::GetFilesystemType(USB1+Settings.partition) != PART_FS_FAT) - OPT_split_size = (u64) 100LL * 1024 * 1024 * 1024 - 32 * 1024; + if(Settings.SDMode && Settings.GameSplit == GAMESPLIT_NONE && DeviceHandler::GetFilesystemType(SD) != PART_FS_FAT) + OPT_split_size = (u64) 100LL * 1024 * 1024 * 1024 - 32 * 1024; + + else if(Settings.GameSplit == GAMESPLIT_NONE && DeviceHandler::GetFilesystemType(USB1+Settings.partition) != PART_FS_FAT) + OPT_split_size = (u64) 100LL * 1024 * 1024 * 1024 - 32 * 1024; else if(Settings.GameSplit == GAMESPLIT_2GB) // 1 cluster less than 2gb diff --git a/source/usbloader/wbfs/wbfs_wbfs.cpp b/source/usbloader/wbfs/wbfs_wbfs.cpp index 55b13e43..bddffad6 100644 --- a/source/usbloader/wbfs/wbfs_wbfs.cpp +++ b/source/usbloader/wbfs/wbfs_wbfs.cpp @@ -19,7 +19,10 @@ s32 Wbfs_Wbfs::Open() PartInfo.hdd_sector_size = hdd_sector_size[usbport]; PartInfo.partition_lba = lba; PartInfo.partition_num_sec = size; - PartInfo.handle = (usbport == 0) ? DeviceHandler::GetUSB0Interface() : DeviceHandler::GetUSB1Interface(); + if (Settings.SDMode) + PartInfo.handle = DeviceHandler::GetSDInterface(); + else + PartInfo.handle = (usbport == 0) ? DeviceHandler::GetUSB0Interface() : DeviceHandler::GetUSB1Interface(); u8 * buffer = (u8 *) malloc(MAX_WBFS_SECTORSIZE); memset(buffer, 0, MAX_WBFS_SECTORSIZE); diff --git a/source/wad/nandtitle.cpp b/source/wad/nandtitle.cpp index 348e13da..52b27302 100644 --- a/source/wad/nandtitle.cpp +++ b/source/wad/nandtitle.cpp @@ -277,7 +277,6 @@ u16 NandTitle::VersionOf(u64 tid) } } return 0; - } u16 NandTitle::VersionFromIndex(u32 i) diff --git a/svnrev.sh b/svnrev.sh index cac2f98b..d98bbbd2 100644 --- a/svnrev.sh +++ b/svnrev.sh @@ -53,6 +53,7 @@ cat < ./HBC/meta.xml --bootios=58 --usbport=0 --mountusb=1 + --sdmode=0 remove this line to enable arguments -->