mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-23 10:21:55 +01:00
makes it possible to use a FAT-Partition on the USB WBFS-Disk
Boot-Strategy: - is "argv[0]" set, then the boot-device extracted from the argv. - if no meaningful boot device found, then looking for "boot.dol"/"boot.elf" in "apps/usbloader_gx/" first on "SD:/" and then on "USB:/". When found, than use this Device. Otherwise use the default "SD:" - Set all default-Paths on this Device - Set the Path for config-Folder, GXGlobal.cfg, GXGameSettings.cfg and GXGameFavorites.cfg on this Device (e.g. USB:/config and so on)
This commit is contained in:
parent
fb61660d22
commit
f5e6663784
@ -1216,7 +1216,8 @@ int GameWindowPrompt()
|
||||
favorite = game_num->favorite;
|
||||
count = game_num->count;//count+=1;
|
||||
}count+=1;
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
if (CFG_save_game_num(header->id))
|
||||
{
|
||||
//WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0);
|
||||
@ -1250,7 +1251,8 @@ int GameWindowPrompt()
|
||||
}
|
||||
|
||||
else if(btnFavorite.GetState() == STATE_CLICKED){//switch favorite
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
faveChoice = !faveChoice;
|
||||
btnFavoriteImg.SetImage(faveChoice ? &imgFavorite : &imgNotFavorite);
|
||||
extern u8 favorite;
|
||||
@ -2285,15 +2287,17 @@ ProgressUpdateWindow()
|
||||
if(file.data != NULL)
|
||||
{
|
||||
char revtxt[10];
|
||||
pfile = fopen("SD:/rev.txt", "w");
|
||||
char rev_txt[14];
|
||||
sprintf(rev_txt, "%s:/rev.txt", bootDevice);
|
||||
pfile = fopen(rev_txt, "w");
|
||||
fwrite(file.data,1,file.size,pfile);
|
||||
fclose(pfile);
|
||||
//has to be repeated or it isnt working (first file download bug)
|
||||
pfile = fopen("SD:/rev.txt", "w");
|
||||
pfile = fopen(rev_txt, "w");
|
||||
fwrite(file.data,1,file.size,pfile);
|
||||
fclose(pfile);
|
||||
//"w+" doesnt work, needs to be reopened as "r"
|
||||
pfile = fopen("SD:/rev.txt", "r");
|
||||
pfile = fopen(rev_txt, "r");
|
||||
int c = 0, i = 0;
|
||||
while(c != EOF || i < 10) {
|
||||
c = fgetc(pfile);
|
||||
@ -2307,7 +2311,7 @@ ProgressUpdateWindow()
|
||||
}
|
||||
fclose(pfile);
|
||||
revnumber = atoi(revtxt);
|
||||
remove("SD:/rev.txt");
|
||||
remove(rev_txt);
|
||||
free(file.data);
|
||||
}
|
||||
|
||||
|
@ -601,7 +601,8 @@ int MenuSettings()
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
if ( Settings.godmode == 1)
|
||||
{
|
||||
w.SetEffect(EFFECT_FADE, -20);
|
||||
@ -1101,7 +1102,8 @@ int MenuSettings()
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
if(isSdInserted())
|
||||
//if(isSdInserted())
|
||||
if(isInserted(bootDevice))
|
||||
{
|
||||
w.SetEffect(EFFECT_FADE, -20);
|
||||
while(w.GetEffect()>0) usleep(50);
|
||||
@ -1252,8 +1254,9 @@ int MenuSettings()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(Settings.covers_path, entered, sizeof(Settings.covers_path));
|
||||
WindowPrompt(LANGUAGE.CoverpathChanged,0,LANGUAGE.ok,0,0,0);
|
||||
if(!isSdInserted()) {
|
||||
WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0);
|
||||
// if(!isSdInserted()) {
|
||||
if(!isInserted(bootDevice)) {
|
||||
WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1277,7 +1280,8 @@ int MenuSettings()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(Settings.disc_path, entered, sizeof(Settings.disc_path));
|
||||
WindowPrompt(LANGUAGE.DiscpathChanged,0,LANGUAGE.ok,0,0,0);
|
||||
if(!isSdInserted()) {
|
||||
// if(!isSdInserted()) {
|
||||
if(!isInserted(bootDevice)) {
|
||||
WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0);
|
||||
}
|
||||
}
|
||||
@ -1302,7 +1306,8 @@ int MenuSettings()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(CFG.theme_path, entered, sizeof(CFG.theme_path));
|
||||
WindowPrompt(LANGUAGE.ThemepathChanged,0,LANGUAGE.ok,0,0,0);
|
||||
if(!isSdInserted()) {
|
||||
// if(!isSdInserted()) {
|
||||
if(!isInserted(bootDevice)) {
|
||||
WindowPrompt(LANGUAGE.NoSDcardinserted, LANGUAGE.InsertaSDCardtosave, LANGUAGE.ok, 0,0,0);
|
||||
} else {
|
||||
cfg_save_global();
|
||||
@ -1358,7 +1363,8 @@ int MenuSettings()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(Settings.titlestxt_path, entered, sizeof(Settings.titlestxt_path));
|
||||
WindowPrompt(LANGUAGE.TitlestxtpathChanged,0,LANGUAGE.ok,0,0,0);
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
CFG_Load();
|
||||
} else {
|
||||
@ -1422,7 +1428,8 @@ int MenuSettings()
|
||||
w.Remove(&MainButton2);
|
||||
w.Remove(&MainButton3);
|
||||
w.Remove(&MainButton4);
|
||||
if(isSdInserted() && Settings.godmode) {
|
||||
// if(isSdInserted() && Settings.godmode) {
|
||||
if(isInserted(bootDevice) && Settings.godmode) {
|
||||
w.Remove(&optionBrowser2);
|
||||
w.Remove(&backBtn);
|
||||
int ret = ProgressUpdateWindow();
|
||||
@ -1459,8 +1466,13 @@ int MenuSettings()
|
||||
if(Settings.godmode) {
|
||||
int choice = WindowPrompt(LANGUAGE.Areyousure, 0, LANGUAGE.Yes, LANGUAGE.Cancel, 0, 0);
|
||||
if(choice == 1) {
|
||||
if(isSdInserted())
|
||||
remove("SD:/config/GXGlobal.cfg");
|
||||
// if(isSdInserted())
|
||||
if(isInserted(bootDevice))
|
||||
{
|
||||
char GXGlobal_cfg[26];
|
||||
sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice);
|
||||
remove(GXGlobal_cfg);
|
||||
}
|
||||
lang_default();
|
||||
CFG_Load();
|
||||
menu = MENU_SETTINGS;
|
||||
@ -1507,7 +1519,8 @@ int MenuSettings()
|
||||
if(backBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
//Add the procedure call to save the global configuration
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
}
|
||||
menu = MENU_DISCLIST;
|
||||
@ -1825,7 +1838,8 @@ int GameSettings(struct discHdr * header)
|
||||
if(saveBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
if (CFG_save_game_opt(header->id))
|
||||
{
|
||||
WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0);
|
||||
|
@ -231,7 +231,8 @@ bool MenuOGG()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(Settings.oggload_path, entered, sizeof(Settings.oggload_path));
|
||||
WindowPrompt(LANGUAGE.Backgroundmusicpath,0,LANGUAGE.ok,0,0,0);
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
if(!strcmp("", Settings.oggload_path)) {
|
||||
sprintf(Settings.ogg_path, "notset");
|
||||
bgMusic->Play();
|
||||
@ -473,7 +474,8 @@ int MenuLanguageSelect()
|
||||
strncat (entered, "/", 1);
|
||||
strncpy(Settings.languagefiles_path, entered, sizeof(Settings.languagefiles_path));
|
||||
WindowPrompt(LANGUAGE.Languagepathchanged,0,LANGUAGE.ok,0,0,0);
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
returnhere = 1;
|
||||
break;
|
||||
@ -492,7 +494,8 @@ int MenuLanguageSelect()
|
||||
if(ret>=0) {
|
||||
choice = WindowPrompt(LANGUAGE.Doyouwanttochangelanguage, 0, LANGUAGE.Yes, LANGUAGE.Cancel,0,0);
|
||||
if(choice == 1) {
|
||||
if(isSdInserted()) {
|
||||
// if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
snprintf(Settings.language_path, sizeof(Settings.language_path), "%s%s", Settings.languagefiles_path, GetFileName(ret));
|
||||
cfg_save_global();
|
||||
if(!checkfile(Settings.language_path)) {
|
||||
|
73
source/cfg.c
73
source/cfg.c
@ -13,8 +13,9 @@
|
||||
struct SSettings Settings;
|
||||
|
||||
|
||||
char bootDevice[10] = "SD:";
|
||||
|
||||
char *cfg_path = "SD:/apps/usbloader/";
|
||||
//char *cfg_path = "SD:/apps/usbloader/";
|
||||
|
||||
char current_path[100];
|
||||
|
||||
@ -221,24 +222,24 @@ void CFG_Default(int widescreen) // -1 = non forced Mode
|
||||
CFG.widescreen = widescreen;
|
||||
|
||||
if (CFG.widescreen) {
|
||||
snprintf(CFG.theme_path, sizeof(CFG.theme_path), "SD:/wtheme/");
|
||||
snprintf(CFG.theme_path, sizeof(CFG.theme_path), "%s/wtheme/", bootDevice);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(CFG.theme_path, sizeof(CFG.theme_path), "SD:/theme/");
|
||||
snprintf(CFG.theme_path, sizeof(CFG.theme_path), "%s/theme/", bootDevice);
|
||||
}
|
||||
|
||||
if (widescreen == -1)
|
||||
{
|
||||
snprintf(Settings.covers_path, sizeof(Settings.covers_path), "SD:/images/"); //default image path
|
||||
snprintf(Settings.disc_path, sizeof(Settings.disc_path), "SD:/images/disc/");
|
||||
snprintf(Settings.titlestxt_path, sizeof(Settings.titlestxt_path), "SD:/config/");//default path for disc images
|
||||
snprintf(Settings.covers_path, sizeof(Settings.covers_path), "%s/images/", bootDevice); //default image path
|
||||
snprintf(Settings.disc_path, sizeof(Settings.disc_path), "%s/images/disc/", bootDevice);
|
||||
snprintf(Settings.titlestxt_path, sizeof(Settings.titlestxt_path), "%s/config/", bootDevice);//default path for disc images
|
||||
char * empty = "";
|
||||
snprintf(Settings.unlockCode, sizeof(Settings.unlockCode), empty); // default password
|
||||
snprintf(Settings.language_path, sizeof(Settings.language_path), "notset");
|
||||
snprintf(Settings.languagefiles_path, sizeof(Settings.languagefiles_path), "SD:/config/language/");
|
||||
snprintf(Settings.oggload_path, sizeof(Settings.oggload_path), "SD:/config/backgroundmusic/");
|
||||
snprintf(Settings.update_path, sizeof(Settings.update_path), "SD:/apps/usbloader_gx/");
|
||||
snprintf(Settings.languagefiles_path, sizeof(Settings.languagefiles_path), "%s/config/language/", bootDevice);
|
||||
snprintf(Settings.oggload_path, sizeof(Settings.oggload_path), "%s/config/backgroundmusic/", bootDevice);
|
||||
snprintf(Settings.update_path, sizeof(Settings.update_path), "%s/apps/usbloader_gx/", bootDevice);
|
||||
sprintf(Settings.ogg_path, "notset");
|
||||
|
||||
//all alignments are left top here
|
||||
@ -1148,14 +1149,17 @@ void cfg_set_game_num(struct Game_NUM *game, u8 *id)
|
||||
|
||||
bool cfg_save_global()// save global settings
|
||||
{
|
||||
char GXGlobal_cfg[26];
|
||||
sprintf(GXGlobal_cfg, "%s/config", bootDevice);
|
||||
struct stat st;
|
||||
if(stat("SD:/config/", &st) != 0) {
|
||||
mkdir("SD:/config", 0777);
|
||||
if(stat(GXGlobal_cfg, &st) != 0) {
|
||||
mkdir(GXGlobal_cfg, 0777);
|
||||
}
|
||||
FILE *f;
|
||||
f = fopen("SD:/config/GXGlobal.cfg", "w");
|
||||
sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice);
|
||||
f = fopen(GXGlobal_cfg, "w");
|
||||
if (!f) {
|
||||
printf("Error saving %s\n", "GXGlobal.cfg");
|
||||
printf("Error saving %s\n", GXGlobal_cfg);
|
||||
sleep(1);
|
||||
return false;
|
||||
}
|
||||
@ -1163,7 +1167,7 @@ bool cfg_save_global()// save global settings
|
||||
fprintf(f, "# Note: This file is automatically generated\n");
|
||||
fclose(f);
|
||||
/* Closing and reopening because of a write issue we are having right now */
|
||||
f = fopen("SD:/config/GXGlobal.cfg", "w");
|
||||
f = fopen(GXGlobal_cfg, "w");
|
||||
fprintf(f, "# USB Loader global settings file\n");
|
||||
fprintf(f, "# Note: This file is automatically generated\n");
|
||||
fprintf(f, "video = %d\n ", Settings.video);
|
||||
@ -1373,20 +1377,28 @@ void game_set_num(char *name, char *val)
|
||||
|
||||
bool cfg_load_games()
|
||||
{
|
||||
return cfg_parsefile("SD:/config/GXGameSettings.cfg", &game_set);
|
||||
char GXGameSettings_cfg[32];
|
||||
sprintf(GXGameSettings_cfg, "%s/config/GXGameSettings.cfg", bootDevice);
|
||||
return cfg_parsefile(GXGameSettings_cfg, &game_set);
|
||||
}
|
||||
|
||||
bool cfg_load_game_num()
|
||||
{
|
||||
return cfg_parsefile("SD:/config/GXGameFavorites.cfg", &game_set_num);
|
||||
char GXGameFavorites_cfg[32];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice);
|
||||
return cfg_parsefile(GXGameFavorites_cfg, &game_set_num);
|
||||
}
|
||||
|
||||
bool cfg_save_games()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
mkdir("SD:/config/", 0777);
|
||||
f = fopen("SD:/config/GXGameSettings.cfg", "w");
|
||||
char GXGameSettings_cfg[32];
|
||||
sprintf(GXGameSettings_cfg, "%s/config", bootDevice);
|
||||
mkdir(GXGameSettings_cfg, 0777);
|
||||
|
||||
sprintf(GXGameSettings_cfg, "%s/config/GXGameSettings.cfg", bootDevice);
|
||||
f = fopen(GXGameSettings_cfg, "w");
|
||||
if (!f) {
|
||||
printf("Error saving %s\n", "GXGameSettings.cfg");
|
||||
sleep(1);
|
||||
@ -1396,7 +1408,7 @@ bool cfg_save_games()
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fclose(f);
|
||||
/* Closing and reopening because of a write issue we are having right now */
|
||||
f = fopen("SD:/config/GXGameSettings.cfg", "w");
|
||||
f = fopen(GXGameSettings_cfg, "w");
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fprintf(f, "# Num Games: %d\n", num_saved_games);
|
||||
@ -1422,8 +1434,12 @@ bool cfg_save_game_num()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
mkdir("SD:/config/", 0777);
|
||||
f = fopen("SD:/config/GXGameFavorites.cfg", "w");
|
||||
char GXGameFavorites_cfg[32];
|
||||
sprintf(GXGameFavorites_cfg, "%s/config", bootDevice);
|
||||
mkdir(GXGameFavorites_cfg, 0777);
|
||||
|
||||
sprintf(GXGameFavorites_cfg, "%s/config/GXGameFavorites.cfg", bootDevice);
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
if (!f) {
|
||||
printf("Error saving %s\n", "GXGameFavorites.cfg");
|
||||
sleep(1);
|
||||
@ -1433,7 +1449,7 @@ bool cfg_save_game_num()
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fclose(f);
|
||||
/* Closing and reopening because of a write issue we are having right now */
|
||||
f = fopen("SD:/config/GXGameFavorites.cfg", "w");
|
||||
f = fopen(GXGameFavorites_cfg, "w");
|
||||
fprintf(f, "# USB Loader settings file\n");
|
||||
fprintf(f, "# note: this file is automatically generated\n");
|
||||
fprintf(f, "# Num Games: %d\n", num_saved_game_num);
|
||||
@ -1449,6 +1465,8 @@ bool cfg_save_game_num()
|
||||
|
||||
bool cfg_load_global()
|
||||
{
|
||||
char GXGlobal_cfg[26];
|
||||
sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice);
|
||||
//Default values defined by dev team
|
||||
Settings.video = discdefault;
|
||||
Settings.vpatch = off;
|
||||
@ -1469,7 +1487,7 @@ bool cfg_load_global()
|
||||
Settings.volume = 80;
|
||||
Settings.sfxvolume = 80;
|
||||
|
||||
return cfg_parsefile("SD:/config/GXGlobal.cfg", &global_cfg_set);
|
||||
return cfg_parsefile(GXGlobal_cfg, &global_cfg_set);
|
||||
}
|
||||
|
||||
|
||||
@ -1537,7 +1555,7 @@ void CFG_Load(void)
|
||||
|
||||
CFG_Default(-1); // set defaults non forced
|
||||
|
||||
snprintf(pathname, sizeof(pathname), "SD:/config/GXGlobal.cfg");
|
||||
snprintf(pathname, sizeof(pathname), "%s/config/GXGlobal.cfg", bootDevice);
|
||||
|
||||
cfg_parsefile(pathname, &widescreen_set); //first set widescreen
|
||||
cfg_parsefile(pathname, &path_set); //then set config and layout options
|
||||
@ -1551,7 +1569,8 @@ void CFG_Load(void)
|
||||
snprintf(pathname, sizeof(pathname), "%stitles.txt", Settings.titlestxt_path);
|
||||
cfg_parsefile(pathname, &title_set);
|
||||
|
||||
cfg_parsefile("SD:/config/GXGameSettings.cfg", &parental_set);
|
||||
snprintf(pathname, sizeof(pathname), "%s/config/GXGameSettings.cfg", bootDevice);
|
||||
cfg_parsefile(pathname, &parental_set);
|
||||
|
||||
// load per-game settings
|
||||
cfg_load_games();
|
||||
@ -1570,7 +1589,9 @@ void CFG_Load(void)
|
||||
|
||||
void CFG_LoadGlobal(void)
|
||||
{
|
||||
cfg_parsefile("SD:/config/GXGlobal.cfg", &global_cfg_set);
|
||||
char GXGlobal_cfg[26];
|
||||
sprintf(GXGlobal_cfg, "%s/config/GXGlobal.cfg", bootDevice);
|
||||
cfg_parsefile(GXGlobal_cfg, &global_cfg_set);
|
||||
}
|
||||
|
||||
void CFG_Cleanup(void)
|
||||
|
@ -41,7 +41,8 @@ extern "C"
|
||||
#define CFG_ALIGN_BOTTOM 4
|
||||
#define CFG_ALIGN_MIDDLE 5
|
||||
|
||||
extern char *cfg_path;
|
||||
extern char bootDevice[10];
|
||||
//extern char *cfg_path;
|
||||
|
||||
struct CFG
|
||||
{
|
||||
@ -161,6 +162,7 @@ extern u8 wsprompt;
|
||||
extern u8 keyset;
|
||||
extern u8 gameDisplay;
|
||||
|
||||
|
||||
struct Game_CFG
|
||||
{
|
||||
u8 id[8];
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <fat.h>
|
||||
#include <string.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
@ -6,21 +7,154 @@
|
||||
#include <ogc/system.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include "usbstorage.h"
|
||||
|
||||
//these are the only stable and speed is good
|
||||
#define CACHE 32
|
||||
#define SECTORS 128
|
||||
|
||||
enum BPB {
|
||||
BPB_jmpBoot = 0x00,
|
||||
BPB_OEMName = 0x03,
|
||||
// BIOS Parameter Block
|
||||
BPB_bytesPerSector = 0x0B,
|
||||
BPB_sectorsPerCluster = 0x0D,
|
||||
BPB_reservedSectors = 0x0E,
|
||||
BPB_numFATs = 0x10,
|
||||
BPB_rootEntries = 0x11,
|
||||
BPB_numSectorsSmall = 0x13,
|
||||
BPB_mediaDesc = 0x15,
|
||||
BPB_sectorsPerFAT = 0x16,
|
||||
BPB_sectorsPerTrk = 0x18,
|
||||
BPB_numHeads = 0x1A,
|
||||
BPB_numHiddenSectors = 0x1C,
|
||||
BPB_numSectors = 0x20,
|
||||
// Ext BIOS Parameter Block for FAT16
|
||||
BPB_FAT16_driveNumber = 0x24,
|
||||
BPB_FAT16_reserved1 = 0x25,
|
||||
BPB_FAT16_extBootSig = 0x26,
|
||||
BPB_FAT16_volumeID = 0x27,
|
||||
BPB_FAT16_volumeLabel = 0x2B,
|
||||
BPB_FAT16_fileSysType = 0x36,
|
||||
// Bootcode
|
||||
BPB_FAT16_bootCode = 0x3E,
|
||||
// FAT32 extended block
|
||||
BPB_FAT32_sectorsPerFAT32 = 0x24,
|
||||
BPB_FAT32_extFlags = 0x28,
|
||||
BPB_FAT32_fsVer = 0x2A,
|
||||
BPB_FAT32_rootClus = 0x2C,
|
||||
BPB_FAT32_fsInfo = 0x30,
|
||||
BPB_FAT32_bkBootSec = 0x32,
|
||||
// Ext BIOS Parameter Block for FAT32
|
||||
BPB_FAT32_driveNumber = 0x40,
|
||||
BPB_FAT32_reserved1 = 0x41,
|
||||
BPB_FAT32_extBootSig = 0x42,
|
||||
BPB_FAT32_volumeID = 0x43,
|
||||
BPB_FAT32_volumeLabel = 0x47,
|
||||
BPB_FAT32_fileSysType = 0x52,
|
||||
// Bootcode
|
||||
BPB_FAT32_bootCode = 0x5A,
|
||||
BPB_bootSig_55 = 0x1FE,
|
||||
BPB_bootSig_AA = 0x1FF
|
||||
};
|
||||
|
||||
static const char FAT_SIG[3] = {'F', 'A', 'T'};
|
||||
|
||||
#define BYTES_PER_READ 512
|
||||
|
||||
static bool _FAT_partition_isFAT(const DISC_INTERFACE* disc, sec_t startSector)
|
||||
{
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
if (!disc->readSectors(startSector, 1, sectorBuffer)) {
|
||||
return false;
|
||||
}
|
||||
// Make sure it is a valid BPB
|
||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now verify that this is indeed a FAT partition
|
||||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
|
||||
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check again for the last two cases to make sure that we really have a FAT filesystem here
|
||||
// and won't corrupt any data
|
||||
if(memcmp(sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3) != 0 && memcmp(sectorBuffer + BPB_FAT32_fileSysType, "FAT32", 5) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) {
|
||||
return ( item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24));
|
||||
}
|
||||
|
||||
sec_t GetFATPartition(const DISC_INTERFACE* disc)
|
||||
{
|
||||
int i;
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
sec_t startSector = 0;
|
||||
|
||||
if(!disc->startup())
|
||||
return 0;
|
||||
|
||||
// Read first sector of disc
|
||||
if (!disc->readSectors(0, 1, sectorBuffer))
|
||||
startSector = 0;
|
||||
|
||||
// Make sure it is a valid MBR or boot sector
|
||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA))
|
||||
startSector = 0;
|
||||
|
||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
// Check if there is a FAT string, which indicates this is a boot sector
|
||||
startSector = 0;
|
||||
}
|
||||
else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
// Check for FAT32
|
||||
startSector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an MBR
|
||||
// Find first valid partition from MBR
|
||||
// First check for an active partition
|
||||
for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10);
|
||||
// If it find an active partition, check for FAT-Partition
|
||||
if ( i != 0x1FE && !_FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8 + i)) )
|
||||
i = 0x1FE;
|
||||
|
||||
// If it didn't find an active partition, search for any valid partition
|
||||
if (i == 0x1FE)
|
||||
{
|
||||
for (i=0x1BE; i < 0x1FE; i+= 0x10)
|
||||
{
|
||||
if ( sectorBuffer[i+0x04] != 0x00 && _FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8 + i)) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != 0x1FE)
|
||||
startSector = u8array_to_u32(sectorBuffer, 0x8 + i);;
|
||||
}
|
||||
disc->shutdown();
|
||||
return startSector;
|
||||
}
|
||||
|
||||
int USBDevice_Init()
|
||||
{
|
||||
return 0;
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
__io_usbstorage.startup();
|
||||
|
||||
fatUnmount("USB:/");
|
||||
//right now only mounts first partition
|
||||
if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
|
||||
//right now mounts first FAT-partition
|
||||
if (fatMount("USB", &__io_usbstorage, GetFATPartition(&__io_usbstorage), CACHE, SECTORS)) {
|
||||
//try first mount with libogc
|
||||
return 1;
|
||||
} else if (fatMount("USB", &__io_wiiums, GetFATPartition(&__io_wiiums), CACHE, SECTORS)) {
|
||||
//try now mount with cIOS
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
@ -28,10 +162,8 @@ int USBDevice_Init()
|
||||
|
||||
void USBDevice_deInit()
|
||||
{
|
||||
return;
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("USB:/");
|
||||
__io_usbstorage.shutdown();
|
||||
}
|
||||
|
||||
int isSdInserted()
|
||||
@ -39,14 +171,21 @@ int isSdInserted()
|
||||
return __io_wiisd.isInserted();
|
||||
}
|
||||
|
||||
DISC_INTERFACE **_FAT_partition_getPartitionFromPath (const char* path);
|
||||
int isInserted(const char *path)
|
||||
{
|
||||
if(!strncmp(path, "USB:", 4))
|
||||
return 1;
|
||||
// if(!strncmp(path, "SD:", 3))
|
||||
return __io_wiisd.isInserted();
|
||||
return 0;
|
||||
}
|
||||
int SDCard_Init()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
__io_wiisd.startup();
|
||||
|
||||
fatUnmount("SD:/");
|
||||
//right now only mounts first partition
|
||||
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS))
|
||||
//right now mounts first FAT-partition
|
||||
if (fatMount("SD", &__io_wiisd, GetFATPartition(&__io_wiisd), CACHE, SECTORS))
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
@ -55,5 +194,4 @@ void SDCard_deInit()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("SD:/");
|
||||
__io_wiisd.shutdown();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ extern "C"
|
||||
int USBDevice_Init();
|
||||
void USBDevice_deInit();
|
||||
int isSdInserted();
|
||||
int isInserted(const char *path);
|
||||
int SDCard_Init();
|
||||
void SDCard_deInit();
|
||||
|
||||
|
@ -54,7 +54,6 @@ u32 do_sd_code(char *filename)
|
||||
u32 ret;
|
||||
char filepath[128];
|
||||
|
||||
__io_wiisd.startup();
|
||||
ret = fatMountSimple("SD", &__io_wiisd);
|
||||
|
||||
if (!ret) {
|
||||
@ -74,7 +73,6 @@ u32 do_sd_code(char *filename)
|
||||
fp = fopen(filepath, "rb");
|
||||
if (!fp) {
|
||||
fatUnmount("SD:/");
|
||||
__io_wiisd.shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -94,7 +92,6 @@ u32 do_sd_code(char *filename)
|
||||
free(filebuff);
|
||||
fclose(fp);
|
||||
fatUnmount("SD:/");
|
||||
__io_wiisd.shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -107,7 +104,6 @@ u32 do_sd_code(char *filename)
|
||||
fclose(fp);
|
||||
|
||||
fatUnmount("SD:/");
|
||||
__io_wiisd.shutdown();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -48,31 +48,24 @@ s32 filenamescmp(const void *a, const void *b)
|
||||
|
||||
int GetAllDirFiles(char * filespath)
|
||||
{
|
||||
|
||||
int countfiles = 0;
|
||||
|
||||
struct stat st;
|
||||
DIR_ITER* dir;
|
||||
dir = diropen (filespath);
|
||||
|
||||
if (dir == NULL) //If empty
|
||||
{
|
||||
int countfiles = 0;
|
||||
|
||||
struct stat st;
|
||||
DIR_ITER* dir;
|
||||
dir = diropen (filespath);
|
||||
|
||||
if (dir == NULL) //If empty
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (dirnext(dir,filenames,&st) == 0)
|
||||
{
|
||||
{
|
||||
if ((st.st_mode & S_IFDIR) == 0)
|
||||
{
|
||||
{
|
||||
// st.st_mode & S_IFDIR indicates a directory
|
||||
snprintf(alldirfiles[countfiles], 70, "%s", filenames);
|
||||
countfiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dirclose(dir);
|
||||
qsort(alldirfiles, countfiles, sizeof(char[70]), filenamescmp);
|
||||
|
||||
return countfiles;
|
||||
return countfiles;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/dir.h>
|
||||
#include <ogcsys.h>
|
||||
#include <unistd.h>
|
||||
#include <wiiuse/wpad.h>
|
||||
@ -68,12 +69,32 @@ main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
s32 ret2;
|
||||
|
||||
SDCard_Init(); // mount SD for loading cfg's
|
||||
USBDevice_Init(); // and mount USB:/
|
||||
bool bootDevice_found=false;
|
||||
if(argc >= 1)
|
||||
{
|
||||
if(!strncasecmp(argv[0], "usb:/", 5))
|
||||
{
|
||||
strcpy(bootDevice, "USB:");
|
||||
bootDevice_found = true;
|
||||
}
|
||||
else if(!strncasecmp(argv[0], "sd:/", 4))
|
||||
bootDevice_found = true;
|
||||
}
|
||||
if(!bootDevice_found)
|
||||
{
|
||||
//try USB
|
||||
if((stat("USB:/apps/usbloader_gx/boot.dol", NULL) == 0) || (stat("USB:/apps/usbloader_gx/boot.elf", NULL) == 0))
|
||||
strcpy(bootDevice, "USB:");
|
||||
}
|
||||
|
||||
SDCard_Init(); // mount SD for loading cfg's
|
||||
lang_default();
|
||||
CFG_Load();
|
||||
|
||||
SDCard_deInit();// unmount SD for reloading IOS
|
||||
USBDevice_deInit();// unmount USB for reloading IOS
|
||||
|
||||
/* Load Custom IOS */
|
||||
if(Settings.cios == ios222) {
|
||||
|
@ -688,7 +688,8 @@ static int MenuDiscList()
|
||||
else if (Settings.gameDisplay==carousel){
|
||||
startat = gameCarousel->GetSelectedOption();
|
||||
offset = gameCarousel->GetOffset();}
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
CFG_Load();
|
||||
}
|
||||
sdcardBtn.ResetState();
|
||||
@ -698,7 +699,8 @@ static int MenuDiscList()
|
||||
|
||||
else if(DownloadBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
choice = WindowPrompt(LANGUAGE.CoverDownload, 0, LANGUAGE.NormalCovers, LANGUAGE.t3Covers, LANGUAGE.DiscImages, LANGUAGE.Back); // ask for download choice
|
||||
|
||||
if (choice != 0)
|
||||
@ -771,7 +773,8 @@ static int MenuDiscList()
|
||||
else if(favoriteBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
Settings.fave=!Settings.fave;
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
}
|
||||
__Menu_GetEntries();
|
||||
@ -797,7 +800,8 @@ static int MenuDiscList()
|
||||
{
|
||||
if(Settings.sort != all) {
|
||||
Settings.sort=all;
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
}
|
||||
__Menu_GetEntries();
|
||||
@ -826,7 +830,8 @@ static int MenuDiscList()
|
||||
{
|
||||
if(Settings.sort != pcount) {
|
||||
Settings.sort=pcount;
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
cfg_save_global();
|
||||
}
|
||||
__Menu_GetEntries();
|
||||
@ -1223,7 +1228,8 @@ static int MenuDiscList()
|
||||
|
||||
}count+=1;
|
||||
|
||||
if(isSdInserted()) {
|
||||
//if(isSdInserted()) {
|
||||
if(isInserted(bootDevice)) {
|
||||
if (CFG_save_game_num(header->id))
|
||||
{
|
||||
//WindowPrompt(LANGUAGE.SuccessfullySaved, 0, LANGUAGE.ok, 0,0,0);
|
||||
|
@ -184,3 +184,88 @@ s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S')
|
||||
|
||||
|
||||
bool umsio_Startup()
|
||||
{
|
||||
return USBStorage_Init() == 0;
|
||||
}
|
||||
|
||||
bool umsio_IsInserted()
|
||||
{
|
||||
return true; // allways true
|
||||
}
|
||||
bool umsio_ReadSectors(sec_t sector, sec_t numSectors, u8 *buffer)
|
||||
{
|
||||
u32 cnt = 0;
|
||||
s32 ret;
|
||||
/* Do reads */
|
||||
while (cnt < numSectors)
|
||||
{
|
||||
u32 sectors = (numSectors - cnt);
|
||||
|
||||
/* Read sectors is too big */
|
||||
if (sectors > 32)
|
||||
sectors = 32;
|
||||
|
||||
/* USB read */
|
||||
ret = USBStorage_ReadSectors(sector + cnt, sectors, &buffer[cnt*512]);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
/* Increment counter */
|
||||
cnt += sectors;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool umsio_WriteSectors(sec_t sector, sec_t numSectors, const u8* buffer)
|
||||
{
|
||||
u32 cnt = 0;
|
||||
s32 ret;
|
||||
|
||||
/* Do writes */
|
||||
while (cnt < numSectors)
|
||||
{
|
||||
u32 sectors = (numSectors - cnt);
|
||||
|
||||
/* Write sectors is too big */
|
||||
if (sectors > 32)
|
||||
sectors = 32;
|
||||
|
||||
/* USB write */
|
||||
ret = USBStorage_WriteSectors(sector + cnt, sectors, &buffer[cnt * 512]);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
/* Increment counter */
|
||||
cnt += sectors;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool umsio_ClearStatus(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool umsio_Shutdown()
|
||||
{
|
||||
USBStorage_Deinit();
|
||||
return true;
|
||||
}
|
||||
const DISC_INTERFACE __io_wiiums =
|
||||
{
|
||||
DEVICE_TYPE_WII_UMS,
|
||||
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
|
||||
(FN_MEDIUM_STARTUP)&umsio_Startup,
|
||||
(FN_MEDIUM_ISINSERTED)&umsio_IsInserted,
|
||||
(FN_MEDIUM_READSECTORS)&umsio_ReadSectors,
|
||||
(FN_MEDIUM_WRITESECTORS)&umsio_WriteSectors,
|
||||
(FN_MEDIUM_CLEARSTATUS)&umsio_ClearStatus,
|
||||
(FN_MEDIUM_SHUTDOWN)&umsio_Shutdown
|
||||
};
|
||||
|
@ -10,8 +10,8 @@ s32 USBStorage_GetCapacity(u32 *);
|
||||
s32 USBStorage_Init(void);
|
||||
void USBStorage_Deinit(void);
|
||||
s32 USBStorage_ReadSectors(u32, u32, void *);
|
||||
s32 USBStorage_WriteSectors(u32, u32, void *);
|
||||
|
||||
s32 USBStorage_WriteSectors(u32, u32, const void *);
|
||||
extern const DISC_INTERFACE __io_wiiums;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,6 +34,10 @@ s32 WBFS_GameSize(u8 *, f32 *);
|
||||
s32 WBFS_DiskSpace(f32 *, f32 *);
|
||||
s32 WBFS_RenameGame(u8 *, const void *);
|
||||
f32 WBFS_EstimeGameSize(void);
|
||||
|
||||
s32 __WBFS_ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
|
||||
s32 __WBFS_WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user