* Added FAT support (Issue 1054)

* Fixed issue 1058
* Menus splitted to several smaller files, to reduce compile time

This version has FAT support. You can change the used partition in the game load options. Default WBFS will be used, if found. Otherwise the first FAT partition with games will be used. FAT will only work when using Hermes cios (222/223)!!!
This commit is contained in:
e.bovendeur 2009-11-15 19:52:58 +00:00
parent ef43c3d0a2
commit a09abe355f
47 changed files with 3493 additions and 3353 deletions

View File

@ -20,7 +20,7 @@ SOURCES := source source/libwiigui source/images source/fonts source/sounds \
source/libwbfs source/unzip source/language source/mload source/patches \
source/usbloader source/xml source/network source/settings source/prompts \
source/ramdisk source/wad source/banner source/cheats source/homebrewboot \
source/themes
source/themes source/menu
DATA := data
INCLUDES := source
@ -35,7 +35,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg
LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
@ -191,6 +191,12 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
%.bin.o : %.bin
@echo $(notdir $<)
$(bin2o)
%.tik.o : %.tik
@echo $(notdir $<)
$(bin2o)
%.tmd.o : %.tmd
@echo $(notdir $<)
$(bin2o)
export PATH := $(PROJECTDIR)/gettext-bin:$(PATH)

BIN
data/ehcmodule_fat.bin Normal file

Binary file not shown.

View File

@ -1 +1 @@
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\prompts" x="true"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="false"></e><e p="gui\source\network" x="true"></e><e p="gui\source\unzip" x="false"></e><e p="gui\source\usbloader" x="true"></e><e p="gui\source\xml" x="false"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\ramdisk" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\wad" x="false"></e><e p="gui" x="true"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="false"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="true"></e><e p="gui\source\patches" x="false"></e><e p="gui\source\themes" x="false"></e></ViewState></pd>
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="true"></e><e p="gui\source\sysmenu" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\prompts" x="false"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="false"></e><e p="gui\source\network" x="false"></e><e p="gui\source\unzip" x="false"></e><e p="gui\source\usbloader" x="true"></e><e p="gui\source\xml" x="false"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\ramdisk" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\wad" x="false"></e><e p="gui" x="true"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="false"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="false"></e><e p="gui\source\patches" x="false"></e><e p="gui\source\themes" x="false"></e></ViewState></pd>

View File

@ -112,7 +112,7 @@ s32 dump_banner(const u8* discid,const char * dest)
WDVD_ClosePartition();
//fatInitDefault();
//SDCard_Init();
WDVD_SetUSBMode(NULL);
WDVD_SetUSBMode(NULL, 0);
FILE *fp = fopen(dest, "wb");
if(fp)
{

View File

@ -129,7 +129,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size)
return NULL;
Disc_SetUSB(NULL);
wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid);
if(!disc)
{
WindowPrompt(tr("Can't find disc"), 0, tr("OK"));
@ -150,7 +150,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size)
}
wd_close_disc(wdisc);
wbfs_close_disc(disc);
WBFS_CloseDisc(disc);
const U8Entry *fst;

View File

@ -10,28 +10,79 @@
#include "usbloader/usbstorage.h"
//these are the only stable and speed is good
#define CACHE 8
#define CACHE 32
#define SECTORS 64
#define MOUNT_NONE 0
#define MOUNT_SD 1
#define MOUNT_SDHC 2
extern DISC_INTERFACE __io_sdhc;
extern sec_t _FAT_startSector;
int fat_sd_mount = MOUNT_NONE;
sec_t fat_sd_sec = 0; // u32
int fat_usb_mount = 0;
sec_t fat_usb_sec = 0;
int fat_wbfs_mount = 0;
sec_t fat_wbfs_sec = 0;
int USBDevice_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
//right now mounts first FAT-partition
if (fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try first mount with cIOS
return 1;
} else if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
//try first mount with cIOS
if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc
return 1;
if (!fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
return -1;
}
}
return -1;
fat_usb_mount = 1;
fat_usb_sec = _FAT_startSector;
return 0;
}
void USBDevice_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("USB:/");
fat_usb_mount = 0;
fat_usb_sec = 0;
}
int WBFSDevice_Init(u32 sector) {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("WBFS:/");
//right now mounts first FAT-partition
//try first mount with cIOS
if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc
if (!fatMount("WBFS", &__io_usbstorage, 0, CACHE, SECTORS)) {
return -1;
}
}
fat_wbfs_mount = 1;
fat_wbfs_sec = _FAT_startSector;
if (sector && fat_wbfs_sec != sector) {
// This is an error situation...actually, but is ignored in Config loader also
// Should ask Oggzee about it...
}
return 0;
}
void WBFSDevice_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("WBFS:/");
fat_wbfs_mount = 0;
fat_wbfs_sec = 0;
}
int isInserted(const char *path) {
@ -40,18 +91,28 @@ int isInserted(const char *path) {
return __io_sdhc.isInserted() || __io_wiisd.isInserted();
}
int SDCard_Init() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
//right now mounts first FAT-partition
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS))
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) {
fat_sd_mount = MOUNT_SD;
fat_sd_sec = _FAT_startSector;
return 1;
else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE))
}
else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) {
fat_sd_mount = MOUNT_SDHC;
fat_sd_sec = _FAT_startSector;
return 1;
}
return -1;
}
void SDCard_deInit() {
//closing all open Files write back the cache and then shutdown em!
fatUnmount("SD:/");
fat_sd_mount = MOUNT_NONE;
fat_sd_sec = 0;
}

View File

@ -5,8 +5,17 @@
extern "C" {
#endif
extern int fat_sd_mount;
extern sec_t fat_sd_sec;
extern int fat_usb_mount;
extern sec_t fat_usb_sec;
extern int fat_wbfs_mount;
extern sec_t fat_wbfs_sec;
int USBDevice_Init();
void USBDevice_deInit();
int WBFSDevice_Init(u32 sector);
void WBFSDevice_deInit();
int isInserted(const char *path);
int SDCard_Init();
void SDCard_deInit();

View File

@ -26,6 +26,7 @@
#include "settings/cfg.h"
#include "unzip/unzip.h"
#include "unzip/miniunz.h"
#include "usbloader/utils.h"
/*** Extern functions ***/
extern void ResumeGui();
@ -785,10 +786,10 @@ int MenuHomebrewBrowse() {
char filesizetxt[50];
char temp[50];
if (infilesize < MBSIZE)
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KBSIZE);
if (infilesize < MB_SIZE)
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KB_SIZE);
else
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MBSIZE);
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MB_SIZE);
snprintf(temp, sizeof(temp), tr("Load file from: %s ?"), GetIncommingIP());

View File

@ -637,3 +637,57 @@ error:
return tot * (((p->wbfs_sec_sz*1.0) / p->hd_sec_sz) * 512);
}
u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel,
u32 *comp_size, u32 *real_size)
{
int i;
u32 tot = 0, last = 0;
u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s);
wiidisc_t *d = 0;
u8 *used = 0;
used = wbfs_malloc(p->n_wii_sec_per_disc);
if(!used)
ERROR("unable to alloc memory");
d = wd_open_disc(read_src_wii_disc,callback_data);
if(!d)
ERROR("unable to open wii disc");
wd_build_disc_usage(d,sel,used);
wd_close_disc(d);
d = 0;
// count total number to write for spinner
for(i=0; i<p->n_wbfs_sec_per_disc;i++) {
if(block_used(used,i,wii_sec_per_wbfs_sect)) {
tot += wii_sec_per_wbfs_sect;
last = i * wii_sec_per_wbfs_sect;
}
}
error:
if(d)
wd_close_disc(d);
if(used)
wbfs_free(used);
*comp_size = tot;
*real_size = last;
return 0;
}
// trim the file-system to its minimum size
u32 wbfs_trim(wbfs_t*p)
{
u32 maxbl;
load_freeblocks(p);
maxbl = alloc_block(p);
p->n_hd_sec = maxbl<<(p->wbfs_sec_sz_s-p->hd_sec_sz_s);
p->head->n_hd_sec = wbfs_htonl(p->n_hd_sec);
// make all block full
memset(p->freeblks,0,p->n_wbfs_sec/8);
wbfs_sync(p);
// os layer will truncate the file.
return maxbl;
}

View File

