* Fixed an issue where setting files were created on SD

if boot.dol was on USB (Thanks Badablek)
* Added Auto-edition of meta.xml arguments based on internal
  user settings.
* Added support for meta.xml arguments when rebooting the loader.

Nintendont :
* Added support for v1.20+
* Fixed launching Gamecube in FST format with nintendont 
  (Thank VashTS)
This commit is contained in:
Cyan 2014-05-04 14:42:52 +00:00
parent 6d9f213091
commit 64f448bc7f
14 changed files with 297 additions and 27 deletions

View File

@ -2,12 +2,13 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>3.0 r1221</version> <version>3.0 r1223</version>
<release_date>20140429130640</release_date> <release_date>20140504141623</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>
<arg>--ios=250</arg> <arg>--ios=250</arg>
<arg>--usbport=0</arg> <arg>--usbport=0</arg>
<arg>--mountusb=1</arg>
</arguments> </arguments>
// remove this line to enable arguments --> // remove this line to enable arguments -->
<ahb_access/> <ahb_access/>

View File

@ -96,6 +96,12 @@ int StartUpProcess::ParseArguments(int argc, char *argv[])
Settings.USBPort = LIMIT(atoi(ptr+strlen("-usbport=")), 0, 2); Settings.USBPort = LIMIT(atoi(ptr+strlen("-usbport=")), 0, 2);
} }
ptr = strcasestr(argv[i], "-mountusb=");
if(ptr)
{
Settings.USBAutoMount = LIMIT(atoi(ptr+strlen("-mountusb=")), 0, 1);
}
if(strlen(argv[i]) == 6 && strchr(argv[i], '=') == 0 && strchr(argv[i], '-') == 0) if(strlen(argv[i]) == 6 && strchr(argv[i], '=') == 0 && strchr(argv[i], '-') == 0)
quickBoot = i; quickBoot = i;
} }
@ -244,21 +250,16 @@ int StartUpProcess::Execute()
SetTextf("Initialize sd card\n"); SetTextf("Initialize sd card\n");
DeviceHandler::Instance()->MountSD(); DeviceHandler::Instance()->MountSD();
SetTextf("Loading config files\n");
// Ugly, but let's load SD card first to allow users to disable USB Auto mounting.
gprintf("\tLoading config from SD...");
bool settingsLoaded = Settings.Load();
gprintf("%s\n", settingsLoaded ? "done" : "failed");
if(Settings.USBAutoMount == ON) if(Settings.USBAutoMount == ON)
{ {
SetTextf("Initialize usb device\n"); SetTextf("Initialize usb device\n");
USBSpinUp(); USBSpinUp();
DeviceHandler::Instance()->MountAllUSB(false); DeviceHandler::Instance()->MountAllUSB(false);
} }
if(!settingsLoaded) gprintf("\tLoading config from USB...%s\n", Settings.Load() ? "done" : "failed"); SetTextf("Loading config files\n");
gprintf("\tLoading config...%s\n", Settings.Load() ? "done" : "failed");
gprintf("\tLoading language...%s\n", Settings.LoadLanguage(Settings.language_path, CONSOLE_DEFAULT) ? "done" : "failed"); gprintf("\tLoading language...%s\n", Settings.LoadLanguage(Settings.language_path, CONSOLE_DEFAULT) ? "done" : "failed");
gprintf("\tLoading game settings...%s\n", GameSettings.Load(Settings.ConfigPath) ? "done" : "failed"); gprintf("\tLoading game settings...%s\n", GameSettings.Load(Settings.ConfigPath) ? "done" : "failed");
gprintf("\tLoading game statistics...%s\n", GameStatistics.Load(Settings.ConfigPath) ? "done" : "failed"); gprintf("\tLoading game statistics...%s\n", GameStatistics.Load(Settings.ConfigPath) ? "done" : "failed");

View File

