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."
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á:"

View File

@ -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:"

View File

@ -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:"

View File

@ -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 ""

View File

@ -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ä:"

View File

@ -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:"

View File

@ -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:"

View File

@ -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 "Χρόνος που απομένει:"

View File

@ -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õ"

View File

@ -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:"

View File

@ -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 "残り時間:"

View File

@ -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 "시간 남음:"

View File

@ -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:"

View File

@ -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"

View File

@ -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:"

View File

@ -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:"

View File

@ -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 "Осталось времени:"

View File

@ -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 "剩余时间:"

View File

@ -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:"

View File

@ -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:"

View File

@ -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 "剩餘時間:"

View File

@ -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 "เหลือเวลาอีก:"

View File

@ -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:"

View File

@ -30,8 +30,6 @@
#include <ogc/system.h>
#include <sdcard/wiisd_io.h>
#include <sdcard/gcsd.h>
#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)
{

View File

@ -26,8 +26,13 @@
#ifndef DEVICE_HANDLER_HPP_
#define DEVICE_HANDLER_HPP_
#include <sdcard/wiisd_io.h>
#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;
};

View File

@ -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)
{

View File

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

View File

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

View File

@ -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;

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)
{
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')){
// 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 {
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,35 +223,34 @@ 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)
@ -258,9 +265,10 @@ static int test_parition_skip(u32 partition_type, partition_selector_t 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_type[32]; // XXX: don't know the real maximum
u32 n_partitions;
@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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" ));
if (Settings.SDMode)
{
DeviceHandler::Instance()->UnMountSD();
DeviceHandler::Instance()->MountSD();
}
else
{
DeviceHandler::Instance()->UnMountAllUSB();
DeviceHandler::Instance()->MountAllUSB();
}
timenow = time(0);
}
while (timenow-starttime < 30);

View File

@ -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)
{

View File

@ -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);

View File

@ -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,11 +100,15 @@ 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.USBAutoMount != oldSettingsUSBAutoMount ||
Settings.SDMode != OldSettingsSDMode)
{
if(!Settings.SDMode)
{
WBFS_CloseAll();
@ -115,7 +125,7 @@ HardDriveSM::~HardDriveSM()
NewSettingsUSBPort = -1;
}
WBFS_Init(WBFS_DEVICE_USB);
WBFS_Init(Settings.SDMode ? WBFS_DEVICE_SDHC : WBFS_DEVICE_USB);
if(Settings.MultiplePartitions)
WBFS_OpenAll();
else
@ -124,11 +134,19 @@ HardDriveSM::~HardDriveSM()
//! 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,23 +224,39 @@ 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)
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;
int ios = IOS_GetVersion();
int retries = 20;
do
{
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);

View File

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

View File

@ -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;

View File

@ -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,6 +98,8 @@ int editMetaArguments()
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--mountusb=%d</arg>\n", Settings.USBAutoMount);
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--sdmode=%d</arg>\n", Settings.SDMode);
fputs(line, destination);
while (strstr(line, "</arguments>") == NULL)
{

View File

@ -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,13 +174,16 @@ 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();
if (!Settings.SDMode)
DeviceHandler::Instance()->MountAllUSB(true);
Disc_Init();

View File

@ -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<struct d2x> 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,10 +579,18 @@ int GameBooter::BootGame(struct discHdr *gameHdr)
{
//! Setup IOS reload block
enable_ES_ioctlv_vector();
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))
{
// Open ES file descriptor for the d2x patches
@ -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

View File

@ -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);
}

View File

@ -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<struct discHdr *> &GetFilteredList(void) { return FilteredList; }
std::vector<struct discHdr> &GetFullGameList(void) { return FullGameList; }

View File

@ -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();

View File

@ -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;

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 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
}

View File

@ -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";

View File

@ -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
}

View File

@ -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();
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())
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
{

View File

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

View File

@ -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,7 +773,10 @@ 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)
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)

View File

@ -19,6 +19,9 @@ s32 Wbfs_Wbfs::Open()
PartInfo.hdd_sector_size = hdd_sector_size[usbport];
PartInfo.partition_lba = lba;
PartInfo.partition_num_sec = size;
if (Settings.SDMode)
PartInfo.handle = DeviceHandler::GetSDInterface();
else
PartInfo.handle = (usbport == 0) ? DeviceHandler::GetUSB0Interface() : DeviceHandler::GetUSB1Interface();
u8 * buffer = (u8 *) malloc(MAX_WBFS_SECTORSIZE);

View File

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

View File

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