@ -219,6 +219,16 @@ float wbfs_estimate_disc(
void *callback_data,
partition_selector_t sel);
// compressed and real size
u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel,
u32 *comp_size, u32 *real_size);
/*! trim the file-system to its minimum size
This allows to use wbfs as a wiidisc container
*/
u32 wbfs_trim(wbfs_t*p);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -115,7 +115,6 @@ noCover(nocover_png)
gameIndex = new int[pagesize];
game = new GuiButton * [pagesize];
titleTT = new GuiTooltip * [pagesize];
coverImg = new GuiImageAsync * [pagesize];
for(int i=0; i < pagesize; i++)
@ -125,11 +124,6 @@ noCover(nocover_png)
//------------------------
gameIndex[i] = GetGameIndex(i, listOffset, gameCnt);
//------------------------
// Tooltip
//------------------------
titleTT[i] = new GuiTooltip(get_title(&gameList[gameIndex[i]]), THEME.tooltipAlpha);
//------------------------
// Image
//------------------------
@ -152,20 +146,6 @@ noCover(nocover_png)
game[i]->SetSoundClick(btnSoundClick);
game[i]->SetClickable(true);
game[i]->SetEffect(EFFECT_GOROUND, IN_SPEED, 90-(pagesize-2*i-1)*DEG_OFFSET/2, RADIUS, 180, 1, 0, RADIUS);
switch((i*3)/pagesize)
{
case 0:
game[i]->SetToolTip(titleTT[i], 122/2, -244/4, ALIGN_LEFT, ALIGN_MIDDLE);
break;
case 1:
game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE);
break;
case 2:
game[i]->SetToolTip(titleTT[i], -122/2, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE);
break;
default:
break;
}
}
}
@ -193,7 +173,6 @@ GuiGameCarousel::~GuiGameCarousel()
for(int i=0; i<pagesize; i++) {
delete coverImg[i];
delete titleTT[i];
delete game[i];
}
delete [] gameIndex;
@ -407,25 +386,20 @@ void GuiGameCarousel::Update(GuiTrigger * t)
if(speed > 0) // rotate right
{
GuiButton *tmpButton;
GuiTooltip *tmpTT;
listOffset = OFFSETLIMIT(listOffset - 1, gameCnt); // set the new listOffset
// Save right Button + TollTip and destroy right Image + Image-Data
delete coverImg[pagesize-1]; coverImg[pagesize-1] = NULL;game[pagesize-1]->SetImage(NULL);
tmpButton = game[pagesize-1];
tmpTT = titleTT[pagesize-1];
// Move all Page-Entries one step right
for (int i=pagesize-1; i>=1; i--)
{
titleTT[i] = titleTT[i-1];
coverImg[i] = coverImg[i-1];
game[i] = game[i-1];
gameIndex[i] = gameIndex[i-1];
}
// set saved Button & gameIndex to right
gameIndex[0] = listOffset;
titleTT[0] = tmpTT;
titleTT[0] ->SetText(get_title(&gameList[gameIndex[0]]));
coverImg[0] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[0]], sizeof(struct discHdr), &noCover);
coverImg[0] ->SetWidescreen(CFG.widescreen);
@ -439,38 +413,19 @@ void GuiGameCarousel::Update(GuiTrigger * t)
game[i]->ResetState();
game[i]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i+1)*DEG_OFFSET/2, 1, 0, RADIUS);
game[i]->UpdateEffects(); // rotate one step for liquid scrolling
// Set Tooltip-Position
switch((i*3)/pagesize)
{
case 0:
game[i]->SetToolTip(titleTT[i], 122/4, -244/4, ALIGN_LEFT, ALIGN_MIDDLE);
break;
case 1:
game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE);
break;
case 2:
game[i]->SetToolTip(titleTT[i], -122/4, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE);
break;
default:
break;
}
}
}
else if(speed < 0) // rotate left
{
GuiButton *tmpButton;
GuiTooltip *tmpTT;
listOffset = OFFSETLIMIT(listOffset + 1, gameCnt); // set the new listOffset
// Save left Button + TollTip and destroy left Image + Image-Data
delete coverImg[0]; coverImg[0] = NULL;game[0]->SetImage(NULL);
tmpButton = game[0];
tmpTT = titleTT[0];
// Move all Page-Entries one step left
for (int i=0; i<(pagesize-1); i++)
{
titleTT[i] = titleTT[i+1];
coverImg[i] = coverImg[i+1];
game[i] = game[i+1];
gameIndex[i] = gameIndex[i+1];
@ -478,8 +433,6 @@ void GuiGameCarousel::Update(GuiTrigger * t)
// set saved Button & gameIndex to right
int ii = pagesize-1;
gameIndex[ii] = OFFSETLIMIT(listOffset + ii, gameCnt);
titleTT[ii] = tmpTT;
titleTT[ii] ->SetText(get_title(&gameList[gameIndex[ii]]));
coverImg[ii] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[ii]], sizeof(struct discHdr), &noCover);
coverImg[ii] ->SetWidescreen(CFG.widescreen);
@ -493,22 +446,6 @@ void GuiGameCarousel::Update(GuiTrigger * t)
game[i]->ResetState();
game[i]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i-3)*DEG_OFFSET/2, 1, 0, RADIUS);
game[i]->UpdateEffects(); // rotate one step for liquid scrolling
// Set Tooltip-Position
switch((i*3)/pagesize)
{
case 0:
game[i]->SetToolTip(titleTT[i], 122/4, -244/4, ALIGN_LEFT, ALIGN_MIDDLE);
break;
case 1:
game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE);
break;
case 2:
game[i]->SetToolTip(titleTT[i], -122/4, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE);
break;
default:
break;
}
}
}

View File

@ -33,7 +33,6 @@ class GuiGameCarousel : public GuiElement
int * gameIndex;
GuiButton ** game;
GuiTooltip ** titleTT;
GuiImageAsync ** coverImg;
GuiText * gamename;

View File