@ -88,6 +88,70 @@ int HomebrewXML::LoadHomebrewXMLData(const char* filename)
return 1; return 1;
} }
int HomebrewXML::SaveHomebrewXMLData(const char* filename)
{
const int max_line_size = 4096;
char *line = new char[max_line_size];
FILE *fp = fopen(filename, "wb");
if(!fp)
{
delete [] line;
return 0;
}
snprintf(line, max_line_size,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); fputs(line, fp);
snprintf(line, max_line_size,"<app version=\"1\">\n"); fputs(line, fp);
snprintf(line, max_line_size," <name>%s</name>\n", GetName()); fputs(line, fp);
snprintf(line, max_line_size," <coder>%s</coder>\n", GetCoder()); fputs(line, fp);
snprintf(line, max_line_size," <version>%s</version>\n", GetVersion()); fputs(line, fp);
snprintf(line, max_line_size," <release_date>%s</release_date>\n", GetReleasedate()); fputs(line, fp);
if (Arguments.size() > 0)
{
snprintf(line, max_line_size," <arguments>\n"); fputs(line, fp);
for(u8 i = 0; i < Arguments.size(); i++)
{
snprintf(line, max_line_size," <arg>%s</arg>\n", Arguments[i].c_str()); fputs(line, fp);
}
snprintf(line, max_line_size," </arguments>\n"); fputs(line, fp);
}
snprintf(line, max_line_size," <ahb_access/>\n"); fputs(line, fp);
snprintf(line, max_line_size," <short_description>%s</short_description>\n", GetShortDescription()); fputs(line, fp);
snprintf(line, max_line_size," <long_description>%s</long_description>\n", GetLongDescription()); fputs(line, fp);
snprintf(line, max_line_size,"</app>\n"); fputs(line, fp);
fclose(fp);
delete [] line;
return 1;
}
/* Set argument */
void HomebrewXML::SetArgument(const char* argument)
{
// Crop value from argument, if present
char argName[strlen(argument)+1];
strcpy(argName, argument);
char *ptr = strrchr(argName, '=');
if(ptr) *(ptr+1) = 0;
// Check if argument already exists and edit it
bool found = false;
for(u8 i=0; i < Arguments.size(); i++)
{
size_t pos = Arguments[i].find(argName);
if(pos != std::string::npos)
{
Arguments[i] = argument;
found = true;
break;
}
}
// if it doesn't exist, add the new argument.
if(!found)
Arguments.push_back(argument);
}
/* Get name */ /* Get name */
const char * HomebrewXML::GetName() const const char * HomebrewXML::GetName() const
{ {
@ -112,6 +176,12 @@ const char * HomebrewXML::GetVersion() const
return Version.c_str(); return Version.c_str();
} }
/* Set version */
void HomebrewXML::SetVersion(const char * newVer)
{
Version = newVer;
}
/* Get releasedate */ /* Get releasedate */
const char * HomebrewXML::GetReleasedate() const const char * HomebrewXML::GetReleasedate() const
{ {

View File

@ -15,15 +15,18 @@ class HomebrewXML
HomebrewXML(const char* filename) { LoadHomebrewXMLData(filename); }; HomebrewXML(const char* filename) { LoadHomebrewXMLData(filename); };
int LoadHomebrewXMLData(const char* filename); int LoadHomebrewXMLData(const char* filename);
int SaveHomebrewXMLData(const char* filename);
const char * GetName() const; const char * GetName() const;
void SetName(char * newName); void SetName(char * newName);
const char * GetCoder() const; const char * GetCoder() const;
const char * GetVersion() const; const char * GetVersion() const;
void SetVersion(const char * newVer);
const char * GetReleasedate() const; const char * GetReleasedate() const;
const char * GetShortDescription() const; const char * GetShortDescription() const;
const char * GetLongDescription() const; const char * GetLongDescription() const;
const std::vector<std::string> & GetArguments() const { return Arguments; }; const std::vector<std::string> & GetArguments() const { return Arguments; };
void SetArgument(const char* argument);
protected: protected:
std::string Name; std::string Name;

View File

@ -343,8 +343,10 @@ void WindowCredits()
// Nintendont Loader..Built : %s %s..Sep 20 2013.15:27:01 // alpha0.1 // Nintendont Loader..Built : %s %s..Sep 20 2013.15:27:01 // alpha0.1
if((*(u32*)(buffer+i+2)) == 'nten' && (*(u32*)(buffer+i+6)) == 'dont' && (*(u32*)(buffer+i+11)) == 'Load') if((*(u32*)(buffer+i+2)) == 'nten' && (*(u32*)(buffer+i+6)) == 'dont' && (*(u32*)(buffer+i+11)) == 'Load')
{ {
u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; // r39 only
if(buffer[i+17] == '\r') offset += 2; //v1.20+
for(int j = 0 ; j < 20 ; j++) for(int j = 0 ; j < 20 ; j++)
NINversion[j] = *(u8*)(buffer+i+36+j); NINversion[j] = *(u8*)(buffer+i+offset+j);
NINversion[11] = ' '; // replace \0 between year and time with a space. NINversion[11] = ' '; // replace \0 between year and time with a space.
NINversion[20] = 0; NINversion[20] = 0;
snprintf(GCInfo2, sizeof(GCInfo2), "Nintendont Built %.20s", NINversion ); snprintf(GCInfo2, sizeof(GCInfo2), "Nintendont Built %.20s", NINversion );

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2011 * Copyright (C) 2014 Cyan
* by Dimok * Copyright (C) 2011 Dimok
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
@ -26,6 +26,7 @@
#include "HardDriveSM.hpp" #include "HardDriveSM.hpp"
#include "Controls/DeviceHandler.hpp" #include "Controls/DeviceHandler.hpp"
#include "settings/CSettings.h" #include "settings/CSettings.h"
#include "settings/meta.h"
#include "prompts/PromptWindows.h" #include "prompts/PromptWindows.h"
#include "language/gettext.h" #include "language/gettext.h"
#include "usbloader/GameList.h" #include "usbloader/GameList.h"
@ -86,6 +87,7 @@ HardDriveSM::HardDriveSM()
OldSettingsPartition = Settings.partition; OldSettingsPartition = Settings.partition;
OldSettingsMultiplePartitions = Settings.MultiplePartitions; OldSettingsMultiplePartitions = Settings.MultiplePartitions;
NewSettingsUSBPort = Settings.USBPort; NewSettingsUSBPort = Settings.USBPort;
oldSettingsUSBAutoMount = Settings.USBAutoMount;
SetOptionValues(); SetOptionValues();
} }
@ -95,7 +97,8 @@ HardDriveSM::~HardDriveSM()
//! if partition has changed, Reinitialize it //! if partition has changed, Reinitialize it
if (Settings.partition != OldSettingsPartition || if (Settings.partition != OldSettingsPartition ||
Settings.MultiplePartitions != OldSettingsMultiplePartitions || Settings.MultiplePartitions != OldSettingsMultiplePartitions ||
Settings.USBPort != NewSettingsUSBPort) Settings.USBPort != NewSettingsUSBPort ||
Settings.USBAutoMount != oldSettingsUSBAutoMount)
{ {
WBFS_CloseAll(); WBFS_CloseAll();
@ -107,6 +110,9 @@ HardDriveSM::~HardDriveSM()
if(Settings.partition >= DeviceHandler::GetUSBPartitionCount()) if(Settings.partition >= DeviceHandler::GetUSBPartitionCount())
Settings.partition = 0; Settings.partition = 0;
// set -1 to edit meta.xml arguments
NewSettingsUSBPort = -1;
} }
WBFS_Init(WBFS_DEVICE_USB); WBFS_Init(WBFS_DEVICE_USB);
@ -119,6 +125,12 @@ HardDriveSM::~HardDriveSM()
gameList.ReadGameList(); gameList.ReadGameList();
gameList.LoadUnfiltered(); gameList.LoadUnfiltered();
GameTitles.LoadTitlesFromGameTDB(Settings.titlestxt_path, false); GameTitles.LoadTitlesFromGameTDB(Settings.titlestxt_path, false);
if(oldSettingsUSBAutoMount != Settings.USBAutoMount || NewSettingsUSBPort == -1)
{
// edit meta.xml arguments
editMetaArguments();
}
} }
} }

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2011 * Copyright (C) 2014 Cyan
* by Dimok * Copyright (C) 2011 Dimok
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
@ -37,6 +37,7 @@ class HardDriveSM : public SettingsMenu
int OldSettingsPartition; int OldSettingsPartition;
int OldSettingsMultiplePartitions; int OldSettingsMultiplePartitions;
int oldSettingsUSBAutoMount;
int NewSettingsUSBPort; int NewSettingsUSBPort;
OptionList GuiOptions; OptionList GuiOptions;

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2012-2013 by Cyan * Copyright (C) 2012-2014 Cyan
* Copyright (C) 2010 by Dimok * Copyright (C) 2010 by Dimok
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
@ -26,6 +26,7 @@
#include "usbloader/usbstorage2.h" #include "usbloader/usbstorage2.h"
#include "settings/CSettings.h" #include "settings/CSettings.h"
#include "settings/GameTitles.h" #include "settings/GameTitles.h"
#include "settings/meta.h"
#include "prompts/PromptWindows.h" #include "prompts/PromptWindows.h"
#include "language/gettext.h" #include "language/gettext.h"
#include "wad/nandtitle.h" #include "wad/nandtitle.h"
@ -218,6 +219,7 @@ LoaderSettings::LoaderSettings()
oldLoaderMode = Settings.LoaderMode; oldLoaderMode = Settings.LoaderMode;
oldGameCubeSource = Settings.GameCubeSource; oldGameCubeSource = Settings.GameCubeSource;
oldLoaderIOS = Settings.LoaderIOS;
} }
LoaderSettings::~LoaderSettings() LoaderSettings::~LoaderSettings()
@ -238,6 +240,12 @@ LoaderSettings::~LoaderSettings()
{ {
GCGames::Instance()->LoadAllGames(); GCGames::Instance()->LoadAllGames();
} }
if(oldLoaderIOS != Settings.LoaderIOS)
{
// edit meta.xml arguments
editMetaArguments();
}
} }
void LoaderSettings::SetOptionValues() void LoaderSettings::SetOptionValues()

