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
This commit is contained in:
wiidev 2023-01-01 17:00:35 +00:00
parent ab3273f475
commit df76e45150
55 changed files with 613 additions and 226 deletions

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Zbývá:" msgstr "Zbývá:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SD-kortet kunne ikke tilgås." msgstr "SD-kortet kunne ikke tilgås."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD GameCube Spil Sti" 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!" msgid "This path must be on SD!"
msgstr "Denne sti skal være på SD!" msgstr "Denne sti skal være på SD!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tid tilbage:" msgstr "Tid tilbage:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "Geen toegang tot SD kaart." msgstr "Geen toegang tot SD kaart."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD GameCube Spellen Pad" 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!" msgid "This path must be on SD!"
msgstr "Dit pad moet op de SD kaart zijn!" msgstr "Dit pad moet op de SD kaart zijn!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tijd resterend:" msgstr "Tijd resterend:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "" msgstr ""

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Aikaa jäljellä:" msgstr "Aikaa jäljellä:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "Impossible d'accéder à la carte SD." msgstr "Impossible d'accéder à la carte SD."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "Dossier GameCube sur la carte SD" 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!" msgid "This path must be on SD!"
msgstr "Ce chemin doit être situé sur la carte 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:" msgid "Time left:"
msgstr "Fini dans:" msgstr "Fini dans:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "Auf die SD konnte nicht zugegriffen werden." msgstr "Auf die SD konnte nicht zugegriffen werden."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD GameCube Spiele" 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!" msgid "This path must be on SD!"
msgstr "Dieser Pfad muss auf der SD sein!" msgstr "Dieser Pfad muss auf der SD sein!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Noch:" msgstr "Noch:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "Μη προσπελάσιμη SD." msgstr "Μη προσπελάσιμη SD."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "Τοποθεσία/μονοπάτι τίτλων GameCube στην κάρτα SD" msgstr "Τοποθεσία/μονοπάτι τίτλων GameCube στην κάρτα SD"
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "Το μονοπάτι αυτό πρέπει να κατευθύνει σε αρχείο στην κάρτα SD!" msgstr "Το μονοπάτι αυτό πρέπει να κατευθύνει σε αρχείο στην κάρτα SD!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Χρόνος που απομένει:" msgstr "Χρόνος που απομένει:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Hátralevõ idõ" msgstr "Hátralevõ idõ"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SD inacessibile." msgstr "SD inacessibile."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "Percorso giochi Gamecube su SD" 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!" msgid "This path must be on SD!"
msgstr "Questo percorso deve essere sulla SD!" msgstr "Questo percorso deve essere sulla SD!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tempo rimasto:" msgstr "Tempo rimasto:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SDカードにアクセス出来ません" msgstr "SDカードにアクセス出来ません"
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD GCゲーム" msgstr "SD GCゲーム"
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "このパスはSDにないといけません!" msgstr "このパスはSDにないといけません!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "残り時間:" msgstr "残り時間:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SD 카드에 접속 할 수 없습니다." msgstr "SD 카드에 접속 할 수 없습니다."
msgid "SD Card Mode"
msgstr "SD 카드 모드"
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD 게임큐브 게임 경로" msgstr "SD 게임큐브 게임 경로"
@ -2206,6 +2209,9 @@ msgstr "이 게임에는 여러 개의 디스크가 있습니다. 실행할 디
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "이 경로는 SD에 있어야 합니다!" msgstr "이 경로는 SD에 있어야 합니다!"
msgid "This setting doesn't work in SD card mode."
msgstr "이 설정은 SD 카드 모드에서 작동하지 않습니다."
msgid "Time left:" msgid "Time left:"
msgstr "시간 남음:" msgstr "시간 남음:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tid igjen:" msgstr "Tid igjen:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Czas pozostaly" msgstr "Czas pozostaly"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "Este Cartão SD não pode ser acessado" msgstr "Este Cartão SD não pode ser acessado"
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "Pasta de jogos de GC no Cartão" 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!" msgid "This path must be on SD!"
msgstr "Essa pasta precisa estar no Cartão SD!" msgstr "Essa pasta precisa estar no Cartão SD!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Restam:" msgstr "Restam:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tempo rem:" msgstr "Tempo rem:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Осталось времени:" msgstr "Осталось времени:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SD 卡不能访问。" msgstr "SD 卡不能访问。"
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD GameCube 游戏路径" msgstr "SD GameCube 游戏路径"
@ -2206,6 +2209,9 @@ msgstr "该游戏有多张光盘。请选择想要加载的光盘。"
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "该路径必须位于 SD 卡!" msgstr "该路径必须位于 SD 卡!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "剩余时间:" msgstr "剩余时间:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "No se puede acceder a tarjeta SD." msgstr "No se puede acceder a tarjeta SD."
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "Ruta de juegos GameCube en SD" 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!" msgid "This path must be on SD!"
msgstr "¡Esta ruta debe estar en la SD!" msgstr "¡Esta ruta debe estar en la SD!"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Quedan:" msgstr "Quedan:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Tid kvar:" msgstr "Tid kvar:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "SD卡無法存取" msgstr "SD卡無法存取"
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "SD卡 GameCube遊戲路徑" msgstr "SD卡 GameCube遊戲路徑"
@ -2206,6 +2209,9 @@ msgstr "此遊戲為多重光碟。請選擇光碟啟動。"
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "此路徑必須是在SD卡上" msgstr "此路徑必須是在SD卡上"
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "剩餘時間:" msgstr "剩餘時間:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "เหลือเวลาอีก:" msgstr "เหลือเวลาอีก:"

View File

@ -1920,6 +1920,9 @@ msgstr ""
msgid "SD Card could not be accessed." msgid "SD Card could not be accessed."
msgstr "" msgstr ""
msgid "SD Card Mode"
msgstr ""
msgid "SD GameCube Games Path" msgid "SD GameCube Games Path"
msgstr "" msgstr ""
@ -2206,6 +2209,9 @@ msgstr ""
msgid "This path must be on SD!" msgid "This path must be on SD!"
msgstr "" msgstr ""
msgid "This setting doesn't work in SD card mode."
msgstr ""
msgid "Time left:" msgid "Time left:"
msgstr "Kalan zaman:" msgstr "Kalan zaman:"

View File