@ -36,6 +36,8 @@
#include "fat.h"
#include "gecko.h"
#include "svnrev.h"
#include "usbloader/partition.h"
#include "usbloader/usbstorage.h"
extern bool geckoinit;
@ -47,6 +49,7 @@ extern bool geckoinit;
FreeTypeGX *fontSystem=0;
FreeTypeGX *fontClock=0;
PartList partitions;
static void BootUpProblems()
{
@ -152,27 +155,24 @@ main(int argc, char *argv[]) {
USBDevice_Init();// seems enough to wake up some HDDs if they are in sleep mode when the loader starts (tested with WD MyPassport Essential 2.5")
ret = IOS_ReloadIOS(249);
ret = IOS_ReloadIOS(222);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
if(ret <0) {
ret = IOS_ReloadIOS(249);
if(ret < 0) {
printf("\n\tERROR: cIOS could not be loaded!\n");
sleep(5);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
}
SDCard_Init();
load_ehc_module();
SDCard_deInit();
ret = WBFS_Init(WBFS_DEVICE_USB);
if (ret < 0) {
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
SDCard_deInit();
ret = IOS_ReloadIOS(249);
if(ret < 0) {
InitVideo(); // Initialise video
Menu_Render();
@ -213,6 +213,7 @@ main(int argc, char *argv[]) {
if (Settings.cios == ios222 && IOS_GetVersion() != 222) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
USBStorage_Deinit();
ret = IOS_ReloadIOS(222);
SDCard_Init();
load_ehc_module();
@ -223,9 +224,11 @@ main(int argc, char *argv[]) {
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
WBFS_Init(WBFS_DEVICE_USB);
} else if (Settings.cios == ios249 && IOS_GetVersion() != 249) {
SDCard_deInit();// unmount SD for reloading IOS
USBDevice_deInit();// unmount USB for reloading IOS
USBStorage_Deinit();
ret = IOS_ReloadIOS(249);
if (ret < 0) {
Settings.cios = ios222;
@ -235,8 +238,11 @@ main(int argc, char *argv[]) {
}
SDCard_Init(); // now mount SD:/
USBDevice_Init(); // and mount USB:/
WBFS_Init(WBFS_DEVICE_USB);
}
// Partition_GetList(&partitions);
if (ret < 0) {
printf("ERROR: cIOS could not be loaded!");
sleep(5);

File diff suppressed because it is too large Load Diff

151
source/menu/menu_check.cpp Normal file
View File

@ -0,0 +1,151 @@
#include <dirent.h>
#include <unistd.h>
#include "menus.h"
#include "wpad.h"
#include "fatmounter.h"
#include "usbloader/getentries.h"
#include "usbloader/wbfs.h"
extern bool load_from_fat;
extern char game_partition[6];
/****************************************************************************
* MenuCheck
***************************************************************************/
int MenuCheck() {
gprintf("\nMenuCheck()");
int menu = MENU_NONE;
int i = 0;
int choice;
s32 ret2, wbfsinit;
OptionList options;
options.length = i;
VIDEO_WaitVSync ();
wbfsinit = WBFS_Init(WBFS_DEVICE_USB);
if (wbfsinit < 0) {
ret2 = WindowPrompt(tr("No USB Device found."), tr("Do you want to retry for 30 secs?"), "cIOS249", "cIOS222", tr("Back to Wii Menu"));
SDCard_deInit();
USBDevice_deInit();
WPAD_Flush(0);
WPAD_Disconnect(0);
WPAD_Shutdown();
if (ret2 == 1) {
Settings.cios = ios249;
} else if (ret2 == 2) {
Settings.cios = ios222;
} else {
Sys_LoadMenu();
}
ret2 = DiscWait(tr("No USB Device"), tr("Waiting for USB Device"), 0, 0, 1);
//reinitialize SD and USB
Wpad_Init();
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight);
if (ret2 < 0) {
WindowPrompt (tr("Error !"),tr("USB Device not found"), tr("OK"));
Sys_LoadMenu();
}
}
ret2 = -1;
memset(game_partition, 0, 6);
load_from_fat = false;
extern PartList partitions;
// Added for slow HDD
for (int runs = 0; runs < 10; runs++) {
if (Partition_GetList(&partitions) != 0) {
sleep(1);
continue;
}
if (Settings.partition != -1 && partitions.num > Settings.partition) {
PartInfo pinfo = partitions.pinfo[Settings.partition];
ret2 = WBFS_OpenPart(pinfo.fs_type == FS_TYPE_FAT32, pinfo.fat_i, partitions.pentry[Settings.partition].sector, partitions.pentry[Settings.partition].size, (char *) &game_partition);
if (ret2 == 0)
{
load_from_fat = pinfo.fs_type == FS_TYPE_FAT32;
break;
}
}
if (partitions.wbfs_n != 0) {
ret2 = WBFS_Open();
for (int p = 0; p < partitions.num; p++) {
if (partitions.pinfo[p].fs_type == FS_TYPE_WBFS) {
Settings.partition = p;
break;
}
}
} else if (Sys_IsHermes() && partitions.fat_n != 0) {
// Loop through FAT partitions, and find the first partition with games on it (if there is one)
u32 count;
for (int i = 0; i < partitions.num; i++) {
if (partitions.pinfo[i].fs_type == FS_TYPE_FAT32) {
if (!WBFS_OpenPart(1, partitions.pinfo[i].fat_i, partitions.pentry[i].sector, partitions.pentry[i].size, (char *) &game_partition)) {
// Get the game count...
WBFS_GetCount(&count);
if (count > 0) {
load_from_fat = true;
Settings.partition = i;
break;
} else {
WBFS_Close();
}
}
}
}
}
if (ret2 >= 0 || load_from_fat) {
cfg_save_global();
break;
}
sleep(1);
}
if (ret2 < 0 && !load_from_fat) {
choice = WindowPrompt(tr("No WBFS or FAT game partition found"),tr("You need to select or format a partition"), tr("Select"), tr("Format"), tr("Return"));
if (choice == 0) {
Sys_LoadMenu();
} else {
load_from_fat = choice == 1;
menu = MENU_FORMAT;
}
}
ret2 = Disc_Init();
if (ret2 < 0) {
WindowPrompt (tr("Error !"),tr("Could not initialize DIP module!"),tr("OK"));
Sys_LoadMenu();
}
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
if (wbfsinit < 0) {
sleep(1);
}
//Spieleliste laden
__Menu_GetEntries(0);
if (menu == MENU_NONE)
menu = MENU_DISCLIST;
//for HDDs with issues
if (wbfsinit < 0) {
sleep(1);
USBDevice_Init();
SDCard_Init();
}
return menu;
}

File diff suppressed because it is too large Load Diff

188
source/menu/menu_format.cpp Normal file
View File

@ -0,0 +1,188 @@
#include <unistd.h>
#include "menus.h"
#include "fatmounter.h"
#include "usbloader/usbstorage.h"
#include "usbloader/utils.h"
#include "usbloader/wbfs.h"
#include "libwiigui/gui_customoptionbrowser.h"
extern bool load_from_fat;
extern char game_partition[6];
/****************************************************************************
* MenuFormat
***************************************************************************/
int MenuFormat() {
USBDevice_deInit();
sleep(1);
USBStorage_Init();
int menu = MENU_NONE;
char imgPath[100];
customOptionList options(MAX_PARTITIONS_EX);
extern PartList partitions;
u32 cnt, counter = 0;
int choice, ret;
char text[ISFS_MAXPATH];
//create the partitionlist
for (cnt = 0; cnt < (u32) partitions.num; cnt++) {
partitionEntry *entry = &partitions.pentry[cnt];
if (load_from_fat && partitions.pinfo[cnt].fs_type != FS_TYPE_FAT32) {
continue; // Skip non FAT partitions when fat loading is enabled.
}
/* Calculate size in gigabytes */
f32 size = entry->size * (partitions.sector_size / GB_SIZE);
if (size) {
options.SetName(counter, "%s %d:",tr("Partition"), cnt+1);
options.SetValue(counter,"%.2fGB", size);
} else {
options.SetName(counter, "%s %d:",tr("Partition"), cnt+1);
options.SetValue(counter,tr("Can't be formatted"));
}
counter++;
}
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
// because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
// GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path);
GuiImageData btnpwroff(imgPath, wiimote_poweroff_png);
snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path);
GuiImageData btnpwroffOver(imgPath, wiimote_poweroff_over_png);
snprintf(imgPath, sizeof(imgPath), "%smenu_button.png", CFG.theme_path);
GuiImageData btnhome(imgPath, menu_button_png);
snprintf(imgPath, sizeof(imgPath), "%smenu_button_over.png", CFG.theme_path);
GuiImageData btnhomeOver(imgPath, menu_button_over_png);
GuiImageData battery(battery_png);
GuiImageData batteryBar(battery_bar_png);
GuiImageData batteryRed(battery_red_png);
GuiImageData batteryBarRed(battery_bar_red_png);
GuiTrigger trigA;
trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
GuiTrigger trigHome;
trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0);
GuiImage poweroffBtnImg(&btnpwroff);
GuiImage poweroffBtnImgOver(&btnpwroffOver);
poweroffBtnImg.SetWidescreen(CFG.widescreen);
poweroffBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1);
GuiImage exitBtnImg(&btnhome);
GuiImage exitBtnImgOver(&btnhomeOver);
exitBtnImg.SetWidescreen(CFG.widescreen);
exitBtnImgOver.SetWidescreen(CFG.widescreen);
GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1);
exitBtn.SetTrigger(&trigHome);
GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10);
optionBrowser.SetPosition(0, 40);
optionBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&poweroffBtn);
w.Append(&exitBtn);
mainWindow->Append(&w);
mainWindow->Append(&optionBrowser);
ResumeGui();
while (menu == MENU_NONE) {
VIDEO_WaitVSync ();
ret = optionBrowser.GetClickedOption();
if(ret >= 0) {
if(Settings.godmode == 1) {
partitionEntry *entry = &partitions.pentry[ret];
if (entry->size) {
if (load_from_fat) {
WBFS_OpenPart(1, partitions.pinfo[ret].fat_i, entry->sector,
entry->size, (char *) &game_partition);
load_from_fat = true;
menu = MENU_DISCLIST;
Settings.partition = ret;
cfg_save_global();
} else {
sprintf(text, "%s %d : %.2fGB",tr("Partition"), ret+1, entry->size * (partitions.sector_size / GB_SIZE));
choice = WindowPrompt( tr("Do you want to format:"), text,tr("Yes"),tr("No"));
if (choice == 1) {
ret = FormatingPartition(tr("Formatting, please wait..."), entry);
if (ret < 0) {
WindowPrompt(tr("Error !"),tr("Failed formating"),tr("Return"));
menu = MENU_SETTINGS;
} else {
sleep(1);
ret = WBFS_Open();
sprintf(text, "%s %s", text,tr("formatted!"));
WindowPrompt(tr("Success:"),text,tr("OK"));
if(ret < 0) {
WindowPrompt(tr("ERROR"), tr("Failed to open partition"), tr("OK"));
Sys_LoadMenu();
}
menu = MENU_DISCLIST;
}
}
}
} else if(Settings.godmode == 0) {
mainWindow->Remove(&optionBrowser);
char entered[20] = "";
int result = OnScreenKeyboard(entered, 20,0);
mainWindow->Append(&optionBrowser);
if ( result == 1 ) {
if (!strcmp(entered, Settings.unlockCode)) { //if password correct
if (Settings.godmode == 0) {
WindowPrompt(tr("Correct Password"),tr("All the features of USB Loader GX are unlocked."),tr("OK"));
Settings.godmode = 1;
}
} else {
WindowPrompt(tr("Wrong Password"),tr("USB Loader GX is protected"),tr("OK"));
}
}
}
}
}
if (shutdown == 1)
Sys_Shutdown();
if (reset == 1)
Sys_Reboot();
if (poweroffBtn.GetState() == STATE_CLICKED) {
choice = WindowPrompt (tr("Shutdown System"),tr("Are you sure?"),tr("Yes"),tr("No"));
if (choice == 1) {
Sys_Shutdown();
}
} else if (exitBtn.GetState() == STATE_CLICKED) {
choice = WindowPrompt (tr("Return to Wii Menu"),tr("Are you sure?"),tr("Yes"),tr("No"));
if (choice == 1) {
Sys_LoadMenu();
}
}
}
HaltGui();
mainWindow->Remove(&optionBrowser);
mainWindow->Remove(&w);
ResumeGui();
return menu;
}

View File

@ -0,0 +1,154 @@
#include "menus.h"
#include "usbloader/usbstorage.h"
#include "usbloader/wbfs.h"
#include "usbloader/disc.h"
#include "usbloader/utils.h"
#include "usbloader/getentries.h"
#include "prompts/ProgressWindow.h"
/****************************************************************************
* MenuInstall
***************************************************************************/
int MenuInstall() {
gprintf("\nMenuInstall()");
int menu = MENU_NONE;
static struct discHdr headerdisc ATTRIBUTE_ALIGN(32);
Disc_SetUSB(NULL);
int ret, choice = 0;
char name[200];
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbattery.png", CFG.theme_path);
GuiImageData battery(imgPath, battery_png);
snprintf(imgPath, sizeof(imgPath), "%sbattery_bar.png", CFG.theme_path);
GuiImageData batteryBar(imgPath, battery_bar_png);
snprintf(imgPath, sizeof(imgPath), "%sbattery_red.png", CFG.theme_path);
GuiImageData batteryRed(imgPath, battery_red_png);
snprintf(imgPath, sizeof(imgPath), "%sbattery_bar_red.png", CFG.theme_path);
GuiImageData batteryBarRed(imgPath, battery_bar_red_png);
HaltGui();
GuiWindow w(screenwidth, screenheight);
mainWindow->Append(&w);
ResumeGui();
while (menu == MENU_NONE) {
VIDEO_WaitVSync ();
ret = DiscWait(tr("Insert Disk"),tr("Waiting..."),tr("Cancel"),0,0);
if (ret < 0) {
WindowPrompt (tr("Error reading Disc"),0,tr("Back"));
menu = MENU_DISCLIST;
break;
}
ret = Disc_Open();
if (ret < 0) {
WindowPrompt (tr("Could not open Disc"),0,tr("Back"));
menu = MENU_DISCLIST;
break;
}
ret = Disc_IsWii();
if (ret < 0) {
choice = WindowPrompt (tr("Not a Wii Disc"),tr("Insert a Wii Disc!"),tr("OK"),tr("Back"));
if (choice == 1) {
menu = MENU_INSTALL;
break;
} else
menu = MENU_DISCLIST;
break;
}
Disc_ReadHeader(&headerdisc);
snprintf(name, sizeof(name), "%s", headerdisc.title);
ret = WBFS_CheckGame(headerdisc.id);
if (ret) {
WindowPrompt (tr("Game is already installed:"),name,tr("Back"));
menu = MENU_DISCLIST;
break;
}
f32 freespace, used;
WBFS_DiskSpace(&used, &freespace);
float gamesize = WBFS_EstimeGameSize()/GB_SIZE;
char gametxt[50];
sprintf(gametxt, "%s : %.2fGB", name, gamesize);
wiilight(1);
choice = WindowPrompt(tr("Continue to install game?"),gametxt,tr("OK"),tr("Cancel"));
if (choice == 1) {
sprintf(gametxt, "%s", tr("Installing game:"));
if (gamesize > freespace) {
char errortxt[50];
sprintf(errortxt, "%s: %.2fGB, %s: %.2fGB",tr("Game Size"), gamesize, tr("Free Space"), freespace);
WindowPrompt(tr("Not enough free space!"),errortxt,tr("OK"));
menu = MENU_DISCLIST;
break;
} else {
USBStorage_Watchdog(0);
SetupGameInstallProgress(gametxt, name);
ret = WBFS_AddGame();
ProgressStop();
USBStorage_Watchdog(1);
wiilight(0);
if (ret != 0) {
WindowPrompt(tr("Install Error!"),0,tr("Back"));
menu = MENU_DISCLIST;
break;
} else {
__Menu_GetEntries(); //get the entries again
GuiSound * instsuccess = NULL;
bgMusic->Pause();
instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume);
instsuccess->SetVolume(Settings.sfxvolume);
instsuccess->SetLoop(0);
instsuccess->Play();
WindowPrompt (tr("Successfully installed:"),name,tr("OK"));
instsuccess->Stop();
delete instsuccess;
bgMusic->Resume();
menu = MENU_DISCLIST;
break;
}
}
} else {
menu = MENU_DISCLIST;
break;
}
if (shutdown == 1) {
wiilight(0);
Sys_Shutdown();
}
if (reset == 1) {
wiilight(0);
Sys_Reboot();
}
}
//Turn off the WiiLight
wiilight(0);
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
return menu;
}