View File

@ -37,6 +37,7 @@ class LoaderSettings : public SettingsMenu
short oldLoaderMode; short oldLoaderMode;
short oldGameCubeSource; short oldGameCubeSource;
short oldLoaderIOS;
OptionList GuiOptions; OptionList GuiOptions;
}; };

118
source/settings/meta.cpp Normal file
View File

@ -0,0 +1,118 @@
/*
Copyright (c) 2014 - Cyan
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "homebrewboot\HomebrewXML.h"
#include "FileOperations\fileops.h"
#include "settings\CSettings.h"
#include "svnrev.h"
int updateMetaXML (void)
{
HomebrewXML MetaXML;
char filepath[255];
snprintf(filepath, sizeof(filepath), "%s/meta.xml", Settings.update_path);
if(!MetaXML.LoadHomebrewXMLData(filepath))
return 0;
char line[50];
snprintf(line, sizeof(line), "--ios=%d", Settings.LoaderIOS);
MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--usbport=%d", Settings.USBPort);
MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "--mountusb=%d", Settings.USBAutoMount);
MetaXML.SetArgument(line);
snprintf(line, sizeof(line), "3.0 r%s", GetRev());
MetaXML.SetVersion(line);
int ret = MetaXML.SaveHomebrewXMLData(filepath);
return ret;
}
int editMetaArguments (void)
{
char metapath[255] = "";
char metatmppath[255] = "";
snprintf(metapath, sizeof(metapath), "%s/meta.xml", Settings.update_path);
snprintf(metatmppath, sizeof(metatmppath), "%s/meta.tmp", Settings.update_path);
FILE *source = fopen(metapath, "rb");
if(!source)
{
return 0;
}
FILE *destination = fopen(metatmppath, "wb");
if(!destination)
{
fclose(source);
return 0;
}
const int max_line_size = 255;
char *line = new char[max_line_size];
while (fgets(line, max_line_size, source) != NULL)
{
// delete commented lines
if( strstr(line, "<!-- // remove this line to enable arguments") != NULL ||
strstr(line, "// remove this line to enable arguments -->") != NULL)
{
strcpy(line, " \n");
}
// generate argurments
if(strstr(line, "<arguments>") != NULL)
{
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--ios=%d</arg>\n", Settings.LoaderIOS);
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--usbport=%d</arg>\n", Settings.USBPort);
fputs(line, destination);
snprintf(line, max_line_size, " <arg>--mountusb=%d</arg>\n", Settings.USBAutoMount);
fputs(line, destination);
while(strstr(line, "</arguments>") == NULL)
{
fgets(line, max_line_size, source); // advance one line
if(feof(source))
{
fclose(source);
fclose(destination);
delete [] line;
return 0;
}
}
}
fputs(line, destination);
}
fclose(source);
fclose(destination);
delete [] line;
if(CopyFile(metatmppath, metapath) <0)
return 0;
RemoveFile(metatmppath);
return 1;
}

30
source/settings/meta.h Normal file
View File

@ -0,0 +1,30 @@
/****************************************************************************
* Copyright (C) 2014
* by cyan
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _META_H_
#define _META_H_
int updateMetaXML(void);
int editMetaArguments(void);
#endif

View File

@ -10,6 +10,7 @@
#include "settings/CSettings.h" #include "settings/CSettings.h"
#include "settings/GameTitles.h" #include "settings/GameTitles.h"
#include "settings/newtitles.h" #include "settings/newtitles.h"
#include "settings/meta.h"
#include "language/gettext.h" #include "language/gettext.h"
#include "network/networkops.h" #include "network/networkops.h"
#include "utils/ResourceManager.h" #include "utils/ResourceManager.h"
@ -222,14 +223,40 @@ void Sys_LoadHBC(void)
bool RebootApp(void) bool RebootApp(void)
{ {
// be sure to use current settings as arguments
editMetaArguments();
#ifdef FULLCHANNEL #ifdef FULLCHANNEL
ExitApp(); ExitApp();
WII_Initialize(); WII_Initialize();
return !(WII_LaunchTitle(TITLE_ID(0x00010001, 0x554c4e52)) < 0); return !(WII_LaunchTitle(TITLE_ID(0x00010001, 0x554c4e52)) < 0);
#else #else
// Load meta.xml arguments
char filepath[255]; char filepath[255];
HomebrewXML MetaXML;
snprintf(filepath, sizeof(filepath), "%s/meta.xml", Settings.update_path);
MetaXML.LoadHomebrewXMLData(filepath);
u8 *buffer = NULL;
u32 filesize = 0;
snprintf(filepath, sizeof(filepath), "%s/boot.dol", Settings.update_path); snprintf(filepath, sizeof(filepath), "%s/boot.dol", Settings.update_path);
return !(BootHomebrew(filepath) < 0); LoadFileToMem(filepath, &buffer, &filesize);
if(!buffer)
{
return false;
}
FreeHomebrewBuffer();
CopyHomebrewMemory(buffer, 0, filesize);
AddBootArgument(filepath);
for(u32 i = 0; i < MetaXML.GetArguments().size(); ++i)
{
AddBootArgument(MetaXML.GetArguments().at(i).c_str());
}
return !(BootHomebrewFromMem() <0);
#endif #endif
} }

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2012-2013 Cyan * Copyright (C) 2012-2014 Cyan
* Copyright (C) 2011 Dimok * Copyright (C) 2011 Dimok
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -969,12 +969,6 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
return 0; return 0;
} }
if(gameHdr->type == TYPE_GAME_GC_EXTRACTED)
{
if(WindowPrompt(tr("Warning:"), fmt(tr("%s only accepts GameCube backups in ISO format."),LoaderName), tr("Continue"), tr("Cancel")) == 0)
return 0;
}
if(!CheckAHBPROT()) if(!CheckAHBPROT())
{ {
WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK")); WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK"));
@ -1047,7 +1041,8 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr)
{ {
// Get Nintendont version // Get Nintendont version
char NINversion[21]; char NINversion[21];
u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; // r39 only
if(buffer[i+17] == '\r') offset += 2; //v1.20+
for(int j = 0 ; j < 20 ; j++) for(int j = 0 ; j < 20 ; j++)
NINversion[j] = *(u8*)(buffer+i+offset+j); NINversion[j] = *(u8*)(buffer+i+offset+j);
NINversion[11] = ' '; // replace \0 between year and time with a space. NINversion[11] = ' '; // replace \0 between year and time with a space.

View File

@ -51,6 +51,7 @@ cat <<EOF > ./HBC/META.XML
<arguments> <arguments>
<arg>--ios=250</arg> <arg>--ios=250</arg>
<arg>--usbport=0</arg> <arg>--usbport=0</arg>
<arg>--mountusb=1</arg>
</arguments> </arguments>
// remove this line to enable arguments --> // remove this line to enable arguments -->
<ahb_access/> <ahb_access/>