mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-22 09:51:55 +01:00
* 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:
parent
ef43c3d0a2
commit
a09abe355f
10
Makefile
10
Makefile
@ -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
BIN
data/ehcmodule_fat.bin
Normal file
Binary file not shown.
2
gui.pnps
2
gui.pnps
@ -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>
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ class GuiGameCarousel : public GuiElement
|
||||
|
||||
int * gameIndex;
|
||||
GuiButton ** game;
|
||||
GuiTooltip ** titleTT;
|
||||
GuiImageAsync ** coverImg;
|
||||
|
||||
GuiText * gamename;
|
||||
|
@ -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();
|
||||
@ -209,10 +209,11 @@ main(int argc, char *argv[]) {
|
||||
CFG_Load();
|
||||
gprintf("\n\tbootDevice = %s",bootDevice);
|
||||
|
||||
/* Load Custom IOS */
|
||||
/* Load Custom IOS */
|
||||
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);
|
||||
|
2007
source/menu.cpp
2007
source/menu.cpp
File diff suppressed because it is too large
Load Diff
151
source/menu/menu_check.cpp
Normal file
151
source/menu/menu_check.cpp
Normal 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;
|
||||
}
|
1508
source/menu/menu_disclist.cpp
Normal file
1508
source/menu/menu_disclist.cpp
Normal file
File diff suppressed because it is too large
Load Diff
188
source/menu/menu_format.cpp
Normal file
188
source/menu/menu_format.cpp
Normal 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;
|
||||
}
|
||||
|
154
source/menu/menu_install.cpp
Normal file
154
source/menu/menu_install.cpp
Normal 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
24
source/menu/menus.h
Normal 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
@ -1,3 +0,0 @@
|
||||
#define size_ehcmodule 32432
|
||||
|
||||
extern unsigned char ehcmodule[32432];
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -27,6 +27,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MAX_GCT_SIZE 2056
|
||||
|
||||
//u32 do_fst(u32 fstlocation);
|
||||
u32 do_sd_code(char *filename);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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,10 +980,31 @@ 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)
|
||||
{
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -393,6 +393,7 @@ extern "C" {
|
||||
u8 gameDisplay;
|
||||
u8 patchcountrystrings;
|
||||
u8 screensaver;
|
||||
u8 partition;
|
||||
short godmode;
|
||||
char covers_path[100];
|
||||
char covers2d_path[100];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -216,7 +216,7 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u
|
||||
void *offset;
|
||||
u32 pos;
|
||||
u32 len;
|
||||
|
||||
|
||||
while (load_dol_image_modified(&offset, &pos, &len)) {
|
||||
if (len != 0) {
|
||||
ret = WDVD_Read(offset, len, (doloffset<<2) + pos);
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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(§or_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;
|
||||
}
|
||||
|
@ -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
313
source/usbloader/splits.c
Normal 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
35
source/usbloader/splits.h
Normal 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);
|
||||
|
@ -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
|
||||
|
@ -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(§or_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(§or_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);
|
||||
|
||||
}
|
||||
|
@ -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
339
source/usbloader/wbfs_fat.c
Normal 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;
|
||||
}
|
||||
|
15
source/usbloader/wbfs_fat.h
Normal file
15
source/usbloader/wbfs_fat.h
Normal 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
|
@ -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));
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user