24
source/menu/menus.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _MENUS_H
#define _MENUS_H
#include "libwiigui/gui.h"
#include "language/gettext.h"
#include "prompts/PromptWindows.h"
#include "menu.h"
#include "gecko.h"
#include "filelist.h"
#include "sys.h"
extern void ResumeGui();
extern void HaltGui();
extern GuiWindow * mainWindow;
extern GuiSound * bgMusic;
extern u8 shutdown;
extern u8 reset;
int MenuInstall();
int MenuDiscList();
int MenuFormat();
int MenuCheck();
#endif // _MENUS_H

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
#define size_ehcmodule 32432
extern unsigned char ehcmodule[32432];

View File

@ -16,7 +16,7 @@
*/
#include "mload.h"
#include "ehcmodule.h"
#include "ehcmodule_fat_bin.h"
#include "dip_plugin.h"
#include <malloc.h>
@ -549,7 +549,7 @@ int load_ehc_module()
if(!external_ehcmodule)
{
if(mload_init()<0) return -1;
mload_elf((void *) ehcmodule, &my_data_elf);
mload_elf((void *) ehcmodule_fat_bin, &my_data_elf);
thread_id = mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio);
if(thread_id < 0) return -1;
}

View File

@ -37,6 +37,9 @@
extern struct SSettings Settings;
// Pre-allocate the buffer size for ocarina codes
u8 filebuff[MAX_GCT_SIZE];
u32 do_sd_code(char *filename)
{
FILE *fp;
@ -73,28 +76,17 @@ u32 do_sd_code(char *filename)
}
fseek(fp, 0, SEEK_SET);
filebuff = (u8*) malloc (filesize);
if(filebuff == 0){
fclose(fp);
sleep(2);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
ret = fread(filebuff, 1, filesize, fp);
ret = fread(&filebuff, 1, filesize, fp);
if(ret != filesize){
free(filebuff);
fclose(fp);
USBDevice_deInit();
SDCard_deInit();
return 0;
}
memcpy((void*)0x800027E8,filebuff,filesize);
memcpy((void*)0x800027E8, &filebuff,filesize);
*(vu8*)0x80001807 = 0x01;
free(filebuff);
fclose(fp);
USBDevice_deInit();

View File

@ -27,6 +27,8 @@ extern "C"
{
#endif
#define MAX_GCT_SIZE 2056
//u32 do_fst(u32 fstlocation);
u32 do_sd_code(char *filename);

View File

@ -16,6 +16,7 @@
#include "libwiigui/gui.h"
#include "prompts/ProgressWindow.h"
#include "usbloader/wbfs.h"
#include "usbloader/utils.h"
/*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL;
@ -73,7 +74,7 @@ static void GameInstallProgress() {
//Calculate speed in MB/s
if (elapsed > 0)
speed = KBSIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed);
speed = KB_SIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed);
if (gameinstalldone != gameinstalltotal) {
//Expected time
@ -356,7 +357,7 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done,
//Calculate speed in KB/s
if (elapsed > 0)
speed = done/(elapsed*KBSIZE);
speed = done/(elapsed*KB_SIZE);
if (done != total) {
//Expected time
@ -376,12 +377,12 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done,
}
if (swSize == true) {
if (total < MBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KBSIZE, total/KBSIZE);
else if (total > MBSIZE && total < GBSIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MBSIZE, total/MBSIZE);
if (total < MB_SIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KB_SIZE, total/KB_SIZE);
else if (total > MB_SIZE && total < GB_SIZE)
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MB_SIZE, total/MB_SIZE);
else
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GBSIZE, total/GBSIZE);
snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GB_SIZE, total/GB_SIZE);
}
showProgress = 1;

View File

@ -8,10 +8,6 @@
#ifndef _PROGRESSWINDOW_H_
#define _PROGRESSWINDOW_H_
#define KBSIZE 1024.0
#define MBSIZE 1048576.0
#define GBSIZE 1073741824.0
void InitProgressThread();
void ExitProgressThread();
void SetupGameInstallProgress(char * titl, char * game);

View File

@ -25,6 +25,7 @@
#include "xml/xml.h"
#include "../wad/title.h"
#include "../usbloader/getentries.h"
#include "../usbloader/utils.h"
#define typei 0x00010001
@ -420,10 +421,10 @@ int TitleBrowser(u32 type) {
snprintf(filepath, sizeof(filepath), "%s/wad/tmp.tmp", bootDevice);
if (infilesize < MBSIZE)
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KBSIZE);
if (infilesize < MB_SIZE)
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KB_SIZE);
else
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MBSIZE);
snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MB_SIZE);
snprintf(temp, sizeof(temp), tr("Load file from: %s ?"), GetIncommingIP());

View File

@ -17,6 +17,8 @@
#include "listfiles.h"
#include "sys.h"
#include "cfg.h"
#include "usbloader/partition.h"
#include "usbloader/utils.h"
#define MAXOPTIONS 13
@ -36,7 +38,9 @@ extern u8 shutdown;
extern u8 reset;
extern u8 mountMethod;
extern struct discHdr *dvdheader;
extern PartList partitions;
extern char game_partition[6];
extern bool load_from_fat;
static const char *opts_no_yes[settings_off_on_max] = {trNOOP("No"),trNOOP("Yes") };
static const char *opts_off_on[settings_off_on_max] = {trNOOP("OFF"),trNOOP("ON") };
@ -46,6 +50,14 @@ static const char *opts_cios[settings_ios_max] = {"IOS 249","IOS 222", "IOS 223"
static const char *opts_parentalcontrol[5] = {trNOOP("0 (Everyone)"),trNOOP("1 (Child 7+)"),trNOOP("2 (Teen 12+)"),trNOOP("3 (Mature 16+)"),trNOOP("4 (Adults Only 18+)")};
static const char *opts_error002[settings_error002_max] = {trNOOP("No"),trNOOP("Yes"),trNOOP("Anti")};
bool IsValidPartition(int fs_type, int cios) {
if (cios == 249) {
return fs_type == FS_TYPE_WBFS;
} else {
return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32;
}
}
/****************************************************************************
* MenuSettings
***************************************************************************/
@ -968,11 +980,32 @@ int MenuSettings()
if(ret == Idx && Settings.godmode == 1 && ++Settings.cios >= settings_cios_max)
Settings.cios = 0;
if (Settings.godmode == 1)
options2.SetValue(Idx,"%s", opts_cios[Settings.cios]);
options2.SetValue(Idx, "%s", opts_cios[Settings.cios]);
else
options2.SetValue(Idx, "********");
}
if (ret == ++Idx || firstRun)
{
if (firstRun) options2.SetName(Idx, "%s", tr("Partition"));
if (ret == Idx) {
// Select the next valid partition, even if that's the same one
do
{
Settings.partition = Settings.partition + 1 == partitions.num ? 0 : Settings.partition + 1;
}
while (!IsValidPartition(partitions.pinfo[Settings.partition].fs_type, Settings.cios));
}
PartInfo pInfo = partitions.pinfo[Settings.partition];
f32 partition_size = partitions.pentry[Settings.partition].size * (partitions.sector_size / GB_SIZE);
// Get the partition name and it's size in GB's
options2.SetValue(Idx,"%s%d (%.2fGB)", pInfo.fs_type == FS_TYPE_FAT32 ? "FAT" : "WBFS",
pInfo.fs_type == FS_TYPE_FAT32 ? pInfo.fat_i : pInfo.wbfs_i,
partition_size);
}
if(ret == ++Idx || firstRun)
{
if(firstRun) options2.SetName(Idx, "%s",tr("Quick Boot"));
@ -2016,6 +2049,12 @@ int MenuSettings()
if (opt_override != opt_overridenew && Settings.titlesOverride==0)
titles_default();
// Reinitialize WBFS partition, it might have changed
PartInfo pinfo = partitions.pinfo[Settings.partition];
load_from_fat = pinfo.fs_type == FS_TYPE_FAT32;
WBFS_Close();
WBFS_OpenPart(load_from_fat, Settings.partition, partitions.pentry[Settings.partition].sector, partitions.pentry[Settings.partition].size, (char *) &game_partition);
HaltGui();
mainWindow->RemoveAll();
@ -2038,9 +2077,6 @@ int GameSettings(struct discHdr * header)
int retVal = 0;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
// because destroy GuiSound must wait while sound playing is finished, we use a global sound
if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);

View File

@ -24,7 +24,7 @@ u8 videoChoice = 0;
u8 faveChoice = no;
u8 languageChoice = 0;
u8 viChoice = 0;
u8 iosChoice = 0;
u8 iosChoice = 1; // Default IOS is 222 from now on
u8 parentalcontrolChoice = 0;
u8 fix002 = 0;
u8 reloadblock = 0;
@ -40,6 +40,7 @@ u8 keyset = 0;
u8 favoritevar = 0;
u16 playcount = 0;
u8 listDisplay = 0;
u8 partition = -1;
char alternatedname[40];
#define TITLE_MAX 200
@ -339,7 +340,7 @@ void Global_Default(void) {
Settings.godmode = 1;
Settings.gamesound = 1;
Settings.parentalcontrol = 0;
Settings.cios = ios249;
Settings.cios = ios222;
Settings.xflip = no;
Settings.qboot = no;
Settings.wiilight = 1;
@ -353,6 +354,7 @@ void Global_Default(void) {
snprintf(Settings.db_language, sizeof(Settings.db_language), empty);
Settings.db_JPtoEN = 0;
Settings.screensaver = 3;
Settings.partition = -1;
}
@ -1035,7 +1037,13 @@ void global_cfg_set(char *name, char *val) {
Settings.screensaver = i;
}
return;
}
} else if (strcmp(name, "partition") == 0) {
int i;
if (sscanf(val, "%d", &i) == 1) {
Settings.partition = i;
}
return;
}
cfg_bool("godmode", &Settings.godmode);
@ -1278,6 +1286,7 @@ bool cfg_save_global() { // save global settings
fprintf(f, "error002 = %d\n ", Settings.error002);
fprintf(f, "autonetwork = %d\n ", Settings.autonetwork);
fprintf(f, "discart = %d\n ", Settings.discart);
fprintf(f, "partition = %d\n", Settings.partition);
fclose(f);
return true;
}
@ -1609,6 +1618,7 @@ bool cfg_load_global() {
Settings.gamesoundvolume = 80;
Settings.titlesOverride = 1;
Settings.partition = -1;
char * empty = "";
snprintf(Settings.db_url, sizeof(Settings.db_url), empty);
snprintf(Settings.db_language, sizeof(Settings.db_language), empty);

View File

@ -393,6 +393,7 @@ extern "C" {
u8 gameDisplay;
u8 patchcountrystrings;
u8 screensaver;
u8 partition;
short godmode;
char covers_path[100];
char covers2d_path[100];

View File

@ -14,6 +14,9 @@
#include "sys.h"
#include "wpad.h"
extern char game_partition[6];
extern bool load_from_fat;
//Wiilight stuff
static vu32 *_wiilight_reg = (u32*)0xCD0000C0;
void wiilight(int enable) { // Toggle wiilight (thanks Bool for wiilight source)
@ -62,6 +65,49 @@ void Sys_Reboot(void) {
STM_RebootSystem();
}
int Sys_ChangeIos(int ios) {
s32 prevIos = IOS_GetVersion();
SDCard_deInit();
USBDevice_deInit();
WPAD_Flush(0);
WPAD_Disconnect(0);
WPAD_Shutdown();
WDVD_Close();
USBStorage_Deinit();
s32 ret = IOS_ReloadIOS(ios);
if (ret < 0) {
ios = prevIos;
}
SDCard_Init();
if (ios == 222 || ios == 223) {
load_ehc_module();
}
USBDevice_Init();
PAD_Init();
Wpad_Init();
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight);
WBFS_Init(WBFS_DEVICE_USB);
Disc_Init();
if (load_from_fat && (ios == 222 || ios == 223)) {
WBFS_OpenNamed((char *) &game_partition);
} else {
WBFS_Open();
}
return ret;
}
int Sys_IosReload(int IOS) {
s32 ret = -1;
@ -156,3 +202,7 @@ void Sys_BackToLoader(void) {
// Channel Version
Sys_LoadMenu();
}
bool Sys_IsHermes() {
return IOS_GetVersion() == 222 || IOS_GetVersion() == 223;
}

View File

@ -11,6 +11,8 @@ void Sys_ShutdownToIdel(void);
void Sys_ShutdownToStandby(void);
void Sys_LoadMenu(void);
void Sys_BackToLoader(void);
int Sys_ChangeIos(int ios);
int Sys_IosReload(int IOS);
bool Sys_IsHermes();
#endif

View File

@ -22,6 +22,9 @@
static u32 *buffer = (u32 *)0x93000000;
static u8 *diskid = (u8 *)Disc_ID;
extern int wbfs_part_fat;
extern u32 wbfs_part_idx;
extern u32 wbfs_part_lba;
void __Disc_SetLowMem(void) {
@ -235,8 +238,15 @@ s32 Disc_Wait(void) {
}
s32 Disc_SetUSB(const u8 *id) {
u32 part = 0;
if (wbfs_part_fat) {
part = wbfs_part_lba;
} else {
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
}
/* Set USB mode */
return WDVD_SetUSBMode(id);
return WDVD_SetUSBMode(id, part);
}
s32 Disc_ReadHeader(void *outbuf) {

View File

@ -469,6 +469,7 @@ int __Menu_GetGameList(int t, wchar_t* gameFilter, discHdr ** PgameList, u32 *Pg
if (buffer) free(buffer);
return ret;
}
for (u32 i = 0; i < cnt; i++) {
struct discHdr *header = &buffer[i];

View File

@ -4,7 +4,10 @@
#include "partition.h"
#include "usbstorage.h"
#include "sdhc.h"
#include "utils.h"
#include "libwbfs/libwbfs.h"
#include "wbfs.h"
/* 'partition table' structure */
typedef struct {
@ -15,7 +18,6 @@ typedef struct {
partitionEntry entries[MAX_PARTITIONS];
} ATTRIBUTE_PACKED partitionTable;
s32 Partition_GetEntries(partitionEntry *outbuf, u32 *outval) {
static partitionTable table ATTRIBUTE_ALIGN(32);
@ -48,3 +50,141 @@ s32 Partition_GetEntries(partitionEntry *outbuf, u32 *outval) {
return 0;
}
s32 Partition_GetEntriesEx(partitionEntry *outbuf, u32 *outval, int *num)
{
static partitionTable table ATTRIBUTE_ALIGN(32);
partitionEntry *entry;
u32 i, sector_size;
s32 ret;
int maxpart = *num;
// Get sector size
ret = USBStorage_GetCapacity(&sector_size);
if (ret == 0) return -1;
u32 ext = 0;
u32 next = 0;
// Read partition table
ret = USBStorage_ReadSectors(0, 1, &table);
if (!ret) return -1;
/* Swap endianess */
for (i = 0; i < 4; i++) {
entry = &table.entries[i];
entry->sector = swap32(entry->sector);
entry->size = swap32(entry->size);
if (!ext && entry->type == 0x0f) ext = entry->sector;
}
/* Set partition entries */
memcpy(outbuf, table.entries, sizeof(table.entries));
/* Set sector size */
*outval = sector_size;
// num primary
*num = 4;
next = ext;
// scan extended partition for logical
if (ext) for(i=0; i<maxpart-4; i++) {
ret = USBStorage_ReadSectors(next, 1, &table);
if (!ret) break;
entry = &table.entries[0];
entry->sector = swap32(entry->sector);
entry->size = swap32(entry->size);
if (entry->type && entry->size && entry->sector) {
// rebase to abolute address
entry->sector += next;
// add logical
memcpy(&outbuf[*num], entry, sizeof(*entry));
(*num)++;
// get next
entry++;
if (entry->type && entry->size && entry->sector) {
next = ext + swap32(entry->sector);
} else {
break;
}
}
}
return 0;
}
char* part_type_data(int type)
{
switch (type) {
case 0x01: return "FAT12";
case 0x04: return "FAT16";
case 0x06: return "FAT16"; //+
case 0x07: return "NTFS";
case 0x0b: return "FAT32";
case 0x0c: return "FAT32";
case 0x0e: return "FAT16";
case 0x82: return "LxSWP";
case 0x83: return "LINUX";
case 0x8e: return "LxLVM";
case 0xa8: return "OSX";
case 0xab: return "OSXBT";
case 0xaf: return "OSXHF";
case 0xe8: return "LUKS";
}
return NULL;
}
int get_fs_type(char *buf)
{
// WBFS
wbfs_head_t *head = (wbfs_head_t *)buf;
if (head->magic == wbfs_htonl(WBFS_MAGIC)) return FS_TYPE_WBFS;
// 55AA
if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) {
// FAT
if (memcmp(buf+0x36,"FAT",3) == 0) return FS_TYPE_FAT16;
if (memcmp(buf+0x52,"FAT",3) == 0) return FS_TYPE_FAT32;
// NTFS
if (memcmp(buf+0x03,"NTFS",4) == 0) return FS_TYPE_NTFS;
}
return FS_TYPE_UNK;
}
bool is_type_fat(int type)
{
return (type == FS_TYPE_FAT16 || type == FS_TYPE_FAT32);
}
s32 Partition_GetList(PartList *plist)
{
partitionEntry *entry = NULL;
PartInfo *pinfo = NULL;
int i, ret;
memset(plist, 0, sizeof(PartList));
// Get partition entries
plist->num = MAX_PARTITIONS_EX;
ret = Partition_GetEntriesEx(plist->pentry, &plist->sector_size, &plist->num);
if (ret < 0) {
return -1;
}
char buf[plist->sector_size];
// scan partitions for filesystem type
for (i = 0; i < plist->num; i++) {
pinfo = &plist->pinfo[i];
entry = &plist->pentry[i];
if (!entry->size) continue;
if (!part_type_data(entry->type)) continue;
if (!USBStorage_ReadSectors(entry->sector, 1, buf)) continue;
pinfo->fs_type = get_fs_type(buf);
if (pinfo->fs_type == FS_TYPE_WBFS) {
plist->wbfs_n++;
pinfo->wbfs_i = plist->wbfs_n;
} else if (is_type_fat(pinfo->fs_type)) {
plist->fat_n++;
pinfo->fat_i = plist->fat_n;
}
}
return 0;
}

View File

@ -27,10 +27,36 @@ extern "C" {
} ATTRIBUTE_PACKED partitionEntry;
/* Constants */
#define MAX_PARTITIONS 4
#define MAX_PARTITIONS 4
#define MAX_PARTITIONS_EX 10
#define FS_TYPE_UNK 0
#define FS_TYPE_FAT16 1
#define FS_TYPE_FAT32 2
#define FS_TYPE_NTFS 3
#define FS_TYPE_WBFS 4
typedef struct
{
int fs_type;
int wbfs_i; // seq wbfs part index
int fat_i; // seq fat part index
} PartInfo;
typedef struct
{
int num;
u32 sector_size;
partitionEntry pentry[MAX_PARTITIONS_EX];
int wbfs_n;
int fat_n;
PartInfo pinfo[MAX_PARTITIONS_EX];
} PartList;
/* Prototypes */
s32 Partition_GetEntries(partitionEntry *, u32 *);
s32 Partition_GetEntriesEx(partitionEntry *, u32 *, int *);
s32 Partition_GetList(PartList *plist);
#ifdef __cplusplus
}

313
source/usbloader/splits.c Normal file
View File

@ -0,0 +1,313 @@
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "splits.h"
#define off64_t off_t
#define FMT_llu "%llu"
#define FMT_lld "%lld"
#define split_error(x) do { /* gprintf("\nsplit error: %s\n\n",x); */ } while(0)
// 1 sector less than 4gb
//u64 OPT_split_size = (u64)4LL * 1024 * 1024 * 1024 - 512;
// 1 sector less than 2gb
u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 512;
//split_info_t split;
void split_get_fname(split_info_t *s, int idx, char *fname)
{
strcpy(fname, s->fname);
if (idx == 0 && s->create_mode) {
strcat(fname, ".tmp");
} else if (idx > 0) {
char *c = fname + strlen(fname) - 1;
*c = '0' + idx;
}
}
int split_open_file(split_info_t *s, int idx)
{
int fd = s->fd[idx];
if (fd>=0) return fd;
char fname[1024];
split_get_fname(s, idx, fname);
//char *mode = s->create_mode ? "wb+" : "rb+";
int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR ;
//printf("SPLIT OPEN %s %s %d\n", fname, mode, idx); //Wpad_WaitButtons();
//f = fopen(fname, mode);
fd = open(fname, mode);
if (fd<0) return -1;
if (idx > 0 && s->create_mode) {
printf("%s Split: %d %s \n",
s->create_mode ? "Create" : "Read",
idx, fname);
}
s->fd[idx] = fd;
return fd;
}
// faster as it uses larger chunks than ftruncate internally
int write_zero(int fd, off_t size)
{
int buf[0x4000]; //64kb
int chunk;
int ret;
memset(buf, 0, sizeof(buf));
while (size) {
chunk = size;
if (chunk > sizeof(buf)) chunk = sizeof(buf);
ret = write(fd, buf, chunk);
//printf("WZ %d %d / %lld \n", ret, chunk, size);
size -= chunk;
if (ret < 0) return ret;
}
return 0;
}
int split_fill(split_info_t *s, int idx, u64 size)
{
int fd = split_open_file(s, idx);
off64_t fsize = lseek(fd, 0, SEEK_END);
if (fsize < size) {
//printf("TRUNC %d "FMT_lld"\n", idx, size); Wpad_WaitButtons();
//ftruncate(fd, size);
write_zero(fd, size - fsize);
return 1;
}
return 0;
}
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill)
{
int fd;
if (lba >= s->total_sec) {
fprintf(stderr, "SPLIT: invalid sector %u / %u\n", lba, (u32)s->total_sec);
return -1;
}
int idx;
idx = lba / s->split_sec;
if (idx >= s->max_split) {
fprintf(stderr, "SPLIT: invalid split %d / %d\n", idx, s->max_split - 1);
return -1;
}
fd = s->fd[idx];
if (fd<0) {
// opening new, make sure all previous are full
int i;
for (i=0; i<idx; i++) {
if (split_fill(s, i, s->split_size)) {
printf("FILL %d\n", i);
}
}
fd = split_open_file(s, idx);
}
if (fd<0) {
fprintf(stderr, "SPLIT %d: no file\n", idx);
return -1;
}
u32 sec = lba % s->split_sec; // inside file
off64_t off = (off64_t)sec * 512;
// num sectors till end of file
u32 to_end = s->split_sec - sec;
if (*sec_count > to_end) *sec_count = to_end;
if (s->create_mode) {
if (fill) {
// extend, so that read will be succesfull
split_fill(s, idx, off + 512 * (*sec_count));
} else {
// fill up so that write continues from end of file
// shouldn't be necessary, but libfat looks buggy
// and this is faster
split_fill(s, idx, off);
}
}
lseek(fd, off, SEEK_SET);
return fd;
}
int split_read_sector(void *_fp,u32 lba,u32 count,void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off *= 512ULL;
int i;
u32 chunk;
size_t ret;
//fprintf(stderr,"READ %d %d\n", lba, count);
for (i=0; i<(int)count; i+=chunk) {
chunk = count - i;
fd = split_get_file(s, lba+i, &chunk, 1);
if (fd<0) {
fprintf(stderr,"\n\n"FMT_lld" %d %p\n",off,count,_fp);
split_error("error seeking in disc partition");
return 1;
}
//ret = fread(buf+i*512, 512ULL, chunk, f);
ret = read(fd, buf+i*512, chunk * 512);
if (ret != chunk * 512) {
fprintf(stderr, "error reading %u %u [%u] %u = %u\n",
lba, count, i, chunk, ret);
split_error("error reading disc");
return 1;
}
}
return 0;
}
int split_write_sector(void *_fp,u32 lba,u32 count,void*buf)
{
split_info_t *s = _fp;
int fd;
u64 off = lba;
off*=512ULL;
int i;
u32 chunk;
size_t ret;
//printf("WRITE %d %d %p \n", lba, count, buf);
for (i=0; i<(int)count; i+=chunk) {
chunk = count - i;
fd = split_get_file(s, lba+i, &chunk, 0);
//if (chunk != count)
// fprintf(stderr, "WRITE CHUNK %d %d/%d\n", lba+i, chunk, count);
if (fd<0 || !chunk) {
fprintf(stderr,"\n\n"FMT_lld" %d %p\n",off,count,_fp);
split_error("error seeking in disc partition");
return 1;
}
//if (fwrite(buf+i*512, 512ULL, chunk, f) != chunk) {
//printf("write %d %p %d \n", fd, buf+i*512, chunk * 512);
ret = write(fd, buf+i*512, chunk * 512);
//printf("write ret = %d \n", ret);
if (ret != chunk * 512) {
split_error("error writing disc");
return 1;
}
}
return 0;
}
void split_init(split_info_t *s, char *fname)
{
int i;
char *p;
//fprintf(stderr, "SPLIT_INIT %s\n", fname);
memset(s, 0, sizeof(*s));
for (i=0; i<MAX_SPLIT; i++) {
s->fd[i] = -1;
}
strcpy(s->fname, fname);
s->max_split = 1;
p = strrchr(fname, '.');
if (p && (strcasecmp(p, ".wbfs") == 0)) {
s->max_split = MAX_SPLIT;
}
}
void split_set_size(split_info_t *s, u64 split_size, u64 total_size)
{
s->total_size = total_size;
s->split_size = split_size;
s->total_sec = total_size / 512;
s->split_sec = split_size / 512;
}
void split_close(split_info_t *s)
{
int i;
char fname[1024];
char tmpname[1024];
for (i=0; i<s->max_split; i++) {
if (s->fd[i] >= 0) {
close(s->fd[i]);
}
}
if (s->create_mode) {
split_get_fname(s, -1, fname);
split_get_fname(s, 0, tmpname);
rename(tmpname, fname);
}
memset(s, 0, sizeof(*s));
}
int split_create(split_info_t *s, char *fname,
u64 split_size, u64 total_size, bool overwrite)
{
int i;
int fd;
char sname[1024];
int error = 0;
split_init(s, fname);
s->create_mode = 1;
// check if any file already exists
for (i=-1; i<s->max_split; i++) {
split_get_fname(s, i, sname);
if (overwrite) {
remove(sname);
} else {
fd = open(sname, O_RDONLY);
if (fd >= 0) {
fprintf(stderr, "Error: file already exists: %s\n", sname);
close(fd);
error = 1;
}
}
}
if (error) {
split_init(s, "");
return -1;
}
split_set_size(s, split_size, total_size);
return 0;
}
int split_open(split_info_t *s, char *fname)
{
int i;
u64 size = 0;
u64 total_size = 0;
u64 split_size = 0;
int fd;
split_init(s, fname);
for (i=0; i<s->max_split; i++) {
fd = split_open_file(s, i);
if (fd<0) {
if (i==0) goto err;
break;
}
// check previous size - all splits except last must be same size
if (i > 0 && size != split_size) {
fprintf(stderr, "split %d: invalid size "FMT_lld"", i, size);
goto err;
}
// get size
//fseeko(f, 0, SEEK_END);
//size = ftello(f);
size = lseek(fd, 0, SEEK_END);
// check sector alignment
if (size % 512) {
fprintf(stderr, "split %d: size ("FMT_lld") not sector (512) aligned!",
i, size);
}
// first sets split size
if (i==0) {
split_size = size;
}
total_size += size;
}
split_set_size(s, split_size, total_size);
return 0;
err:
split_close(s);
return -1;
}

35
source/usbloader/splits.h Normal file
View File

@ -0,0 +1,35 @@
#define MAX_SPLIT 10
typedef struct split_info
{
char fname[1024];
//FILE *f[MAX_SPLIT];
int fd[MAX_SPLIT];
//u64 fsize[MAX_SPLIT];
u32 split_sec;
u32 total_sec;
u64 split_size;
u64 total_size;
int create_mode;
int max_split;
} split_info_t;
// 1 sector less than 4gb
extern u64 OPT_split_size;
void split_get_fname(split_info_t *s, int idx, char *fname);
//FILE *split_open_file(split_info_t *s, int idx);
//FILE *split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_open_file(split_info_t *s, int idx);
int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill);
int split_fill(split_info_t *s, int idx, u64 size);
int split_read_sector(void *_fp,u32 lba,u32 count,void*buf);
int split_write_sector(void *_fp,u32 lba,u32 count,void*buf);
void split_init(split_info_t *s, char *fname);
void split_set_size(split_info_t *s, u64 split_size, u64 total_size);
void split_close(split_info_t *s);
int split_open(split_info_t *s, char *fname);
int split_create(split_info_t *s, char *fname,
u64 split_size, u64 total_size, bool overwrite);

View File

@ -1,6 +1,10 @@
#ifndef _UTILS_H_
#define _UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Constants */
#define KB_SIZE 1024.0
#define MB_SIZE 1048576.0
@ -12,4 +16,8 @@
/* Prototypes */
u32 swap32(u32);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -10,14 +10,25 @@
#include "video.h"
#include "wdvd.h"
#include "wbfs.h"
#include "wbfs_fat.h"
#include "fatmounter.h"
#include "partition.h"
#include "libwbfs/libwbfs.h"
/* Constants */
#define MAX_NB_SECTORS 32
/* WBFS device */
s32 wbfsDev = WBFS_MIN_DEVICE;
// partition
int wbfs_part_fat = 0;
u32 wbfs_part_idx = 0;
u32 wbfs_part_lba = 0;
/* WBFS HDD */
static wbfs_t *hdd = NULL;
wbfs_t *hdd = NULL;
/* WBFS callbacks */
static rw_sector_callback_t readCallback = NULL;
@ -26,11 +37,39 @@ static s32 done = -1, total = -1;
/* Variables */
static u32 nb_sectors, sector_size;
static void WBFS_Spinner(s32 x, s32 max) {
void WBFS_Spinner(s32 x, s32 max) {
done = x;
total = max;
}
wbfs_disc_t* WBFS_OpenDisc(u8 *discid)
{
if (wbfs_part_fat) return WBFS_FAT_OpenDisc(discid);
/* No device open */
if (!hdd)
return NULL;
/* Open disc */
return wbfs_open_disc(hdd, discid);
}
void WBFS_CloseDisc(wbfs_disc_t *disc)
{
if (wbfs_part_fat) {
WBFS_FAT_CloseDisc(disc);
return;
}
/* No device open */
if (!hdd || !disc)
return;
/* Close disc */
wbfs_close_disc(disc);
}
void GetProgressValue(s32 * d, s32 * m) {
*d = done;
*m = total;
@ -226,82 +265,6 @@ s32 WBFS_Init(u32 device) {
return 0;
}
//s32 WBFS_Init(void)
//{
// s32 ret;
//
// /* Initialize USB storage */
// ret = USBStorage_Init();
// if (ret < 0)
// return ret;
//
// /* Get USB capacity */
// nb_sectors = USBStorage_GetCapacity(&sector_size);
// if (!nb_sectors)
// return -1;
//
// return 0;
//}
/*
s32 WBFS_Init(u32 device, u32 timeout)
{
u32 cnt;
s32 ret;
// Wrong timeout
if (!timeout)
return -1;
// Try to mount device
for (cnt = 0; cnt < timeout; cnt++) {
switch (device) {
case WBFS_DEVICE_USB: {
// Initialize USB storage
ret = USBStorage_Init();
if (ret >= 0) {
// Setup callbacks
readCallback = __WBFS_ReadUSB;
writeCallback = __WBFS_WriteUSB;
// Device info
nb_sectors = USBStorage_GetCapacity(&sector_size);
goto out;
}
}
case WBFS_DEVICE_SDHC: {
// Initialize SDHC
ret = SDHC_Init();
if (ret) {
// Setup callbacks
readCallback = __WBFS_ReadSDHC;
writeCallback = __WBFS_WriteSDHC;
// Device info
nb_sectors = 0;
sector_size = SDHC_SECTOR_SIZE;
goto out;
} else
ret = -1;
}
default:
return -1;
}
// Sleep 1 second
sleep(1);
}
out:
return ret;
}
*/
s32 WBFS_Open(void) {
/* Close hard disk */
@ -309,6 +272,7 @@ s32 WBFS_Open(void) {
wbfs_close(hdd);
/* Open hard disk */
wbfs_part_fat = wbfs_part_idx = wbfs_part_lba = 0;
hdd = wbfs_open_hd(readCallback, writeCallback, NULL, sector_size, nb_sectors, 0);
if (!hdd)
return -1;
@ -316,19 +280,134 @@ s32 WBFS_Open(void) {
// Save the new sector size, so it will be used in read and write calls
sector_size = 1 << hdd->head->hd_sec_sz_s;
wbfs_part_idx = 1;
return 0;
}
s32 WBFS_Close(void)
s32 WBFS_OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition)
{
// close
WBFS_Close();
if (part_fat) {
if (wbfsDev != WBFS_DEVICE_USB) return -1;
if (part_lba == fat_usb_sec) {
strcpy(wbfs_fat_drive, "USB:");
} else {
if (WBFSDevice_Init(part_lba)) return -1;
strcpy(wbfs_fat_drive, "WBFS:");
}
} else {
if (WBFS_OpenLBA(part_lba, part_size)) return -3;
}
// success
wbfs_part_fat = part_fat;
wbfs_part_idx = part_idx;
wbfs_part_lba = part_lba;
sprintf(partition, "%s%d", wbfs_part_fat ? "FAT" : "WBFS", wbfs_part_idx);
return 0;
}
s32 WBFS_OpenNamed(char *partition)
{
int i;
u32 part_idx = 0;
u32 part_fat = 0;
u32 part_lba = 0;
s32 ret = 0;
PartList plist;
// close
WBFS_Close();
// parse partition option
if (strncasecmp(partition, "WBFS", 4) == 0) {
i = atoi(partition+4);
if (i < 1 || i > 4) goto err;
part_idx = i;
} else if (strncasecmp(partition, "FAT", 3) == 0) {
if (wbfsDev != WBFS_DEVICE_USB) goto err;
i = atoi(partition+3);
if (i < 1 || i > 9) goto err;
part_idx = i;
part_fat = 1;
} else {
goto err;
}
// Get partition entries
ret = Partition_GetList(&plist);
if (ret || plist.num == 0) return -1;
if (part_fat) {
if (part_idx > plist.fat_n) goto err;
for (i=0; i<plist.num; i++) {
if (plist.pinfo[i].fat_i == part_idx) break;
}
} else {
if (part_idx > plist.wbfs_n) goto err;
for (i=0; i<plist.num; i++) {
if (plist.pinfo[i].wbfs_i == part_idx) break;
}
}
if (i >= plist.num) goto err;
// set partition lba sector
part_lba = plist.pentry[i].sector;
if (WBFS_OpenPart(part_fat, part_idx, part_lba, plist.pentry[i].size, partition)) {
goto err;
}
// success
return 0;
err:
return -1;
}
s32 WBFS_OpenLBA(u32 lba, u32 size)
{
wbfs_t *part = NULL;
/* Open partition */
part = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 0);
if (!part) return -1;
/* Close current hard disk */
if (hdd) wbfs_close(hdd);
hdd = part;
return 0;
}
bool WBFS_Close(void)
{
/* Close hard disk */
if (hdd)
if (hdd) {
wbfs_close(hdd);
hdd = NULL;
}
WBFSDevice_deInit();
wbfs_part_fat = 0;
wbfs_part_idx = 0;
wbfs_part_lba = 0;
wbfs_fat_drive[0] = '\0';
return 0;
}
bool WBFS_Mounted()
{
return (hdd != NULL);
}
bool WBFS_Selected()
{
if (wbfs_part_fat && wbfs_part_lba && *wbfs_fat_drive) return true;
return WBFS_Mounted();
}
s32 WBFS_Format(u32 lba, u32 size) {
wbfs_t *partition = NULL;
@ -344,6 +423,8 @@ s32 WBFS_Format(u32 lba, u32 size) {
}
s32 WBFS_GetCount(u32 *count) {
if (wbfs_part_fat) return WBFS_FAT_GetCount(count);
/* No device open */
if (!hdd)
return -1;
@ -355,6 +436,8 @@ s32 WBFS_GetCount(u32 *count) {
}
s32 WBFS_GetHeaders(void *outbuf, u32 cnt, u32 len) {
if (wbfs_part_fat) return WBFS_FAT_GetHeaders(outbuf, cnt, len);
u32 idx, size;
s32 ret;
@ -378,10 +461,10 @@ s32 WBFS_CheckGame(u8 *discid) {
wbfs_disc_t *disc = NULL;
/* Try to open game disc */
disc = wbfs_open_disc(hdd, discid);
disc = WBFS_OpenDisc(discid);
if (disc) {
/* Close disc */
wbfs_close_disc(disc);
WBFS_CloseDisc(disc);
return 1;
}
@ -390,6 +473,8 @@ s32 WBFS_CheckGame(u8 *discid) {
}
s32 WBFS_AddGame(void) {
if (wbfs_part_fat) return WBFS_FAT_AddGame();
s32 ret;
/* No device open */
@ -405,6 +490,8 @@ s32 WBFS_AddGame(void) {
}
s32 WBFS_RemoveGame(u8 *discid) {
if (wbfs_part_fat) return WBFS_FAT_RemoveGame(discid);
s32 ret;
/* No device open */
@ -424,28 +511,26 @@ s32 WBFS_GameSize(u8 *discid, f32 *size) {
u32 sectors;
/* No device open */
if (!hdd)
return -1;
/* Open disc */
disc = wbfs_open_disc(hdd, discid);
disc = WBFS_OpenDisc(discid);
if (!disc)
return -2;
/* Get game size in sectors */
sectors = wbfs_sector_used(hdd, disc->header);
/* Close disc */
wbfs_close_disc(disc);
sectors = wbfs_sector_used(disc->p, disc->header);
/* Copy value */
*size = (hdd->wbfs_sec_sz / GB_SIZE) * sectors;
*size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors;
/* Close disc */
WBFS_CloseDisc(disc);
return 0;
}
s32 WBFS_DiskSpace(f32 *used, f32 *free) {
if (wbfs_part_fat) return WBFS_FAT_DiskSpace(used, free);
f32 ssize;
u32 cnt;
@ -467,6 +552,8 @@ s32 WBFS_DiskSpace(f32 *used, f32 *free) {
}
s32 WBFS_RenameGame(u8 *discid, const void *newname) {
if (wbfs_part_fat) return -1;
s32 ret;
/* No USB device open */
@ -480,6 +567,8 @@ s32 WBFS_RenameGame(u8 *discid, const void *newname) {
}
s32 WBFS_ReIDGame(u8 *discid, const void *newID) {
if (wbfs_part_fat) return -1;
s32 ret;
/* No USB device open */
@ -493,7 +582,11 @@ s32 WBFS_ReIDGame(u8 *discid, const void *newID) {
}
f32 WBFS_EstimeGameSize(void) {
if (wbfs_part_fat) {
u64 comp;
WBFS_FAT_DVD_Size(&comp, NULL);
return comp;
}
return wbfs_estimate_disc(hdd, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION);
}

View File

@ -13,14 +13,19 @@ extern "C" {
};
/* Macros */
#define WBFS_MIN_DEVICE 1
#define WBFS_MAX_DEVICE 2
#define WBFS_MIN_DEVICE 1
#define WBFS_MAX_DEVICE 2
extern s32 wbfsDev;
extern int wbfs_part_fat;
extern u32 wbfs_part_idx;
extern u32 wbfs_part_lba;
extern char wbfs_fat_drive[16];
/* Prototypes */
void GetProgressValue(s32 * d, s32 * m);
s32 WBFS_Init(u32);
s32 WBFS_Open(void);
s32 WBFS_Close(void);
s32 WBFS_Format(u32, u32);
s32 WBFS_GetCount(u32 *);
s32 WBFS_GetHeaders(void *, u32, u32);
@ -38,6 +43,15 @@ extern "C" {
s32 __WBFS_ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WBFS_WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 WBFS_OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition);
s32 WBFS_OpenNamed(char *partition);
s32 WBFS_OpenLBA(u32 lba, u32 size);
wbfs_disc_t* WBFS_OpenDisc(u8 *discid);
void WBFS_CloseDisc(wbfs_disc_t *disc);
bool WBFS_Close();
bool WBFS_Mounted();
bool WBFS_Selected();
#ifdef __cplusplus
}

339
source/usbloader/wbfs_fat.c Normal file
View File

@ -0,0 +1,339 @@
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <ogcsys.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/statvfs.h>
#include <ctype.h>
#include "libwbfs/libwbfs.h"
#include "sdhc.h"
#include "usbstorage.h"
#include "utils.h"
#include "video.h"
#include "wbfs.h"
#include "wdvd.h"
#include "splits.h"
#include "fat.h"
#include "partition.h"
#include "wpad.h"
#include "wbfs_fat.h"
#include "disc.h"
#include "settings/cfg.h"
// WBFS FAT by oggzee
#define D_S(A) A, sizeof(A)
char wbfs_fat_drive[16];
char wbfs_fat_dir[16] = "/wbfs";
int wbfs_fat_vfs_have = 0;
int wbfs_fat_vfs_lba = 0;
struct statvfs wbfs_fat_vfs;
split_info_t split;
static u32 fat_sector_size = 512;
void WBFS_Spinner(s32 x, s32 max);
s32 __WBFS_ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
s32 _WBFS_FAT_GetHeadersCount(void *outbuf, u32 *count, u32 len)
{
DIR *dir;
struct dirent *dent;
char *p;
int ret, cnt = 0;
char path[100];
wbfs_t *part = NULL;
u32 size;
u8 *ptr;
struct discHdr tmpHdr;
int hdrsize;
struct stat st;
//dbg_time1();
strcpy(path, wbfs_fat_drive);
strcat(path, wbfs_fat_dir);
dir = opendir(path);
if (!dir) {
*count = 0;
return 0;
}
while ((dent = readdir(dir)) != NULL) {
if (outbuf && cnt >= *count) break;
if ((char)dent->d_name[0] == '.') continue;
p = strrchr(dent->d_name, '.');
if (!p) continue;
if (strcasecmp(p, ".wbfs") != 0) continue;
if (strlen(dent->d_name) != 11) continue; // GAMEID.wbfs
u8 id[8];
memcpy(id, dent->d_name, 6);
id[6] = 0;
strcpy(path, wbfs_fat_drive);
strcat(path, wbfs_fat_dir);
strcat(path, "/");
strcat(path, dent->d_name);
stat(path, &st);
// size must be at least 1MB to be considered a valid wbfs file
if (st.st_size < 1024*1024) continue;
if (!outbuf) {
// just counting
cnt++;
continue;
}
ptr = ((u8 *)outbuf) + (cnt * len);
hdrsize = len;
char *title = cfg_get_title(id);
if (title) {
memset(&tmpHdr, 0, sizeof(tmpHdr));
memcpy(tmpHdr.id, id, 6);
strncpy(tmpHdr.title, title, sizeof(tmpHdr.title));
tmpHdr.magic = 0x5D1C9EA3;
memcpy(ptr, &tmpHdr, hdrsize);
cnt++;
continue;
}
// no title found, read it from wbfs file directly
FILE *fp = fopen(path, "rb");
if (fp != NULL) {
fseek(fp, 512, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
if (tmpHdr.magic == 0x5D1C9EA3 && (memcmp(tmpHdr.id, id, 6) == 0)) {
memcpy(ptr, &tmpHdr, hdrsize);
cnt++;
continue;
}
}
// no title found, read it from wbfs file
// but this is a little bit slower
// open 'partition' file
part = WBFS_FAT_OpenPart(id);
if (!part) {
continue;
}
/* Get header */
ret = wbfs_get_disc_info(part, 0, ptr, hdrsize, &size);
if (ret == 0) cnt++;
WBFS_FAT_ClosePart(part);
}
*count = cnt;
closedir(dir);
//dbg_time2("\nFAT HDRS");
//Wpad_WaitButtons();
return 0;
}
s32 WBFS_FAT_GetCount(u32 *count)
{
*count = 0;
_WBFS_FAT_GetHeadersCount(NULL, count, 0);
return 0;
}
s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len)
{
_WBFS_FAT_GetHeadersCount(outbuf, &cnt, len);
return 0;
}
wbfs_disc_t* WBFS_FAT_OpenDisc(u8 *discid)
{
wbfs_t *part = WBFS_FAT_OpenPart(discid);
if (!part) return NULL;
return wbfs_open_disc(part, discid);
}
void WBFS_FAT_CloseDisc(wbfs_disc_t* disc)
{
if (!disc) return;
wbfs_t *part = disc->p;
wbfs_close_disc(disc);
WBFS_FAT_ClosePart(part);
return;
}
s32 WBFS_FAT_DiskSpace(f32 *used, f32 *free)
{
f32 size;
int ret;
*used = 0;
*free = 0;
// statvfs is slow, so cache values
if (!wbfs_fat_vfs_have || wbfs_fat_vfs_lba != wbfs_part_lba) {
ret = statvfs(wbfs_fat_drive, &wbfs_fat_vfs);
if (ret) return 0;
wbfs_fat_vfs_have = 1;
wbfs_fat_vfs_lba = wbfs_part_lba;
}
/* FS size in GB */
size = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_blocks / GB_SIZE;
*free = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_bfree / GB_SIZE;
*used = size - *free;
return 0;
}
static int nop_read_sector(void *_fp,u32 lba,u32 count,void*buf)
{
return 0;
}
static int nop_write_sector(void *_fp,u32 lba,u32 count,void*buf)
{
return 0;
}
void WBFS_FAT_fname(u8 *id, char *fname, int len)
{
snprintf(fname, len, "%s%s/%.6s.wbfs", wbfs_fat_drive, wbfs_fat_dir, id);
}
wbfs_t* WBFS_FAT_OpenPart(u8 *id)
{
char fname[100];
wbfs_t *part = NULL;
int ret;
// wbfs 'partition' file
WBFS_FAT_fname(id, fname, sizeof(fname));
ret = split_open(&split, fname);
if (ret) return NULL;
part = wbfs_open_partition(
split_read_sector,
nop_write_sector, //readonly //split_write_sector,
&split, fat_sector_size, split.total_sec, 0, 0);
if (!part) {
split_close(&split);
}
return part;
}
wbfs_t* WBFS_FAT_CreatePart(u8 *id)
{
char fname[100];
wbfs_t *part = NULL;
u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / 512;
int ret;
snprintf(D_S(fname), "%s%s", wbfs_fat_drive, wbfs_fat_dir);
mkdir(fname, 0777);
WBFS_FAT_fname(id, fname, sizeof(fname));
ret = split_create(&split, fname, OPT_split_size, size, true);
if (ret) return NULL;
// force create first file
u32 scnt = 0;
int fd = split_get_file(&split, 0, &scnt, 0);
if (fd<0) {
split_close(&split);
return NULL;
}
part = wbfs_open_partition(
split_read_sector,
split_write_sector,
&split, fat_sector_size, n_sector, 0, 1);
if (!part) {
split_close(&split);
}
return part;
}
void WBFS_FAT_ClosePart(wbfs_t* part)
{
if (!part) return;
split_info_t *s = (split_info_t*)part->callback_data;
wbfs_close(part);
if (s) split_close(s);
}
s32 WBFS_FAT_RemoveGame(u8 *discid)
{
char fname[100];
// wbfs 'partition' file
WBFS_FAT_fname(discid, fname, sizeof(fname));
split_create(&split, fname, 0, 0, true);
split_close(&split);
// Reset FAT stats
wbfs_fat_vfs_have = 0;
return 0;
}
s32 WBFS_FAT_AddGame(void)
{
static struct discHdr header ATTRIBUTE_ALIGN(32);
s32 ret;
wbfs_t *part = NULL;
//write_test(); return -1;
// read ID from DVD
Disc_ReadHeader(&header);
// create wbfs 'partition' file
part = WBFS_FAT_CreatePart(header.id);
if (!part) return -1;
/* Add game to device */
extern wbfs_t *hdd;
wbfs_t *old_hdd = hdd;
hdd = part; // used by spinner
ret = wbfs_add_disc(part, __WBFS_ReadDVD, NULL, WBFS_Spinner, ONLY_GAME_PARTITION, 0);
hdd = old_hdd;
wbfs_trim(part);
WBFS_FAT_ClosePart(part);
// Reset FAT stats
wbfs_fat_vfs_have = 0;
if (ret < 0) return ret;
return 0;
}
s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size)
{
s32 ret;
u32 comp_sec = 0, last_sec = 0;
wbfs_t *part = NULL;
u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / fat_sector_size;
u32 wii_sec_sz;
// init a temporary dummy part
// as a placeholder for wbfs_size_disc
part = wbfs_open_partition(
nop_read_sector, nop_write_sector,
NULL, fat_sector_size, n_sector, 0, 1);
if (!part) return -1;
wii_sec_sz = part->wii_sec_sz;
/* Add game to device */
ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION, &comp_sec, &last_sec);
wbfs_close(part);
if (ret < 0)
return ret;
if (comp_size != NULL) *comp_size = (u64)wii_sec_sz * comp_sec;
if (real_size != NULL) *real_size = (u64)wii_sec_sz * last_sec;
return 0;
}

View File

@ -0,0 +1,15 @@
#ifndef _WBFS_FAT_H
#define _WBFS_FAT_H
wbfs_t* WBFS_FAT_OpenPart(u8 *id);
void WBFS_FAT_ClosePart(wbfs_t* part);
s32 WBFS_FAT_GetCount(u32 *count);
s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len);
wbfs_disc_t* WBFS_FAT_OpenDisc(u8 *discid);
void WBFS_FAT_CloseDisc(wbfs_disc_t* disc);
s32 WBFS_FAT_DiskSpace(f32 *used, f32 *free);
s32 WBFS_FAT_RemoveGame(u8 *discid);
s32 WBFS_FAT_AddGame(void);
s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size);
#endif

View File

@ -306,7 +306,7 @@ s32 WDVD_DisableReset(u8 val) {
}
/** Hermes **/
s32 WDVD_SetUSBMode(const u8 *id) {
s32 WDVD_SetUSBMode(const u8 *id, s32 partition) {
s32 ret;
memset(inbuf, 0, sizeof(inbuf));
@ -315,10 +315,12 @@ s32 WDVD_SetUSBMode(const u8 *id) {
inbuf[0] = IOCTL_DI_SETUSBMODE << 24;
inbuf[1] = (id) ? 1 : 0;
/* Copy ID */
if (id) {
memcpy(&inbuf[2], id, 6);
if (IOS_GetVersion() != 249) {
inbuf[5] = partition;
}
}
ret = IOS_Ioctl(di_fd, IOCTL_DI_SETUSBMODE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));

View File

@ -22,7 +22,7 @@ extern "C" {
s32 WDVD_WaitForDisc(void);
s32 WDVD_GetCoverStatus(u32 *);
s32 WDVD_DisableReset(u8);
s32 WDVD_SetUSBMode(const u8 *);
s32 WDVD_SetUSBMode(const u8 *, s32 partition);
#ifdef __cplusplus
}

View File

@ -8,8 +8,8 @@ Copyright (C) 2008 tona and/or waninkoko
#include <ogcsys.h>
#include <string.h>
#include <stdio.h>
#include <fat.h>
#include <malloc.h>
#include <fat.h>
// Turn upper and lower into a full title ID
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))