@ -30,8 +30,6 @@
#include <ogc/system.h> #include <ogc/system.h>
#include <sdcard/wiisd_io.h> #include <sdcard/wiisd_io.h>
#include <sdcard/gcsd.h> #include <sdcard/gcsd.h>
#include "settings/CSettings.h"
#include "usbloader/usbstorage2.h"
#include "DeviceHandler.hpp" #include "DeviceHandler.hpp"
#include "usbloader/wbfs.h" #include "usbloader/wbfs.h"
#include "system/IosLoader.h" #include "system/IosLoader.h"
@ -120,7 +118,7 @@ bool DeviceHandler::IsInserted(int dev)
void DeviceHandler::UnMount(int dev) void DeviceHandler::UnMount(int dev)
{ {
if(dev == SD) if(dev == SD && !Settings.SDMode)
UnMountSD(); UnMountSD();
else if(dev >= USB1 && dev <= USB8) else if(dev >= USB1 && dev <= USB8)
@ -130,7 +128,7 @@ void DeviceHandler::UnMount(int dev)
bool DeviceHandler::MountSD() bool DeviceHandler::MountSD()
{ {
if(!sd) if(!sd)
sd = new PartitionHandle(&__io_wiisd); sd = new PartitionHandle(GetSDInterface());
if(sd->GetPartitionCount() < 1) if(sd->GetPartitionCount() < 1)
{ {

View File

@ -26,8 +26,13 @@
#ifndef DEVICE_HANDLER_HPP_ #ifndef DEVICE_HANDLER_HPP_
#define DEVICE_HANDLER_HPP_ #define DEVICE_HANDLER_HPP_
#include <sdcard/wiisd_io.h>
#include "usbloader/sdhc.h"
#include "PartitionHandle.h" #include "PartitionHandle.h"
#include "usbloader/usbstorage2.h" #include "usbloader/usbstorage2.h"
#include "settings/CSettings.h"
extern const DISC_INTERFACE __io_sdhc;
/** /**
* libogc device names. * libogc device names.
@ -81,7 +86,7 @@ class DeviceHandler
bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; } bool SD_Inserted() { if(sd) return sd->IsInserted(); return false; }
bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; } bool USB0_Inserted() { if(usb0) return usb0->IsInserted(); return false; }
bool USB1_Inserted() { if(usb1) return usb1->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 UnMountUSB(int pos);
void UnMountAllUSB(); void UnMountAllUSB();
PartitionHandle * GetSDHandle() const { return sd; } PartitionHandle * GetSDHandle() const { return sd; }
@ -90,6 +95,7 @@ class DeviceHandler
PartitionHandle * GetUSBHandleFromPartition(int part) const; PartitionHandle * GetUSBHandleFromPartition(int part) const;
static const DISC_INTERFACE *GetUSB0Interface() { return (IOS_GetVersion() >= 200) ? &__io_usbstorage2_port0 : &__io_usbstorage; } 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 *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 int GetFilesystemType(int dev);
static const char * GetFSName(int dev); static const char * GetFSName(int dev);
static int PathToDriveType(const char * path); static int PathToDriveType(const char * path);
@ -99,15 +105,13 @@ class DeviceHandler
static u16 GetUSBPartitionCount(); static u16 GetUSBPartitionCount();
static int PartitionToPortPartition(int part); static int PartitionToPortPartition(int part);
private: private:
DeviceHandler() : sd(0), gca(0), gcb(0), usb0(0), usb1(0) { } DeviceHandler() : sd(0), usb0(0), usb1(0) { }
~DeviceHandler(); ~DeviceHandler();
bool MountUSB(int part); bool MountUSB(int part);
static DeviceHandler *instance; static DeviceHandler *instance;
PartitionHandle * sd; PartitionHandle * sd;
PartitionHandle * gca;
PartitionHandle * gcb;
PartitionHandle * usb0; PartitionHandle * usb0;
PartitionHandle * usb1; PartitionHandle * usb1;
}; };

View File

@ -92,7 +92,7 @@ PartitionHandle::PartitionHandle(const DISC_INTERFACE *discio)
PartitionHandle::~PartitionHandle() PartitionHandle::~PartitionHandle()
{ {
UnMountAll(); UnMountAll();
//shutdown device //shutdown device
interface->shutdown(); interface->shutdown();

View File

@ -26,8 +26,11 @@
#include "sys.h" #include "sys.h"
#include "svnrev.h" #include "svnrev.h"
#include "gitver.h" #include "gitver.h"
#include "usbloader/sdhc.h"
#include "settings/meta.h"
extern bool isWiiVC; // in sys.cpp extern bool isWiiVC; // in sys.cpp
extern u8 sdhc_mode_sd;
StartUpProcess::StartUpProcess() StartUpProcess::StartUpProcess()
{ {
@ -59,11 +62,10 @@ StartUpProcess::StartUpProcess()
versionTxt->SetTextf("v3.0 Rev. %s (%s)", GetRev(), commitID()); versionTxt->SetTextf("v3.0 Rev. %s (%s)", GetRev(), commitID());
#endif #endif
#if 1 // enable if you release a modded version - enabled by default to differentiate official releases if (strncmp(Settings.ConfigPath, "sd", 2) == 0)
versionTxt->SetTextf("v3.0 Rev. %s mod (%s)", GetRev(), commitID()); cancelTxt = new GuiText("Press B to cancel or A to enable SD card mode", 22, (GXColor){255, 255, 255, 255});
#endif else
cancelTxt = new GuiText("Press B to cancel", 22, (GXColor){255, 255, 255, 255});
cancelTxt = new GuiText("Press B to cancel", 18, (GXColor){255, 255, 255, 255});
cancelTxt->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE); cancelTxt->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
cancelTxt->SetPosition(screenwidth / 2, screenheight / 2 + 90); cancelTxt->SetPosition(screenwidth / 2, screenheight / 2 + 90);
@ -73,6 +75,13 @@ StartUpProcess::StartUpProcess()
cancelBtn = new GuiButton(0, 0); cancelBtn = new GuiButton(0, 0);
cancelBtn->SetTrigger(trigB); 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; drawCancel = false;
} }
@ -86,7 +95,9 @@ StartUpProcess::~StartUpProcess()
delete versionTxt; delete versionTxt;
delete cancelTxt; delete cancelTxt;
delete cancelBtn; delete cancelBtn;
delete sdmodeBtn;
delete trigB; delete trigB;
delete trigA;
} }
int StartUpProcess::ParseArguments(int argc, char *argv[]) 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); 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) if (strlen(argv[i]) == 6 && strchr(argv[i], '=') == 0 && strchr(argv[i], '-') == 0)
quickBoot = i; quickBoot = i;
} }
@ -208,11 +230,21 @@ bool StartUpProcess::USBSpinUp()
UpdatePads(); UpdatePads();
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{
cancelBtn->Update(&userInput[i]); cancelBtn->Update(&userInput[i]);
sdmodeBtn->Update(&userInput[i]);
}
if (cancelBtn->GetState() == STATE_CLICKED) if (cancelBtn->GetState() == STATE_CLICKED)
break; 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()); messageTxt->SetTextf("Waiting for HDD: %i sec left\n", 20 - (int)countDown.elapsed());
Draw(); Draw();
usleep(50000); 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"); 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 // 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); LoadIOS(Settings.LoaderIOS, false);
// Reload to a cIOS if required (old forwarder?) or requested // 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 // Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel
bool USBSuccess = false; bool USBSuccess = false;
if (Settings.USBAutoMount == ON && !isWiiVC) if (Settings.USBAutoMount == ON && !isWiiVC && !Settings.SDMode)
{ {
SetTextf("Initializing USB devices\n"); SetTextf("Initializing USB devices\n");
if (USBSpinUp()) if (USBSpinUp())
@ -344,18 +376,21 @@ int StartUpProcess::Execute(bool quickGameBoot)
SetupPads(); SetupPads();
DeviceHandler::Instance()->MountSD(); DeviceHandler::Instance()->MountSD();
if (Settings.USBAutoMount == ON && USBSuccess) if (Settings.USBAutoMount == ON && !Settings.SDMode && USBSuccess)
{ {
if (USBSpinUp()) if (USBSpinUp())
DeviceHandler::Instance()->MountAllUSB(false); DeviceHandler::Instance()->MountAllUSB(false);
} }
} }
if (!IosLoader::IsHermesIOS() && !IosLoader::IsD2X()) if (sdhc_mode_sd)
editMetaArguments();
if (!IosLoader::IsHermesIOS() && !IosLoader::IsD2X() && !Settings.SDMode)
{ {
Settings.USBPort = 0; 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) if (Settings.USBAutoMount == ON && !isWiiVC)
{ {
@ -364,7 +399,7 @@ int StartUpProcess::Execute(bool quickGameBoot)
DeviceHandler::Instance()->MountAllUSB(); DeviceHandler::Instance()->MountAllUSB();
} }
} }
else if (Settings.USBPort == 2) else if (Settings.USBPort == 2 && !Settings.SDMode)
{ {
if (Settings.USBAutoMount == ON && !isWiiVC) if (Settings.USBAutoMount == ON && !isWiiVC)
{ {

View File

@ -30,7 +30,9 @@ private:
GuiText *versionTxt; GuiText *versionTxt;
GuiText *cancelTxt; GuiText *cancelTxt;
GuiButton *cancelBtn; GuiButton *cancelBtn;
GuiButton *sdmodeBtn;
GuiTrigger *trigB; GuiTrigger *trigB;
GuiTrigger *trigA;
}; };
#endif #endif

View File

@ -57,13 +57,22 @@ bool isCacheCurrent()
std::string list; std::string list;
// GameCube // GameCube
snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubePath); if (!Settings.SDMode)
GetDirectoryList(filepath, list); {
snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubePath);
GetDirectoryList(filepath, list);
}
snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubeSDPath); snprintf(filepath, sizeof(filepath), "%s", Settings.GameCubeSDPath);
GetDirectoryList(filepath, list); GetDirectoryList(filepath, list);
// Wii // Wii
GetListWBFS(list); if (Settings.SDMode)
{
snprintf(filepath, sizeof(filepath), "sd:/wbfs");
GetDirectoryList(filepath, list);
}
else
GetListWBFS(list);
// EmuNAND // EmuNAND
snprintf(filepath, sizeof(filepath), "%s/title/00010001", Settings.NandEmuChanPath); snprintf(filepath, sizeof(filepath), "%s/title/00010001", Settings.NandEmuChanPath);

View File

@ -13,9 +13,8 @@ extern "C"
enum enum
{ {
WBFS_DEVICE_USB = 1, /* USB device */ WBFS_DEVICE_SDHC = 0, /* SDHC device */
WBFS_DEVICE_SDHC WBFS_DEVICE_USB = 1 /* USB device */
/* SDHC device */
}; };
typedef u32 be32_t; typedef u32 be32_t;

View File

@ -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) 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 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 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]; u8 iv[16];
wbfs_memset( iv, 0, sizeof iv ); wbfs_memset(iv, 0, sizeof iv);
wbfs_memcpy( iv, tik + 0x01dc, 8 ); wbfs_memcpy(iv, tik + 0x01dc, 8);
//check byte 0x1f1 in ticket to determine whether or not to use Korean 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 // 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 // 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')){ if (tik[0x01f1] == 0x01 && (tik[0x01e3] == 'K' || tik[0x01e3] == 'Q' || tik[0x01e3] == 'T'))
aes_set_key(korean_key); aes_set_key(korean_key);
} else { else
aes_set_key(common_key); aes_set_key(common_key);
}
aes_decrypt(iv, tik + 0x01bf, title_key, 16); 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) if (data)
{ {
int ret = 0; int ret = 0;
if (len == 0) return; if (len == 0)
return;
ret = d->read(d->fp, offset, len, data); ret = d->read(d->fp, offset, len, data);
if (ret) if (ret)
wbfs_fatal( "error reading disc" ); wbfs_fatal("error reading disc");
} }
if (d->sector_usage_table) 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; d->sector_usage_table[blockno] = 1;
blockno += 1; blockno += 1;
if (len > 0x8000) len -= 0x8000; if (len > 0x8000)
len -= 0x8000;
} while (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) 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]; u8 iv[16];
u32 offset; 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); offset = d->partition_data_offset + ((0x8000 >> 2) * blockno);
partition_raw_read(d, offset, raw, 0x8000); 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; u8 *block = d->tmp_buffer2;
u32 offset_in_block; u32 offset_in_block;
u32 len_in_block; u32 len_in_block;
if (fake && d->sector_usage_table == 0) return; if (fake && d->sector_usage_table == 0)
return;
while (len) while (len)
{ {
offset_in_block = offset % (0x7c00 >> 2); offset_in_block = offset % (0x7c00 >> 2);
len_in_block = 0x7c00 - (offset_in_block << 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) if (!fake)
{ {
partition_read_block(d, offset / (0x7c00 >> 2), block); 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; data += len_in_block;
offset += len_in_block >> 2; offset += len_in_block >> 2;
len -= len_in_block; 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) 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; d->extracted_size = size;
partition_read(d, offset, d->extracted_buffer, size, 0); 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; 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 dol_offset;
u32 fst_offset; u32 fst_offset;
u32 fst_size; u32 fst_size;
u32 apl_offset; u32 apl_offset;
u32 apl_size; u32 apl_size;
u8 *apl_header = wbfs_ioalloc( 0x20 ); u8 *apl_header = wbfs_ioalloc(0x20);
u8 *fst; u8 *fst;
u32 n_files; u32 n_files;
partition_read(d, 0, b, 0x480, 0); 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); partition_read(d, apl_offset, apl_header, 0x20, 0);
apl_size = 0x20 + wbfs_be32(apl_header + 0x14) + wbfs_be32(apl_header + 0x18); apl_size = 0x20 + wbfs_be32(apl_header + 0x14) + wbfs_be32(apl_header + 0x18);
// fake read dol and partition // 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); partition_read(d, dol_offset, 0, (fst_offset - dol_offset) << 2, 1);
if (fst_size) if (fst_size)
{ {
fst = wbfs_ioalloc( fst_size ); fst = wbfs_ioalloc(fst_size);
if (fst == 0) if (fst == 0)
wbfs_fatal( "malloc fst" ); wbfs_fatal("malloc fst");
partition_read(d, fst_offset, fst, fst_size, 0); partition_read(d, fst_offset, fst, fst_size, 0);
n_files = wbfs_be32(fst + 8); n_files = wbfs_be32(fst + 8);
if (d->extract_pathname && strcmp(d->extract_pathname, "FST") == 0) if (d->extract_pathname && strcmp(d->extract_pathname, "FST") == 0)
{ {
// if empty pathname requested return fst // if empty pathname requested return fst
@ -183,19 +189,21 @@ static void do_files(wiidisc_t*d)
if (12 * n_files <= fst_size) 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(b);
wbfs_iofree( apl_header ); wbfs_iofree(apl_header);
} }
static void do_partition(wiidisc_t*d) static void do_partition(wiidisc_t *d)
{ {
u8 *tik = wbfs_ioalloc( 0x2a4 ); u8 *tik = wbfs_ioalloc(0x2a4);
u8 *b = wbfs_ioalloc( 0x1c ); u8 *b = wbfs_ioalloc(0x1c);
u64 tmd_offset; u64 tmd_offset;
u32 tmd_size; u32 tmd_size;
u8 *tmd; u8 *tmd;
@ -215,54 +223,54 @@ static void do_partition(wiidisc_t*d)
h3_offset = wbfs_be32(b + 0x10); h3_offset = wbfs_be32(b + 0x10);
d->partition_data_offset = wbfs_be32(b + 0x14); d->partition_data_offset = wbfs_be32(b + 0x14);
d->partition_block = (d->partition_raw_offset + d->partition_data_offset) >> 13; 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) if (tmd == 0)
wbfs_fatal( "malloc tmd" ); wbfs_fatal("malloc tmd");
partition_raw_read(d, tmd_offset, tmd, tmd_size); 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_buffer = tmd;
d->extracted_size = tmd_size; d->extracted_size = tmd_size;
} }
cert = wbfs_ioalloc( cert_size ); cert = wbfs_ioalloc(cert_size);
if (cert == 0) if (cert == 0)
wbfs_fatal( "malloc cert" ); wbfs_fatal("malloc cert");
partition_raw_read(d, cert_offset, cert, cert_size); partition_raw_read(d, cert_offset, cert, cert_size);
_decrypt_title_key(tik, d->disc_key); _decrypt_title_key(tik, d->disc_key);
partition_raw_read(d, h3_offset, 0, 0x18000); partition_raw_read(d, h3_offset, 0, 0x18000);
wbfs_iofree( b ); wbfs_iofree(b);
wbfs_iofree( tik ); wbfs_iofree(tik);
wbfs_iofree( cert ); wbfs_iofree(cert);
if(tmd != d->extracted_buffer) if(tmd != d->extracted_buffer)
wbfs_iofree( tmd ); wbfs_iofree(tmd);
do_files(d); do_files(d);
} }
static int test_parition_skip(u32 partition_type, partition_selector_t part_sel) static int test_parition_skip(u32 partition_type, partition_selector_t part_sel)
{ {
switch (part_sel) switch (part_sel)
{ {
case ALL_PARTITIONS: case ALL_PARTITIONS:
return 0; return 0;
case REMOVE_UPDATE_PARTITION: case REMOVE_UPDATE_PARTITION:
return (partition_type == 1); return (partition_type == 1);
case ONLY_GAME_PARTITION: case ONLY_GAME_PARTITION:
return (partition_type != 0); return (partition_type != 0);
default: default:
return (partition_type != part_sel); 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_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 n_partitions;
u32 magic; u32 magic;
u32 i; u32 i;
@ -270,8 +278,8 @@ static void do_disc(wiidisc_t*d)
magic = wbfs_be32(b + 24); magic = wbfs_be32(b + 24);
if (magic != 0x5D1C9EA3) if (magic != 0x5D1C9EA3)
{ {
wbfs_iofree( b ); wbfs_iofree(b);
wbfs_error( "not a wii disc" ); wbfs_error("not a wii disc");
return; return;
} }
disc_read(d, 0x40000 >> 2, b, 0x100); 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++) for (i = 0; i < n_partitions; i++)
{ {
d->partition_raw_offset = partition_offset[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 ) ); wiidisc_t *d = wbfs_malloc(sizeof(wiidisc_t));
if (!d) return 0; if (!d)
wbfs_memset( d, 0, sizeof( wiidisc_t ) ); return 0;
wbfs_memset(d, 0, sizeof(wiidisc_t));
d->read = read; d->read = read;
d->fp = fp; d->fp = fp;
d->part_sel = ALL_PARTITIONS; d->part_sel = ALL_PARTITIONS;
d->tmp_buffer = wbfs_ioalloc( 0x8000 ); d->tmp_buffer = wbfs_ioalloc(0x8000);
d->tmp_buffer2 = wbfs_malloc( 0x8000 ); d->tmp_buffer2 = wbfs_malloc(0x8000);
return d; return d;
} }
void wd_close_disc(wiidisc_t *d) void wd_close_disc(wiidisc_t *d)
{ {
wbfs_iofree( d->tmp_buffer ); wbfs_iofree(d->tmp_buffer);
wbfs_free( d->tmp_buffer2 ); wbfs_free(d->tmp_buffer2);
wbfs_free( d ); wbfs_free(d);
} }
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error // 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. // XXX pathname not implemented. files are extracted by their name.
// first file found with that name is returned. // 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; u8 *retval = 0;
d->extract_pathname = pathname; d->extract_pathname = pathname;
@ -325,27 +337,28 @@ u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pa
return retval; 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; d->sector_usage_table = usage_table;
wbfs_memset( usage_table, 0, 143432*2 ); wbfs_memset(usage_table, 0, 143432 * 2);
d->part_sel = selector; d->part_sel = selector;
do_disc(d); do_disc(d);
d->part_sel = ALL_PARTITIONS; d->part_sel = ALL_PARTITIONS;
d->sector_usage_table = 0; 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; u8 *b = partition_table;
u32 partition_offset; u32 partition_offset;
u32 partition_type; u32 partition_type;
u32 n_partitions, i, j; u32 n_partitions, i, j;
u32 *b32; u32 *b32;
if (selector == ALL_PARTITIONS) return; if (selector == ALL_PARTITIONS)
return;
n_partitions = wbfs_be32(b); n_partitions = wbfs_be32(b);
if (wbfs_be32(b + 4) - (0x40000 >> 2) > 0x50) 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; b += (wbfs_be32(b + 4) - (0x40000 >> 2)) * 4;
j = 0; 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); partition_type = wbfs_be32(b + 8 * i + 4);
if (!test_parition_skip(partition_type, selector)) if (!test_parition_skip(partition_type, selector))
{ {
b32 = (u32*) (b + 8 * j); b32 = (u32 *)(b + 8 * j);
b32[0] = wbfs_htonl( partition_offset ); b32[0] = wbfs_htonl(partition_offset);
b32[1] = wbfs_htonl( partition_type ); b32[1] = wbfs_htonl(partition_type);
j++; j++;
} }
} }
b32 = (u32*) (partition_table); b32 = (u32 *)(partition_table);
*b32 = wbfs_htonl( j ); *b32 = wbfs_htonl(j);
} }

