mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
USB Loader GX Release V2.2
New: - Added game categories and filter games list by categories (Can be imported from WiiTDB). - Wiinertag support. - Supporting arguments from meta.xml on boot (--ios=xxx and --usbport=x) (Requires Homebrew Channel 1.0.7+ or UNEO Forwarder v3.0). - New ehci modules by Rodries with better drive compatibility. - Added two new video modes to force progressive video mode, 'FORCE PAL480p' and 'FORCE NTSC480p'. - Added Sneek Video Patch mode. - Added new 'Inherit' setting for game settings named "Use global". If that option is set then the main loader setting is used. - Full d2x cIOS support with it's new features (Block IOS Reload, Return To, Sector Sizes > 512). - Support for sector sizes > 512B with FAT32/NTFS (Requires d2x v6+) - Real support for simultanious use of both USB ports without switching the 2nd drive temporary off. (Requires Hermes cIOS or Rodries MOD of the Hermes cIOS (recommended)) - Added two new settings menus - Added saving of game browser position when returning to USB Loader GX Changes: - Improved several GUI controls/navigations - Changed settings menu layout and sorted the items to their correct place (HDD menu, features menu) - Set games settings to use the global setting by default, set to "use global" to use the main loader settings. - Use TinyXML instead of MXML (better XML support) - Updated to new libs (libogc, libfat, libext2fs, libntfs) Fix: - "Return to" option now work for all games, even problematic games like Prince of Persia. (Requires d2x v4+) - Xflip setting fixed. - Fix the parental lock of Individual game settings (Thanks to NJ7) - Fix Theme downloader - Fixed reset of the loader when loading game with IOS reload and disabled WiiTDB titles - Fixed timeout timer on startup to count correctly. - Fixed reversed disc image download when Custom/Original option is selected - Fixed reload of game list after a game rename - Fixed horizontal text scrolling - Fixed booting games by arguments (headless id feature) - Fixed We Dare game boot (thx oggzee) R1099 Change Log: *Added IOS225 from Rodries cIOS Installer MOD to Hermes IOS types New Forwarder V3.0 Changes: *added support for ext partitions *added support for arguments from xml *clean up of source
This commit is contained in:
parent
72c39f8cab
commit
1618b4b1e0
4
Makefile
4
Makefile
@ -38,7 +38,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -lfat -lntfs -lpng -lz -lbte -logc -lm
|
LIBS := -lfat -lntfs -lext2fs -lpng -lz -lbte -logc -lm
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
@ -107,7 +107,7 @@ export OUTPUT := $(CURDIR)/$(TARGET)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
|
@ -18,7 +18,6 @@ u8 * GetImageData()
|
|||||||
else
|
else
|
||||||
ctx = PNGU_SelectImageFromBuffer(background_png);
|
ctx = PNGU_SelectImageFromBuffer(background_png);
|
||||||
|
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
97
source/cfg.c
97
source/cfg.c
@ -6,72 +6,67 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <ogcsys.h>
|
#include <ogcsys.h>
|
||||||
|
|
||||||
#include "cfg.h"
|
static char *trimcopy(char *src, char *dest, int size)
|
||||||
|
|
||||||
char update_path[150];
|
|
||||||
|
|
||||||
static char *cfg_name, *cfg_val;
|
|
||||||
|
|
||||||
char* strcopy(char *dest, char *src, int size)
|
|
||||||
{
|
{
|
||||||
strncpy(dest,src,size);
|
int i = 0;
|
||||||
dest[size-1] = 0;
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* trimcopy(char *dest, char *src, int size)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
while (*src == ' ') src++;
|
while (*src == ' ') src++;
|
||||||
len = strlen(src);
|
|
||||||
// trim trailing " \r\n"
|
while (*src != 0 && *src != '\n' && *src != '\r' && i < size-1)
|
||||||
while (len > 0 && strchr(" \r\n", src[len-1])) len--;
|
{
|
||||||
if (len >= size) len = size-1;
|
dest[i] = *src;
|
||||||
strncpy(dest, src, len);
|
i++;
|
||||||
dest[len] = 0;
|
src++;
|
||||||
|
}
|
||||||
|
dest[i] = 0;
|
||||||
|
i--;
|
||||||
|
|
||||||
|
while(i > 0 && dest[i] == ' ')
|
||||||
|
{
|
||||||
|
dest[i] = 0;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfg_parseline(char *line, void (*set_func)(char*, char*))
|
static char *cfg_parseline(char *line)
|
||||||
{
|
{
|
||||||
// split name = value
|
char tmp[300], name[200];
|
||||||
char tmp[200], name[100], val[100];
|
snprintf(tmp, sizeof(tmp), line);
|
||||||
strcopy(tmp, line, sizeof(tmp));
|
|
||||||
char *eq = strchr(tmp, '=');
|
char *eq = strchr(tmp, '=');
|
||||||
if (!eq) return;
|
if (!eq)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
*eq = 0;
|
*eq = 0;
|
||||||
trimcopy(name, tmp, sizeof(name));
|
|
||||||
trimcopy(val, eq+1, sizeof(val));
|
trimcopy(tmp, name, sizeof(name));
|
||||||
//printf("CFG: %s = %s\n", name, val);
|
|
||||||
set_func(name, val);
|
if(strcmp(name, "update_path") == 0)
|
||||||
|
return eq+1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cfg_parsefile(char *fname, int size)
|
||||||
bool cfg_parsefile(char *fname, void (*set_func)(char*, char*))
|
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f = fopen(fname, "r");
|
||||||
char line[200];
|
if (!f)
|
||||||
|
|
||||||
//printf("opening(%s)\n", fname);
|
|
||||||
f = fopen(fname, "r");
|
|
||||||
if (!f) {
|
|
||||||
//printf("error opening(%s)\n", fname);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
while (fgets(line, sizeof(line), f)) {
|
char line[300];
|
||||||
// lines starting with # are comments
|
|
||||||
|
while (fgets(line, sizeof(line), f))
|
||||||
|
{
|
||||||
if (line[0] == '#') continue;
|
if (line[0] == '#') continue;
|
||||||
cfg_parseline(line, set_func);
|
|
||||||
|
char * value = cfg_parseline(line);
|
||||||
|
if(value)
|
||||||
|
{
|
||||||
|
trimcopy(value, fname, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfg_set(char *name, char *val)
|
|
||||||
{
|
|
||||||
cfg_name = name;
|
|
||||||
cfg_val = val;
|
|
||||||
if (strcmp(name, "update_path") == 0) {
|
|
||||||
strcopy(update_path, val, sizeof(update_path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
33
source/cfg.h
33
source/cfg.h
@ -1,18 +1,15 @@
|
|||||||
#ifndef _CFG_H_
|
#ifndef _CFG_H_
|
||||||
#define _CFG_H_
|
#define _CFG_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char update_path[150];
|
bool cfg_parsefile(char * fname, int maxsize);
|
||||||
|
|
||||||
void cfg_set(char *name, char *val);
|
#ifdef __cplusplus
|
||||||
bool cfg_parsefile(char * fname, void (*set_func)(char*, char*));
|
}
|
||||||
|
#endif
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <ntfs.h>
|
#include <ntfs.h>
|
||||||
|
#include <ext2.h>
|
||||||
#include <sdcard/wiisd_io.h>
|
#include <sdcard/wiisd_io.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -33,6 +34,7 @@ typedef struct _MASTER_BOOT_RECORD {
|
|||||||
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
|
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
|
||||||
|
|
||||||
|
|
||||||
|
#define PARTITION_TYPE_LINUX 0x83
|
||||||
#define le32(i) (((((u32) i) & 0xFF) << 24) | ((((u32) i) & 0xFF00) << 8) | \
|
#define le32(i) (((((u32) i) & 0xFF) << 24) | ((((u32) i) & 0xFF00) << 8) | \
|
||||||
((((u32) i) & 0xFF0000) >> 8) | ((((u32) i) & 0xFF000000) >> 24))
|
((((u32) i) & 0xFF0000) >> 8) | ((((u32) i) & 0xFF000000) >> 24))
|
||||||
|
|
||||||
@ -76,6 +78,10 @@ int USBDevice_Init()
|
|||||||
ntfsMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr.partitions[i].lba_start), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER | NTFS_IGNORE_CASE);
|
ntfsMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr.partitions[i].lba_start), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER | NTFS_IGNORE_CASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(mbr.partitions[i].type == PARTITION_TYPE_LINUX)
|
||||||
|
{
|
||||||
|
ext2Mount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr.partitions[i].lba_start), CACHE, SECTORS, EXT2_FLAG_DEFAULT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -39,6 +39,78 @@
|
|||||||
|
|
||||||
void __exception_setreload(int t);
|
void __exception_setreload(int t);
|
||||||
|
|
||||||
|
static int GetXMLArguments(const char *path, struct __argv *args)
|
||||||
|
{
|
||||||
|
char xmlpath[200];
|
||||||
|
snprintf(xmlpath, sizeof(xmlpath), "%s", path);
|
||||||
|
|
||||||
|
char *ptr = strrchr(xmlpath, '/');
|
||||||
|
if(ptr)
|
||||||
|
ptr[1] = '\0';
|
||||||
|
else
|
||||||
|
return -1; // only take full path
|
||||||
|
|
||||||
|
strncat(xmlpath, "meta.xml", sizeof(xmlpath));
|
||||||
|
|
||||||
|
FILE *fp = fopen(xmlpath, "rb");
|
||||||
|
if(!fp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
int size = ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
|
||||||
|
char *fileBuf = (char *) malloc(size+1);
|
||||||
|
if(!fileBuf)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(fileBuf, 1, size, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
fileBuf[size] = '\0';
|
||||||
|
|
||||||
|
const int max_len = 1024;
|
||||||
|
char *entry = (char *) malloc(max_len);
|
||||||
|
ptr = fileBuf;
|
||||||
|
|
||||||
|
while(ptr)
|
||||||
|
{
|
||||||
|
char *comment = strstr(ptr, "<!--");
|
||||||
|
ptr = strstr(ptr, "<arg>");
|
||||||
|
if(!ptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(comment && comment < ptr)
|
||||||
|
{
|
||||||
|
ptr = strstr(ptr, "-->");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += strlen("<arg>");
|
||||||
|
int len;
|
||||||
|
for(len = 0; *ptr != '\0' && !(ptr[0] == '<' && ptr[1] == '/') && len < max_len-1; ptr++, len++)
|
||||||
|
entry[len] = *ptr;
|
||||||
|
|
||||||
|
entry[len] = '\0';
|
||||||
|
|
||||||
|
char *tmp = (char *) realloc(args->commandLine, args->length + len + 1);
|
||||||
|
if(!tmp)
|
||||||
|
break; //out of memory, take what we got until now
|
||||||
|
|
||||||
|
args->commandLine = tmp;
|
||||||
|
strcpy(args->commandLine + args->length - 1, entry);
|
||||||
|
args->length += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(entry);
|
||||||
|
free(fileBuf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static FILE * open_file(const char * dev, char * filepath)
|
static FILE * open_file(const char * dev, char * filepath)
|
||||||
{
|
{
|
||||||
sprintf(filepath, "%s:/apps/usbloader_gx/boot.dol", dev);
|
sprintf(filepath, "%s:/apps/usbloader_gx/boot.dol", dev);
|
||||||
@ -58,21 +130,21 @@ static FILE * open_file(const char * dev, char * filepath)
|
|||||||
return exeFile;
|
return exeFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FindConfigPath(const char * device, char *cfgpath)
|
static bool FindConfigPath(const char * device, char *cfgpath, int maxsize)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
sprintf(cfgpath, "%s:/config/GXGlobal.cfg", device);
|
snprintf(cfgpath, maxsize, "%s:/config/GXGlobal.cfg", device);
|
||||||
result = cfg_parsefile(cfgpath, &cfg_set);
|
result = cfg_parsefile(cfgpath, maxsize);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
{
|
{
|
||||||
sprintf(cfgpath, "%s:/apps/usbloader_gx/GXGlobal.cfg", device);
|
snprintf(cfgpath, maxsize, "%s:/apps/usbloader_gx/GXGlobal.cfg", device);
|
||||||
result = cfg_parsefile(cfgpath, &cfg_set);
|
result = cfg_parsefile(cfgpath, maxsize);
|
||||||
}
|
}
|
||||||
if(!result)
|
if(!result)
|
||||||
{
|
{
|
||||||
sprintf(cfgpath, "%s:/apps/usbloadergx/GXGlobal.cfg", device);
|
snprintf(cfgpath, maxsize, "%s:/apps/usbloadergx/GXGlobal.cfg", device);
|
||||||
result = cfg_parsefile(cfgpath, &cfg_set);
|
result = cfg_parsefile(cfgpath, maxsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -99,7 +171,7 @@ int main(int argc, char **argv)
|
|||||||
// try SD Card First
|
// try SD Card First
|
||||||
SDCard_Init();
|
SDCard_Init();
|
||||||
|
|
||||||
if(FindConfigPath(DeviceName[SD], filepath))
|
if(FindConfigPath(DeviceName[SD], filepath, sizeof(filepath)))
|
||||||
{
|
{
|
||||||
strcat(filepath, "boot.dol");
|
strcat(filepath, "boot.dol");
|
||||||
exeFile = fopen(filepath, "rb");
|
exeFile = fopen(filepath, "rb");
|
||||||
@ -113,7 +185,7 @@ int main(int argc, char **argv)
|
|||||||
int dev;
|
int dev;
|
||||||
for(dev = USB1; dev < MAXDEVICES; ++dev)
|
for(dev = USB1; dev < MAXDEVICES; ++dev)
|
||||||
{
|
{
|
||||||
if(FindConfigPath(DeviceName[dev], filepath))
|
if(FindConfigPath(DeviceName[dev], filepath, sizeof(filepath)))
|
||||||
{
|
{
|
||||||
strcat(filepath, "boot.dol");
|
strcat(filepath, "boot.dol");
|
||||||
exeFile = fopen(filepath, "rb");
|
exeFile = fopen(filepath, "rb");
|
||||||
@ -159,6 +231,7 @@ int main(int argc, char **argv)
|
|||||||
args.commandLine = (char*)malloc(args.length);
|
args.commandLine = (char*)malloc(args.length);
|
||||||
if (!args.commandLine) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
if (!args.commandLine) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||||
strcpy(args.commandLine, filepath);
|
strcpy(args.commandLine, filepath);
|
||||||
|
GetXMLArguments(filepath, &args);
|
||||||
args.commandLine[args.length - 1] = '\0';
|
args.commandLine[args.length - 1] = '\0';
|
||||||
args.argc = 1;
|
args.argc = 1;
|
||||||
args.argv = &args.commandLine;
|
args.argv = &args.commandLine;
|
||||||
@ -188,8 +261,9 @@ int main(int argc, char **argv)
|
|||||||
StopGX();
|
StopGX();
|
||||||
free(imgdata);
|
free(imgdata);
|
||||||
|
|
||||||
//! Reset HBC stub so we can leave correct from usb loader
|
//! Reset HBC stub so we can leave correct from USB Loader to System Menu
|
||||||
memset((char *) 0x80001804, 0, 8);
|
memset((char *) 0x80001804, 0, 8);
|
||||||
|
DCFlushRange((char *) 0x80001804, 8);
|
||||||
|
|
||||||
if (exeEntryPointAddress == 0)
|
if (exeEntryPointAddress == 0)
|
||||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user