View File

@ -962,7 +962,7 @@ int GameBrowseMenu::MainLoop()
this->SetState(STATE_DISABLED); this->SetState(STATE_DISABLED);
if (!(Settings.LoaderMode & MODE_WIIGAMES) && (gameList.GameCount() == 0)) 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.")); ShowError(tr("Failed to initialize the USB storage device."));
else else
{ {
@ -1339,16 +1339,17 @@ int GameBrowseMenu::MainLoop()
if((Settings.LoaderMode & MODE_WIIGAMES) && (gameList.GameCount() == 0)) 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) 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.")); ShowError("%s %s", tr( "USB Device not initialized." ), tr("Switching to channel list mode."));
Settings.LoaderMode &= ~MODE_WIIGAMES; Settings.LoaderMode &= ~MODE_WIIGAMES;
Settings.LoaderMode |= MODE_NANDCHANNELS; Settings.LoaderMode |= MODE_NANDCHANNELS;
} }
else else
{ {
WBFS_ReInit(WBFS_DEVICE_USB); WBFS_ReInit(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB);
} }
gameList.ReadGameList(true); gameList.ReadGameList(true);

View File

@ -73,8 +73,8 @@ int MenuGCInstall()
gcDumper.SetCompressed(Settings.GCInstallAligned); gcDumper.SetCompressed(Settings.GCInstallAligned);
//! If a different main path than the SD path is selected ask where to install //! If a different main path than the SD path is selected ask where to install
int destination = 1; int destination = Settings.SDMode ? 2 : 1;
if(strcmp(Settings.GameCubePath, Settings.GameCubeSDPath) != 0) 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")); destination = WindowPrompt(tr("Where should the game be installed to?"), 0, tr("Main Path"), tr("SD Path"), tr("Cancel"));
if(!destination) if(!destination)
return MENU_DISCLIST; return MENU_DISCLIST;

View File

@ -1141,12 +1141,20 @@ int DiscWait(const char *title, const char *msg, const char *btn1Label, const ch
do do
{ {
gprintf("%i\n", (int) (timenow-starttime)); 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; if (ret >= 0) break;
timerTxt.SetTextf("%i %s", (int) (30-(timenow-starttime)), tr( "seconds left" )); timerTxt.SetTextf("%i %s", (int) (30-(timenow-starttime)), tr( "seconds left" ));
DeviceHandler::Instance()->UnMountAllUSB(); if (Settings.SDMode)
DeviceHandler::Instance()->MountAllUSB(); {
DeviceHandler::Instance()->UnMountSD();
DeviceHandler::Instance()->MountSD();
}
else
{
DeviceHandler::Instance()->UnMountAllUSB();
DeviceHandler::Instance()->MountAllUSB();
}
timenow = time(0); timenow = time(0);
} }
while (timenow-starttime < 30); while (timenow-starttime < 30);

View File

@ -881,7 +881,7 @@ bool CSettings::SetSetting(char *name, char *value)
} }
else if(strcmp(name, "NandEmuMode") == 0) else if(strcmp(name, "NandEmuMode") == 0)
{ {
NandEmuMode = atoi(value); NandEmuMode = SDMode ? EMUNAND_OFF : atoi(value);
} }
else if(strcmp(name, "NandEmuChanMode") == 0) else if(strcmp(name, "NandEmuChanMode") == 0)
{ {

View File

@ -247,6 +247,7 @@ class CSettings
// These variables are not saved to the settings file // These variables are not saved to the settings file
bool FirstTimeRun; bool FirstTimeRun;
bool skipSaving; bool skipSaving;
short SDMode;
protected: protected:
bool ValidVersion(FILE * file); bool ValidVersion(FILE * file);
bool ValidateURL(char *value, int type = 0); bool ValidateURL(char *value, int type = 0);

View File

@ -36,6 +36,9 @@
#include "system/IosLoader.h" #include "system/IosLoader.h"
#include "wad/nandtitle.h" #include "wad/nandtitle.h"
#include "utils/tools.h" #include "utils/tools.h"
#include "FileOperations/fileops.h"
#include "gecko.h"
#include "sys.h"
static const char * OnOffText[] = static const char * OnOffText[] =
{ {
@ -75,6 +78,8 @@ HardDriveSM::HardDriveSM()
int Idx = 0; int Idx = 0;
Options->SetName(Idx++, "%s", tr( "Game/Install Partition" )); Options->SetName(Idx++, "%s", tr( "Game/Install Partition" ));
Options->SetName(Idx++, "%s", tr( "Multiple Partitions" )); 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( "USB Port" ));
Options->SetName(Idx++, "%s", tr( "Mount USB at launch" )); Options->SetName(Idx++, "%s", tr( "Mount USB at launch" ));
Options->SetName(Idx++, "%s", tr( "Install Directories" )); Options->SetName(Idx++, "%s", tr( "Install Directories" ));
@ -86,6 +91,7 @@ HardDriveSM::HardDriveSM()
OldSettingsPartition = Settings.partition; OldSettingsPartition = Settings.partition;
OldSettingsMultiplePartitions = Settings.MultiplePartitions; OldSettingsMultiplePartitions = Settings.MultiplePartitions;
OldSettingsSDMode = Settings.SDMode;
NewSettingsUSBPort = Settings.USBPort; NewSettingsUSBPort = Settings.USBPort;
oldSettingsUSBAutoMount = Settings.USBAutoMount; oldSettingsUSBAutoMount = Settings.USBAutoMount;
@ -94,41 +100,53 @@ HardDriveSM::HardDriveSM()
HardDriveSM::~HardDriveSM() HardDriveSM::~HardDriveSM()
{ {
gprintf("Quit HDD settings: %i\n", Settings.SDMode);
//! if partition has changed, Reinitialize it //! if partition has changed, Reinitialize it
if (Settings.partition != OldSettingsPartition || if (Settings.partition != OldSettingsPartition ||
Settings.MultiplePartitions != OldSettingsMultiplePartitions || Settings.MultiplePartitions != OldSettingsMultiplePartitions ||
Settings.USBPort != NewSettingsUSBPort || Settings.USBPort != NewSettingsUSBPort ||
Settings.USBAutoMount != oldSettingsUSBAutoMount) Settings.USBAutoMount != oldSettingsUSBAutoMount ||
Settings.SDMode != OldSettingsSDMode)
{ {
WBFS_CloseAll(); if(!Settings.SDMode)
if(Settings.USBPort != NewSettingsUSBPort)
{ {
DeviceHandler::Instance()->UnMountAllUSB(); WBFS_CloseAll();
Settings.USBPort = NewSettingsUSBPort;
DeviceHandler::Instance()->MountAllUSB();
if(Settings.partition >= DeviceHandler::GetUSBPartitionCount()) if(Settings.USBPort != NewSettingsUSBPort)
Settings.partition = 0; {
DeviceHandler::Instance()->UnMountAllUSB();
Settings.USBPort = NewSettingsUSBPort;
DeviceHandler::Instance()->MountAllUSB();
// set -1 to edit meta.xml arguments if(Settings.partition >= DeviceHandler::GetUSBPartitionCount())
NewSettingsUSBPort = -1; 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 // edit meta.xml arguments
editMetaArguments(); 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; int Idx = 0;
//! Settings: Game/Install Partition //! Settings: Game/Install Partition
PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); PartitionHandle *handle;
int checkPart = DeviceHandler::PartitionToPortPartition(Settings.partition); 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 //! Get the partition name and it's size in GB's
if(usbHandle) if (handle)
Options->SetValue(Idx++, "%s (%.2fGB)", usbHandle->GetFSName(checkPart), usbHandle->GetSize(checkPart)/GB_SIZE); Options->SetValue(Idx++, "%s (%.2fGB)", handle->GetFSName(checkPart), handle->GetSize(checkPart)/GB_SIZE);
else else
Options->SetValue(Idx++, tr("Not Initialized")); Options->SetValue(Idx++, tr("Not Initialized"));
//! Settings: Multiple Partitions //! Settings: Multiple Partitions
Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.MultiplePartitions] )); 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 //! Settings: USB Port
if(NewSettingsUSBPort == 2) if(NewSettingsUSBPort == 2)
Options->SetValue(Idx++, tr("Both Ports")); Options->SetValue(Idx++, tr("Both Ports"));
@ -195,10 +224,18 @@ int HardDriveSM::GetMenuInternal()
//! Settings: Game/Install Partition //! Settings: Game/Install Partition
if (ret == ++Idx) if (ret == ++Idx)
{ {
// Init the USB device if mounted after launch. PartitionHandle *handle;
PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(Settings.partition); if (Settings.SDMode)
if(usbHandle == NULL) {
DeviceHandler::Instance()->MountAllUSB(true); 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 // Select the next valid partition, even if that's the same one
int fs_type = 0; int fs_type = 0;
@ -206,12 +243,20 @@ int HardDriveSM::GetMenuInternal()
int retries = 20; int retries = 20;
do do
{ {
Settings.partition = (Settings.partition + 1) % DeviceHandler::GetUSBPartitionCount(); if (Settings.SDMode)
fs_type = DeviceHandler::GetFilesystemType(USB1+Settings.partition); {
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); 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; Settings.GameSplit = GAMESPLIT_4GB;
} }
@ -221,6 +266,12 @@ int HardDriveSM::GetMenuInternal()
if (++Settings.MultiplePartitions >= MAX_ON_OFF) Settings.MultiplePartitions = 0; 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 //! Settings: USB Port
else if (ret == ++Idx) else if (ret == ++Idx)
{ {
@ -252,7 +303,7 @@ int HardDriveSM::GetMenuInternal()
{ {
if (++Settings.GameSplit >= GAMESPLIT_MAX) 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; Settings.GameSplit = GAMESPLIT_2GB;
else else
Settings.GameSplit = GAMESPLIT_NONE; Settings.GameSplit = GAMESPLIT_NONE;
@ -293,20 +344,25 @@ int HardDriveSM::GetMenuInternal()
else if (ret == ++Idx ) 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")); 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); StartProgress(tr("Synchronizing..."), tr("Please wait..."), 0, false, false);
int partCount = DeviceHandler::GetUSBPartitionCount(); int partCount = Settings.SDMode ? 1 : DeviceHandler::GetUSBPartitionCount();
for(int i = 0; i < partCount; ++i) for (int i = 0; i < partCount; ++i)
{ {
ShowProgress(i, partCount); 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); PartitionHandle *handle;
if(!usb) continue; if (Settings.SDMode)
handle = DeviceHandler::Instance()->GetSDHandle();
else
handle = DeviceHandler::Instance()->GetUSBHandleFromPartition(i);
if (!handle)
continue;
struct statvfs stats; struct statvfs stats;
char drive[20]; char drive[20];
snprintf(drive, sizeof(drive), "%s:/", usb->MountName(i)); snprintf(drive, sizeof(drive), "%s:/", handle->MountName(i));
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
memcpy(&stats.f_flag, "SCAN", 4); memcpy(&stats.f_flag, "SCAN", 4);
statvfs(drive, &stats); statvfs(drive, &stats);

View File

@ -37,6 +37,7 @@ class HardDriveSM : public SettingsMenu
int OldSettingsPartition; int OldSettingsPartition;
int OldSettingsMultiplePartitions; int OldSettingsMultiplePartitions;
int OldSettingsSDMode;
int oldSettingsUSBAutoMount; int oldSettingsUSBAutoMount;
int NewSettingsUSBPort; int NewSettingsUSBPort;

View File

@ -234,7 +234,7 @@ LoaderSettings::~LoaderSettings()
{ {
if(Settings.LoaderMode & MODE_WIIGAMES && (gameList.GameCount() == 0)) 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(); gameList.ReadGameList();
} }
@ -774,7 +774,13 @@ int LoaderSettings::GetMenuInternal()
//! Settings: EmuNAND Save Mode //! Settings: EmuNAND Save Mode
else if (ret == ++Idx ) 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")); WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK"));
Settings.NandEmuMode = EMUNAND_OFF; Settings.NandEmuMode = EMUNAND_OFF;

View File

@ -42,6 +42,8 @@ int updateMetaXML()
MetaXML.SetArgument(line); MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--mountusb=%d", Settings.USBAutoMount); snprintf(line, sizeof(line), "--mountusb=%d", Settings.USBAutoMount);
MetaXML.SetArgument(line); MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--sdmode=%d", Settings.SDMode);
MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "3.0 r%s", GetRev()); snprintf(line, sizeof(line), "3.0 r%s", GetRev());
MetaXML.SetVersion(line); MetaXML.SetVersion(line);
@ -96,7 +98,9 @@ int editMetaArguments()
fputs(line, destination); fputs(line, destination);
snprintf(line, max_line_size, " <arg>--mountusb=%d</arg>\n", Settings.USBAutoMount); snprintf(line, max_line_size, " <arg>--mountusb=%d</arg>\n", Settings.USBAutoMount);
fputs(line, destination); fputs(line, destination);
snprintf(line, max_line_size, " <arg>--sdmode=%d</arg>\n", Settings.SDMode);
fputs(line, destination);
while (strstr(line, "</arguments>") == NULL) while (strstr(line, "</arguments>") == NULL)
{ {
fgets(line, max_line_size, source); // advance one line fgets(line, max_line_size, source); // advance one line

View File

@ -22,6 +22,7 @@
#include "libs/libruntimeiospatch/runtimeiospatch.h" #include "libs/libruntimeiospatch/runtimeiospatch.h"
extern u32 hdd_sector_size[2]; extern u32 hdd_sector_size[2];
extern u8 sdhc_mode_sd;
/* /*
* Buffer variables for the IOS info to avoid loading it several times * 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. // Unmount fat before reloading IOS.
WBFS_CloseAll(); WBFS_CloseAll();
WDVD_Close(); WDVD_Close();
DeviceHandler::Instance()->UnMountSD();
DeviceHandler::DestroyInstance(); DeviceHandler::DestroyInstance();
USBStorage2_Deinit(); USBStorage2_Deinit();
ret = ReloadIosSafe(ios); ret = ReloadIosSafe(ios);
// Remount devices after reloading IOS. // Remount devices after reloading IOS.
sdhc_mode_sd = 0;
DeviceHandler::Instance()->MountSD(); DeviceHandler::Instance()->MountSD();
DeviceHandler::Instance()->MountAllUSB(true); if (!Settings.SDMode)
DeviceHandler::Instance()->MountAllUSB(true);
Disc_Init(); Disc_Init();
return ret; return ret;

View File

@ -59,6 +59,7 @@
#include "neek.hpp" #include "neek.hpp"
#include "lstub.h" #include "lstub.h"
#include "xml/GameTDB.hpp" #include "xml/GameTDB.hpp"
#include "usbloader/sdhc.h"
#include "wad/nandtitle.h" #include "wad/nandtitle.h"
/* GCC 11 false positives */ /* GCC 11 false positives */
@ -72,6 +73,7 @@ u32 AppEntrypoint = 0;
extern bool isWiiVC; // in sys.cpp extern bool isWiiVC; // in sys.cpp
extern u32 hdd_sector_size[2]; extern u32 hdd_sector_size[2];
extern u8 sdhc_mode_sd;
extern std::vector<struct d2x> d2x_list; extern std::vector<struct d2x> d2x_list;
extern "C" extern "C"
{ {
@ -136,7 +138,7 @@ int GameBooter::BootGCMode(struct discHdr *gameHdr)
u32 GameBooter::BootPartition(char *dolpath, u8 videoselected, u8 alternatedol, u32 alternatedoloffset) 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; entry_point p_entry;
s32 ret; s32 ret;
u64 offset; u64 offset;
@ -207,6 +209,7 @@ void GameBooter::SetupNandEmu(u8 NandEmuMode, const char *NandEmuPath, struct di
} }
else else
{ {
//! Can't play from an SD card while saving to an SD card with bases other than 56 & 57
DeviceHandler::Instance()->UnMountSD(); DeviceHandler::Instance()->UnMountSD();
} }
@ -222,7 +225,7 @@ int GameBooter::SetupDisc(struct discHdr &gameHeader)
{ {
if (gameHeader.type == TYPE_GAME_WII_DISC) if (gameHeader.type == TYPE_GAME_WII_DISC)
{ {
gprintf("\tloading DVD\n"); gprintf("Loading DVD\n");
return Disc_Open(); return Disc_Open();
} }
@ -243,10 +246,10 @@ int GameBooter::SetupDisc(struct discHdr &gameHeader)
gprintf("%d\n", ret); gprintf("%d\n", ret);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = set_frag_list(gameHeader.id); ret = set_frag_list(gameHeader.id, Settings.SDMode);
if (ret < 0) if (ret < 0)
return ret; return ret;
gprintf("\tUSB set to game\n"); gprintf("%s set to game\n", Settings.SDMode ? "SD" : "USB");
} }
gprintf("Disc_Open()..."); gprintf("Disc_Open()...");
@ -286,7 +289,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
struct discHdr gameHeader; struct discHdr gameHeader;
memcpy(&gameHeader, gameHdr, sizeof(struct discHdr)); 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 // Load the HBC from NAND instead of from the homebrew browser
if (memcmp(gameHeader.id, "JODI", 4) == 0) 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; u64 returnToChoice = strlen(Settings.returnTo) > 0 ? (game_cfg->returnTo ? NandTitles.FindU32(Settings.returnTo) : 0) : 0;
u8 NandEmuMode = OFF; u8 NandEmuMode = OFF;
const char *NandEmuPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuPath : game_cfg->NandEmuPath.c_str(); 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; NandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuMode : game_cfg->NandEmuMode;
if (gameHeader.type == TYPE_GAME_EMUNANDCHAN) if (gameHeader.type == TYPE_GAME_EMUNANDCHAN)
{ {
@ -422,6 +425,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
++cios; ++cios;
} }
bool sdEmuNAND = false;
gprintf("Requested IOS: %d\n", requestedIOS); gprintf("Requested IOS: %d\n", requestedIOS);
// Workaround for SpongeBobs Boating Bash // Workaround for SpongeBobs Boating Bash
if (memcmp(gameHeader.id, "SBV", 3) == 0) if (memcmp(gameHeader.id, "SBV", 3) == 0)
@ -432,10 +436,25 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
if (isWiiU()) if (isWiiU())
requestedIOS = 58; requestedIOS = 58;
else else
// Saves will go to NAND in SD card mode if using base 38
requestedIOS = IosLoader::GetD2XIOS(58) ? 58 : 38; requestedIOS = IosLoader::GetD2XIOS(58) ? 58 : 38;
gprintf("Applied SpongeBob workaround\n"); 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 // Check if there's any cIOS options remaining
if (d2x_list.size()) if (d2x_list.size())
@ -461,7 +480,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
requestedIOS = cios->base; requestedIOS = cios->base;
iosChoice = cios->slot; 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); gprintf("Boot with IOS: %d base %d\n", iosChoice, requestedIOS);
} }
@ -469,7 +488,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
} }
AppCleanUp(); AppCleanUp();
gprintf("\tSettings.partition: %d\n", Settings.partition); gprintf("Settings.partition: %d\n", Settings.partition);
s32 ret = -1; s32 ret = -1;
@ -488,6 +507,13 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
if (MountGamePartition(false) < 0) if (MountGamePartition(false) < 0)
return -1; 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) //! Modify Wii Message Board to display the game starting here (before NAND Emu)
if (Settings.PlaylogUpdate) if (Settings.PlaylogUpdate)
@ -553,8 +579,16 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
{ {
//! Setup IOS reload block //! Setup IOS reload block
enable_ES_ioctlv_vector(); enable_ES_ioctlv_vector();
if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS) if (Settings.SDMode)
mload_close(); {
if (gameList.GetGameFSSD() == PART_FS_WBFS)
mload_close();
}
else
{
if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS)
mload_close();
}
} }
} }
else if (IosLoader::IsD2X(iosChoice)) 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 //! Load main.dol or alternative dol into memory, start the game apploader and get game entrypoint
if (gameHeader.tid == 0) if (gameHeader.tid == 0)
{ {
gprintf("\tGame Boot\n"); gprintf("Game Boot\n");
AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, alternatedol, alternatedoloffset); AppEntrypoint = BootPartition(Settings.dolpath, videoChoice, alternatedol, alternatedoloffset);
// Reading of game is done we can close devices now // Reading of game is done we can close devices now
ShutDownDevices(usbport); 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 //! shutdown now and avoid later crashes with free if memory gets overwritten by channel
ShutDownDevices(DeviceHandler::PartitionToUSBPort(std::max(atoi(NandEmuPath + 3) - 1, 0))); ShutDownDevices(DeviceHandler::PartitionToUSBPort(std::max(atoi(NandEmuPath + 3) - 1, 0)));
gprintf("\tChannel Boot\n"); gprintf("Channel Boot\n");
/* Setup video mode */ /* Setup video mode */
Disc_SelectVMode(videoChoice, false, NULL, NULL); Disc_SelectVMode(videoChoice, false, NULL, NULL);
// Load dol // Load dol

View File

@ -188,7 +188,7 @@ int GameList::ReadGameList(bool use_cache)
int cnt = 0; int cnt = 0;
if (!Settings.MultiplePartitions) if (Settings.SDMode || !Settings.MultiplePartitions)
{ {
cnt = InternalReadList(Settings.partition); cnt = InternalReadList(Settings.partition);
} }

View File

@ -33,6 +33,7 @@ class GameList
struct discHdr * GetCurrentSelected() const { return operator[](selectedGame); } struct discHdr * GetCurrentSelected() const { return operator[](selectedGame); }
int GetPartitionNumber(const u8 *gameid) const; int GetPartitionNumber(const u8 *gameid) const;
int GetGameFS(const u8 *gameID) const { return DeviceHandler::Instance()->GetFilesystemType(USB1+GetPartitionNumber(gameID)); } 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); void RemovePartition(int part_num);
std::vector<struct discHdr *> &GetFilteredList(void) { return FilteredList; } std::vector<struct discHdr *> &GetFilteredList(void) { return FilteredList; }
std::vector<struct discHdr> &GetFullGameList(void) { return FullGameList; } std::vector<struct discHdr> &GetFullGameList(void) { return FullGameList; }

View File

@ -77,6 +77,43 @@ static int FindGamePartition()
return -1; 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() static int PartitionChoice()
{ {
int ret = -1; int ret = -1;
@ -127,13 +164,13 @@ int MountGamePartition(bool ShowGUI)
s32 ret = -1; s32 ret = -1;
gprintf("MountGamePartition()\n"); 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 (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.")); ShowError("%s %s", tr( "USB Device not initialized." ), tr("Switching to channel list mode."));
Settings.LoaderMode &= ~MODE_WIIGAMES; Settings.LoaderMode &= ~MODE_WIIGAMES;
@ -142,19 +179,21 @@ int MountGamePartition(bool ShowGUI)
} }
else else
{ {
if(Settings.MultiplePartitions) if (Settings.SDMode)
ret = WBFS_OpenPart(Settings.partition);
else if (Settings.MultiplePartitions)
ret = WBFS_OpenAll(); ret = WBFS_OpenAll();
else if(!Settings.FirstTimeRun) else if (!Settings.FirstTimeRun)
ret = WBFS_OpenPart(Settings.partition); ret = WBFS_OpenPart(Settings.partition);
if(Settings.LoaderMode & MODE_WIIGAMES) if (Settings.LoaderMode & MODE_WIIGAMES)
{ {
if(ret < 0) if (ret < 0)
ret = FindGamePartition(); ret = Settings.SDMode ? FindGamePartitionSD() : FindGamePartition();
if(ret < 0) if (ret < 0)
{ {
if(ShowGUI) if (ShowGUI && !Settings.SDMode)
PartitionChoice(); PartitionChoice();
else else
Settings.LoaderMode = MODE_NANDCHANNELS; Settings.LoaderMode = MODE_NANDCHANNELS;
@ -166,12 +205,12 @@ int MountGamePartition(bool ShowGUI)
ret = Disc_Init(); ret = Disc_Init();
if (ret < 0) if (ret < 0)
{ {
if(ShowGUI) if (ShowGUI)
WindowPrompt(tr( "Error !" ), tr( "Could not initialize DIP module!" ), tr( "OK" )); WindowPrompt(tr( "Error !" ), tr( "Could not initialize DIP module!" ), tr( "OK" ));
Sys_LoadMenu(); Sys_LoadMenu();
} }
if(ShowGUI && Settings.CacheCheck && !isCacheCurrent()) if (ShowGUI && Settings.CacheCheck && !isCacheCurrent())
ResetGameHeaderCache(); ResetGameHeaderCache();
gameList.LoadUnfiltered(); gameList.LoadUnfiltered();

View File

@ -159,7 +159,7 @@ int frag_remap(FragList *ff, FragList *log, FragList *phy)
return 0; 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; struct stat st;
FragList *fs = NULL; 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. // if wbfs file format, remap.
wbfs_disc_t *d = WBFS_OpenDisc(id); wbfs_disc_t *d = WBFS_OpenDisc(id);
if (!d) { ret_val = -4; WBFS_CloseDisc(d); goto out; } 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); WBFS_CloseDisc(d);
if (ret) { ret_val = -5; goto out; } 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); wbfs_disc_t *d = WBFS_OpenDisc(id);
if (!d) { ret_val = -4; goto out; } if (!d) { ret_val = -4; goto out; }
frag_init(fw, MAX_FRAG); 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; } if (ret) { ret_val = -5; goto out; }
WBFS_CloseDisc(d); WBFS_CloseDisc(d);
// DEBUG: frag_list->num = MAX_FRAG-10; // stress test // DEBUG: frag_list->num = MAX_FRAG-10; // stress test
@ -262,17 +262,16 @@ int get_frag_list(u8 *id)
return WBFS_GetFragList(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; return -2;
}
// (+1 for header which is same size as fragment) // (+1 for header which is same size as fragment)
int size = sizeof(Fragment) * (frag_list->num + 1); int size = sizeof(Fragment) * (frag_list->num + 1);
gprintf("Calling WDVD_SetFragList, frag list size %d\n", size); 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); free(frag_list);
frag_list = NULL; frag_list = NULL;

View File

@ -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 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 get_frag_list(u8 *id);
int set_frag_list(u8 *id); int set_frag_list(u8 *id, bool sd_only);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -14,7 +14,7 @@
#define SDHC_HEAPSIZE 0x8000 #define SDHC_HEAPSIZE 0x8000
#define SDHC_MEM2_SIZE 0x10000 #define SDHC_MEM2_SIZE 0x10000
int sdhc_mode_sd = 0; u8 sdhc_mode_sd = 0;
/* Variables */ /* Variables */
static char fs[] ATTRIBUTE_ALIGN( 32 ) = "/dev/sdio/sdhc"; static char fs[] ATTRIBUTE_ALIGN( 32 ) = "/dev/sdio/sdhc";

View File

@ -14,7 +14,6 @@ extern "C"
bool SDHC_Close(void); bool SDHC_Close(void);
bool SDHC_ReadSectors(u32, u32, void *); bool SDHC_ReadSectors(u32, u32, void *);
bool SDHC_WriteSectors(u32, u32, void *); bool SDHC_WriteSectors(u32, u32, void *);
extern int sdhc_mode_sd;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -11,6 +11,7 @@
#include "usbloader/wbfs/wbfs_fat.h" #include "usbloader/wbfs/wbfs_fat.h"
#include "usbloader/wbfs/wbfs_ntfs.h" #include "usbloader/wbfs/wbfs_ntfs.h"
#include "usbloader/wbfs/wbfs_ext.h" #include "usbloader/wbfs/wbfs_ext.h"
#include "settings/CSettings.h"
#include "usbloader/GameList.h" #include "usbloader/GameList.h"
#include "menu/menus.h" #include "menu/menus.h"
@ -51,14 +52,22 @@ s32 WBFS_Init(u32 device)
s32 WBFS_ReInit(u32 device) s32 WBFS_ReInit(u32 device)
{ {
WBFS_CloseAll(); WBFS_CloseAll();
DeviceHandler::Instance()->UnMountAllUSB(); if (device == WBFS_DEVICE_SDHC)
DeviceHandler::Instance()->MountAllUSB(); {
DeviceHandler::Instance()->UnMountSD();
DeviceHandler::Instance()->MountSD();
}
else
{
DeviceHandler::Instance()->UnMountAllUSB();
DeviceHandler::Instance()->MountAllUSB();
}
s32 ret = -1; s32 ret = -1;
if(Settings.MultiplePartitions) if (device == WBFS_DEVICE_SDHC || !Settings.MultiplePartitions)
ret = WBFS_OpenAll();
else
ret = WBFS_OpenPart(Settings.partition); ret = WBFS_OpenPart(Settings.partition);
else
ret = WBFS_OpenAll();
return ret; return ret;
} }
@ -79,9 +88,20 @@ s32 WBFS_OpenAll()
s32 WBFS_OpenPart(int part_num) s32 WBFS_OpenPart(int part_num)
{ {
PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(part_num); PartitionHandle *handle;
if(!usbHandle || part_num < 0 || part_num >= DeviceHandler::GetUSBPartitionCount())
return -1; 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 // close
WBFS_Close(part_num); WBFS_Close(part_num);
@ -89,26 +109,26 @@ s32 WBFS_OpenPart(int part_num)
if(part_num >= (int) WbfsList.size()) if(part_num >= (int) WbfsList.size())
WbfsList.resize(part_num+1); WbfsList.resize(part_num+1);
int portPart = DeviceHandler::PartitionToPortPartition(part_num); int portPart = Settings.SDMode ? 0 : DeviceHandler::PartitionToPortPartition(part_num);
int usbPort = DeviceHandler::PartitionToUSBPort(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 else
{ {

View File

@ -22,7 +22,7 @@ s32 Wbfs::Init(u32 device)
{ {
s32 ret; s32 ret;
switch (WBFS_DEVICE_USB) switch (device)
{ {
case WBFS_DEVICE_USB: case WBFS_DEVICE_USB:
/* Initialize USB storage */ /* Initialize USB storage */

View File

@ -59,7 +59,18 @@ s32 Wbfs_Fat::Open()
{ {
Close(); 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); PartitionHandle *usbHandle = DeviceHandler::Instance()->GetUSBHandleFromPartition(partition);
int portPart = DeviceHandler::PartitionToPortPartition(partition); int portPart = DeviceHandler::PartitionToPortPartition(partition);
@ -762,8 +773,11 @@ wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path)
// 1 cluster less than 4gb // 1 cluster less than 4gb
u64 OPT_split_size = 4LL * 1024 * 1024 * 1024 - 32 * 1024; u64 OPT_split_size = 4LL * 1024 * 1024 * 1024 - 32 * 1024;
if(Settings.GameSplit == GAMESPLIT_NONE && DeviceHandler::GetFilesystemType(USB1+Settings.partition) != PART_FS_FAT) if(Settings.SDMode && Settings.GameSplit == GAMESPLIT_NONE && DeviceHandler::GetFilesystemType(SD) != PART_FS_FAT)
OPT_split_size = (u64) 100LL * 1024 * 1024 * 1024 - 32 * 1024; 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) else if(Settings.GameSplit == GAMESPLIT_2GB)
// 1 cluster less than 2gb // 1 cluster less than 2gb

View File

@ -19,7 +19,10 @@ s32 Wbfs_Wbfs::Open()
PartInfo.hdd_sector_size = hdd_sector_size[usbport]; PartInfo.hdd_sector_size = hdd_sector_size[usbport];
PartInfo.partition_lba = lba; PartInfo.partition_lba = lba;
PartInfo.partition_num_sec = size; 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); u8 * buffer = (u8 *) malloc(MAX_WBFS_SECTORSIZE);
memset(buffer, 0, MAX_WBFS_SECTORSIZE); memset(buffer, 0, MAX_WBFS_SECTORSIZE);

View File

@ -277,7 +277,6 @@ u16 NandTitle::VersionOf(u64 tid)
} }
} }
return 0; return 0;
} }
u16 NandTitle::VersionFromIndex(u32 i) u16 NandTitle::VersionFromIndex(u32 i)

View File

@ -53,6 +53,7 @@ cat <<EOF > ./HBC/meta.xml
<arg>--bootios=58</arg> <arg>--bootios=58</arg>
<arg>--usbport=0</arg> <arg>--usbport=0</arg>
<arg>--mountusb=1</arg> <arg>--mountusb=1</arg>
<arg>--sdmode=0</arg>
</arguments> </arguments>
remove this line to enable arguments --> remove this line to enable arguments -->
<ahb_access/> <ahb_access/>