*Added banner sounds for channels (emu and real nand)

*few cleanups
This commit is contained in:
strtoul 2011-11-13 09:09:27 +00:00
parent c51b2304c2
commit f307f60c00
19 changed files with 824 additions and 39 deletions

View File

@ -2,8 +2,8 @@
<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>2.3 r1128</version> <version>2.3 r1129</version>
<release_date>201111112324</release_date> <release_date>201111121818</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>
<arg>--ios=250</arg> <arg>--ios=250</arg>

18
source/Channels/chan_stub.s Executable file
View File

@ -0,0 +1,18 @@
#define STUB 0x3400
.text
.section .text
.globl _unstub_start
_unstub_start:
isync
// set MSR[DR:IR] = 00, jump to STUB
lis 3,STUB@h
ori 3,3,STUB@l
mtsrr0 3
mfmsr 3
li 4,0x30
andc 3,3,4
mtsrr1 3
rfi

673
source/Channels/channels.cpp Executable file
View File

@ -0,0 +1,673 @@
/***************************************************************************
* Copyright (C) 2010 by dude
* Copyright (C) 2011 by Miigotu
* Copyright (C) 2011 by Dimok
*
* 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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/dirent.h>
#include "FileOperations/fileops.h"
#include "Controls/DeviceHandler.hpp"
#include "settings/CSettings.h"
#include "settings/GameTitles.h"
#include "patches/gamepatches.h"
#include "wad/nandtitle.h"
#include "utils/lz77.h"
#include "gecko.h"
#include "channels.h"
typedef struct _dolheader{
u32 section_pos[18];
u32 section_start[18];
u32 section_size[18];
u32 bss_start;
u32 bss_size;
u32 entry_point;
u32 padding[7];
} __attribute__((packed)) dolheader;
Channels *Channels::instance = NULL;
void Channels::GetEmuChannelList()
{
EmuChannels.clear();
char filepath[1024];
int language = CONF_GetLanguage();
snprintf(filepath, sizeof(filepath), "%s/title/00010001", Settings.NandEmuChanPath);
ParseTitleDir(filepath, language);
snprintf(filepath, sizeof(filepath), "%s/title/00010004", Settings.NandEmuChanPath);
ParseTitleDir(filepath, language);
snprintf(filepath, sizeof(filepath), "%s/title/00010002", Settings.NandEmuChanPath);
ParseTitleDir(filepath, language);
}
void Channels::GetChannelList()
{
ISFS_Initialize();
NandChannels.clear();
// Get count of titles of the good titles
u32 num_titles = NandTitles.SetType(0x10001);
for (u32 i = 0; i < num_titles; i++)
{
u64 tid = NandTitles.Next();
if (!tid)
break;
//remove ones not actually installed on the nand
if (!NandTitles.Exists(tid))
continue;
char id[5];
NandTitles.AsciiTID(tid, id);
const char *name = GameTitles.GetTitle(id);
std::string TitleName;
if(!name || *name == '\0')
{
name = NandTitles.NameOf(tid);
// Set title for caching
if(name)
GameTitles.SetGameTitle(id, name);
}
int s = NandChannels.size();
NandChannels.resize(s + 1);
memset(&NandChannels[s], 0, sizeof(struct discHdr));
memcpy(NandChannels[s].id, id, 4);
NandChannels[s].tid = tid;
strncpy(NandChannels[s].title, name ? name : "", sizeof(NandChannels[s].title)-1);
}
// Get count of system titles
num_titles = NandTitles.SetType(0x10002);
for (u32 i = 0; i < num_titles; i++)
{
u64 tid = NandTitles.Next();
if (!tid)
break;
//these can't be booted anyways
if (TITLE_LOWER( tid ) == 0x48414741 || TITLE_LOWER( tid ) == 0x48414141 || TITLE_LOWER( tid ) == 0x48414641)
continue;
//these aren't installed on the nand
if (!NandTitles.Exists(tid))
continue;
char id[5];
NandTitles.AsciiTID(tid, id);
const char *name = GameTitles.GetTitle(id);
std::string TitleName;
if(!name || *name == '\0')
{
name = NandTitles.NameOf(tid);
// Set title for caching
if(name)
GameTitles.SetGameTitle(id, name);
}
int s = NandChannels.size();
NandChannels.resize(s + 1);
memset(&NandChannels[s], 0, sizeof(struct discHdr));
memcpy(NandChannels[s].id, id, 4);
NandChannels[s].tid = tid;
strncpy(NandChannels[s].title, name ? name : "", sizeof(NandChannels[s].title)-1);
}
ISFS_Deinitialize();
}
vector<struct discHdr> & Channels::GetDiscHeaderList(void)
{
if(Settings.NandEmuChanMode != 0)
{
if(EmuChannels.empty())
this->GetEmuChannelList();
return EmuChannels;
}
else
{
if(NandChannels.empty())
this->GetChannelList();
return NandChannels;
}
}
u8 * Channels::GetDol(u64 title)
{
char *filepath = (char *) memalign(32, ISFS_MAXPATH);
if(!filepath)
return NULL;
u32 bootcontent;
u32 high = TITLE_UPPER(title);
u32 low = TITLE_LOWER(title);
snprintf(filepath, ISFS_MAXPATH, "/title/%08x/%08x/content/title.tmd", high, low);
u8 *buffer = NULL;
u32 filesize = 0;
if (NandTitle::LoadFileFromNand(filepath, &buffer, &filesize, false) < 0)
{
free(filepath);
return NULL;
}
_tmd * tmd_file = (_tmd *) SIGNATURE_PAYLOAD((u32 *)buffer);
bool found = false;
for(u32 i = 0; i < tmd_file->num_contents; ++i)
{
if(tmd_file->contents[i].index == tmd_file->boot_index)
{
bootcontent = tmd_file->contents[i].cid;
found = true;
break;
}
}
free(buffer);
buffer = NULL;
filesize = 0;
if(!found)
{
free(filepath);
return NULL;
}
snprintf(filepath, ISFS_MAXPATH, "/title/%08x/%08x/content/%08x.app", high, low, bootcontent);
gprintf("Loading Channel DOL: %s\n", filepath);
if (NandTitle::LoadFileFromNand(filepath, &buffer, &filesize, false) < 0)
{
gprintf("Failed loading DOL file\n");
free(filepath);
return NULL;
}
free(filepath);
if (isLZ77compressed(buffer))
{
u8 *decompressed = NULL;
u32 size = 0;
if (decompressLZ77content(buffer, filesize, &decompressed, &size) < 0)
{
gprintf("Decompression failed\n");
free(buffer);
return NULL;
}
free(buffer);
buffer = decompressed;
filesize = size;
}
return buffer;
}
u8 Channels::GetRequestedIOS(u64 title)
{
u8 IOS = 0;
char *filepath = (char *) memalign(32, ISFS_MAXPATH);
if(!filepath)
return 0;
snprintf(filepath, ISFS_MAXPATH, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(title), TITLE_LOWER(title));
u8 *titleTMD = NULL;
u32 filesize = 0;
if (NandTitle::LoadFileFromNand(filepath, &titleTMD, &filesize, false) < 0)
{
free(filepath);
return 0;
}
if(filesize > 0x18B)
IOS = titleTMD[0x18B];
free(titleTMD);
free(filepath);
return IOS;
}
u32 Channels::LoadChannel(u64 chantitle)
{
ISFS_Initialize();
u8 *chanDOL = GetDol(chantitle);
if(!chanDOL)
return 0;
u32 ios = 0;
Identify(chantitle, &ios);
dolheader *dolfile = (dolheader *)chanDOL;
if(dolfile->bss_start)
{
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
}
int i;
for(i = 0; i < 18; i++)
{
if (!dolfile->section_size[i]) continue;
if (dolfile->section_pos[i] < sizeof(dolheader)) continue;
if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000;
u8 *dolChunkOffset = (u8 *)dolfile->section_start[i];
u32 dolChunkSize = dolfile->section_size[i];
ICInvalidateRange(dolChunkOffset, dolChunkSize);
memmove (dolChunkOffset, chanDOL + dolfile->section_pos[i], dolChunkSize);
DCFlushRange(dolChunkOffset, dolChunkSize);
RegisterDOL(dolChunkOffset, dolChunkSize);
}
u32 chanEntryPoint = dolfile->entry_point;
// IOS Version Check
*(vu32*)0x80003140 = ((ios << 16)) | 0xFFFF;
*(vu32*)0x80003188 = ((ios << 16)) | 0xFFFF;
DCFlushRange((void *)0x80003140, 32);
DCFlushRange((void *)0x80003188, 32);
// Game ID Online Check
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
*(vu32 *)0x80003180 = TITLE_LOWER(chantitle);
DCFlushRange((void *)0x80000000, 32);
DCFlushRange((void *)0x80003180, 32);
ISFS_Deinitialize();
return chanEntryPoint;
}
static bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
{
signed_blob *buffer = (signed_blob *)memalign(32, STD_SIGNED_TIK_SIZE);
if (!buffer) return false;
memset(buffer, 0, STD_SIGNED_TIK_SIZE);
sig_rsa2048 *signature = (sig_rsa2048 *)buffer;
signature->type = ES_SIG_RSA2048;
tik *tik_data = (tik *)SIGNATURE_PAYLOAD(buffer);
strcpy(tik_data->issuer, "Root-CA00000001-XS00000003");
memset(tik_data->cidx_mask, 0xFF, 32);
*outbuf = buffer;
*outlen = STD_SIGNED_TIK_SIZE;
return true;
}
bool Channels::Identify(u64 titleid, u32 *ios)
{
char *filepath = (char *) memalign(32, ISFS_MAXPATH);
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
u8 *tmdBuffer = NULL;
u32 tmdSize = 0;
if (NandTitle::LoadFileFromNand(filepath, &tmdBuffer, &tmdSize, false) < 0)
{
free(filepath);
gprintf("Reading TMD...Failed!\n");
return false;
}
*ios = (u32)(tmdBuffer[0x18b]);
u32 tikSize;
signed_blob *tikBuffer = NULL;
if(!Identify_GenerateTik(&tikBuffer,&tikSize))
{
free(tmdBuffer);
free(filepath);
gprintf("Generating fake ticket...Failed!");
return false;
}
sprintf(filepath, "/sys/cert.sys");
u8 *certBuffer = NULL;
u32 certSize = 0;
if (NandTitle::LoadFileFromNand(filepath, &certBuffer, &certSize, false) < 0)
{
gprintf("Reading certs...Failed!\n");
free(tmdBuffer);
free(tikBuffer);
free(filepath);
return false;
}
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL);
if (ret < 0)
{
switch(ret)
{
case ES_EINVAL:
gprintf("Error! ES_Identify (ret = %d;) Data invalid!\n", ret);
break;
case ES_EALIGN:
gprintf("Error! ES_Identify (ret = %d;) Data not aligned!\n", ret);
break;
case ES_ENOTINIT:
gprintf("Error! ES_Identify (ret = %d;) ES not initialized!\n", ret);
break;
case ES_ENOMEM:
gprintf("Error! ES_Identify (ret = %d;) No memory!\n", ret);
break;
default:
gprintf("Error! ES_Identify (ret = %d)\n", ret);
break;
}
}
free(tmdBuffer);
free(tikBuffer);
free(filepath);
free(certBuffer);
return ret < 0 ? false : true;
}
bool Channels::ParseTitleDir(char *path, int language)
{
if(!path)
return false;
const char *tidPtr = strrchr(path, '/');
if(!tidPtr)
return false;
else
tidPtr++;
struct dirent *dirent = NULL;
DIR *dir = opendir(path);
if(!dir)
return false;
char *pathEndPtr = path + strlen(path);
u32 tidHigh = strtoul(tidPtr, NULL, 16);
struct stat st;
while ((dirent = readdir(dir)) != 0)
{
if(!dirent->d_name)
continue;
//these can't be booted anyways
if(*dirent->d_name == '.' || strcmp(dirent->d_name, "48414141") == 0 || strcmp(dirent->d_name, "48414641") == 0)
{
continue;
}
snprintf(pathEndPtr, 1024-(pathEndPtr-path), "/%s/content/title.tmd", dirent->d_name);
if(stat(path, &st) != 0)
continue;
u32 tidLow = strtoul(dirent->d_name, NULL, 16);
char id[5];
memset(id, 0, sizeof(id));
memcpy(id, &tidLow, 4);
u64 tid = ((u64)tidHigh << 32) | ((u64) tidLow);
// Force old and new format to be "JODI" which is known by GameTDB
if(tid == 0x00010001AF1BF516LL || tid == 0x0001000148415858LL)
strcpy(id, "JODI");
std::string TitleName;
const char *title = GameTitles.GetTitle(id);
if(title && *title != '\0')
{
TitleName = title;
}
else if(GetEmuChanTitle(path, language, TitleName))
{
GameTitles.SetGameTitle(id, TitleName.c_str());
}
else
{
TitleName = id;
}
int s = EmuChannels.size();
EmuChannels.resize(s + 1);
memset(&EmuChannels[s], 0, sizeof(struct discHdr));
memcpy(EmuChannels[s].id, id, 4);
EmuChannels[s].tid = tid;
strncpy(EmuChannels[s].title, TitleName.c_str(), sizeof(EmuChannels[s].title)-1);
}
closedir(dir);
return true;
}
bool Channels::GetEmuChanTitle(char *tmdpath, int language, std::string &Title)
{
u8 *buffer = NULL;
u32 size = 0;
if(LoadFileToMem(tmdpath, &buffer, &size) < 0)
return false;
signed_blob *s_tmd = (signed_blob *) buffer;
u32 i;
tmd *titleTmd = (tmd *) SIGNATURE_PAYLOAD(s_tmd);
for (i = 0; i < titleTmd->num_contents; i++)
if (!titleTmd->contents[i].index)
break;
if(i == titleTmd->num_contents)
{
free(buffer);
return false;
}
u32 cid = titleTmd->contents[i].cid;
free(buffer);
char *ptr = strrchr(tmdpath, '/');
if(!ptr)
return false;
sprintf(ptr+1, "%08x.app", cid);
FILE *f = fopen(tmdpath, "rb");
if(!f)
return false;
if(fseek(f, IMET_OFFSET, SEEK_SET) != 0)
{
fclose(f);
return false;
}
IMET *imet = (IMET*) malloc(sizeof(IMET));
if(!imet)
{
fclose(f);
return false;
}
if(fread(imet, 1, sizeof(IMET), f) != sizeof(IMET))
{
free(imet);
fclose(f);
return false;
}
fclose(f);
if (imet->sig != IMET_SIGNATURE)
{
free(imet);
return false;
}
// names not available
if (imet->name_japanese[language * IMET_MAX_NAME_LEN] == 0)
{
if(imet->name_english[0] != 0)
language = CONF_LANG_ENGLISH;
else
{
free(imet);
return false;
}
}
wchar_t wName[IMET_MAX_NAME_LEN];
// retrieve channel name in system language or on english
for (int i = 0; i < IMET_MAX_NAME_LEN; i++)
wName[i] = imet->name_japanese[i + (language * IMET_MAX_NAME_LEN)];
wString wsname(wName);
Title = wsname.toUTF8();
free(imet);
return true;
}
u8 *Channels::GetOpeningBnr(u64 title)
{
u8 *banner = NULL;
u32 high = TITLE_UPPER(title);
u32 low = TITLE_LOWER(title);
char *filepath = (char *) memalign(32, ISFS_MAXPATH);
if(!filepath)
return NULL;
if(Settings.NandEmuChanMode == 0)
ISFS_Initialize();
char prefix[sizeof(Settings.NandEmuChanPath)];
if(Settings.NandEmuChanMode != 0)
strcpy(prefix, Settings.NandEmuChanPath);
else
prefix[0] = '\0';
do
{
snprintf(filepath, ISFS_MAXPATH, "%s/title/%08x/%08x/content/title.tmd", prefix, high, low);
u8 *buffer = NULL;
u32 filesize = 0;
int ret = 0;
if(Settings.NandEmuChanMode != 0)
ret = LoadFileToMem(filepath, &buffer, &filesize);
else
ret = NandTitle::LoadFileFromNand(filepath, &buffer, &filesize, false);
if (ret < 0)
break;
_tmd * tmd_file = (_tmd *) SIGNATURE_PAYLOAD((u32 *)buffer);
bool found = false;
u32 bootcontent = 0;
for(u32 i = 0; i < tmd_file->num_contents; ++i)
{
if(tmd_file->contents[i].index == 0)
{
bootcontent = tmd_file->contents[i].cid;
found = true;
break;
}
}
free(buffer);
buffer = NULL;
filesize = 0;
if(!found)
break;
snprintf(filepath, ISFS_MAXPATH, "%s/title/%08x/%08x/content/%08x.app", prefix, high, low, bootcontent);
if(Settings.NandEmuChanMode != 0)
ret = LoadFileToMem(filepath, &buffer, &filesize);
else
ret = NandTitle::LoadFileFromNand(filepath, &buffer, &filesize, false);
if (ret < 0)
break;
IMET *imet = (IMET *) (buffer + IMET_OFFSET);
if(imet->sig != 'IMET')
{
free(buffer);
break;
}
banner = (u8 *) memalign(32, filesize-IMET_OFFSET);
if(!banner)
{
free(buffer);
break;
}
memcpy(banner, buffer + IMET_OFFSET, filesize-IMET_OFFSET);
free(buffer);
}
while(0);
free(filepath);
if(Settings.NandEmuChanMode == 0)
ISFS_Deinitialize();
return banner;
}

61
source/Channels/channels.h Executable file
View File

@ -0,0 +1,61 @@
/***************************************************************************
* Copyright (C) 2010 by dude
* Copyright (C) 2011 by Miigotu
* Copyright (C) 2011 by Dimok
*
* 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 _CHANNELS_H_
#define _CHANNELS_H_
#include <string>
#include <vector>
#include <gccore.h>
#include "usbloader/disc.h"
using namespace std;
class Channels
{
public:
static Channels *Instance(void) { if(!instance) instance = new Channels(); return instance; }
static void DestroyInstance(void) { if(instance) delete instance; instance = NULL; }
static u32 LoadChannel(u64 chantitle);
static u8 GetRequestedIOS(u64 title);
static u8 *GetDol(u64 title);
static u8 *GetOpeningBnr(u64 title);
void GetChannelList();
void GetEmuChannelList();
vector<struct discHdr> & GetDiscHeaderList(void);
private:
static Channels *instance;
static bool Identify(u64 titleid, u32 *ios);
bool ParseTitleDir(char *path, int language);
bool GetEmuChanTitle(char *tmdpath, int language, std::string &Title);
vector<struct discHdr> NandChannels;
vector<struct discHdr> EmuChannels;
};
#endif

View File

@ -93,7 +93,7 @@ extern "C" u64 FileSize(const char * filepath)
* *
* Load up the file into a block of memory * Load up the file into a block of memory
***************************************************************************/ ***************************************************************************/
extern "C" int LoadFileToMem(const char *filepath, u8 **inbuffer, u64 *size) extern "C" int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
{ {
int ret = -1; int ret = -1;
u64 filesize = FileSize(filepath); u64 filesize = FileSize(filepath);
@ -168,7 +168,7 @@ extern "C" int LoadFileToMem(const char *filepath, u8 **inbuffer, u64 *size)
* *
* Load up the file into a block of memory, while showing a progress dialog * Load up the file into a block of memory, while showing a progress dialog
***************************************************************************/ ***************************************************************************/
extern "C" int LoadFileToMemWithProgress(const char *progressText, const char *filepath, u8 **inbuffer, u64 *size) extern "C" int LoadFileToMemWithProgress(const char *progressText, const char *filepath, u8 **inbuffer, u32 *size)
{ {
int ret = LoadFileToMem(filepath, inbuffer, size); int ret = LoadFileToMem(filepath, inbuffer, size);

View File

@ -37,8 +37,8 @@ extern "C" {
bool CreateSubfolder(const char * fullpath); bool CreateSubfolder(const char * fullpath);
bool CheckFile(const char * filepath); bool CheckFile(const char * filepath);
u64 FileSize(const char * filepath); u64 FileSize(const char * filepath);
int LoadFileToMem(const char * filepath, u8 **buffer, u64 *size); int LoadFileToMem(const char * filepath, u8 **buffer, u32 *size);
int LoadFileToMemWithProgress(const char *progressText, const char *filePath, u8 **buffer, u64 *size); int LoadFileToMemWithProgress(const char *progressText, const char *filePath, u8 **buffer, u32 *size);
int CopyFile(const char * src, const char * dest); int CopyFile(const char * src, const char * dest);
int MoveFile(const char *srcpath, char *destdir); int MoveFile(const char *srcpath, char *destdir);
bool RenameFile(const char * srcpath, const char * destpath); bool RenameFile(const char * srcpath, const char * destpath);

View File

@ -42,7 +42,7 @@ GuiImageData::GuiImageData(const char * filepath)
format = GX_TF_RGBA8; format = GX_TF_RGBA8;
u8 *buffer = NULL; u8 *buffer = NULL;
u64 size = 0; u32 size = 0;
if(LoadFileToMem(filepath, &buffer, &size) < 0) if(LoadFileToMem(filepath, &buffer, &size) < 0)
return; return;

View File

@ -38,7 +38,7 @@ TplImage::TplImage(const char * filepath)
TPLSize = 0; TPLSize = 0;
u8 * buffer = NULL; u8 * buffer = NULL;
u64 filesize = 0; u32 filesize = 0;
LoadFileToMem(filepath, &buffer, &filesize); LoadFileToMem(filepath, &buffer, &filesize);
if(buffer) if(buffer)

View File

@ -151,7 +151,7 @@ bool GuiSound::Load(const char * filepath)
if(magic == 'IMD5') if(magic == 'IMD5')
{ {
u8 * snd = NULL; u8 * snd = NULL;
u64 filesize = 0; u32 filesize = 0;
LoadFileToMem(filepath, &snd, &filesize); LoadFileToMem(filepath, &snd, &filesize);
return Load(snd, filesize, true); return Load(snd, filesize, true);
} }

View File

@ -1,5 +1,6 @@
#include <malloc.h> #include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include "Channels/channels.h"
#include "usbloader/disc.h" #include "usbloader/disc.h"
#include "usbloader/wbfs.h" #include "usbloader/wbfs.h"
#include "utils/uncompress.h" #include "utils/uncompress.h"
@ -19,6 +20,39 @@ OpeningBNR::~OpeningBNR()
free(imetHdr); free(imetHdr);
} }
bool OpeningBNR::Load(const u64 &tid)
{
if(tid == 0)
return false;
u32 tidLow = (u32) (tid & 0xFFFFFFFF);
char id[6];
memset(id, 0, sizeof(id));
memcpy(id, &tidLow, 4);
if(memcmp(gameID, id, 6) == 0)
return true;
memcpy(gameID, id, 6);
if(imetHdr)
free(imetHdr);
imetHdr = NULL;
imetHdr = (IMETHeader*) Channels::GetOpeningBnr(tid);
if(!imetHdr)
return false;
if (imetHdr->fcc != 'IMET')
{
free(imetHdr);
imetHdr = NULL;
return false;
}
return true;
}
bool OpeningBNR::Load(const u8 * discid) bool OpeningBNR::Load(const u8 * discid)
{ {
if(!discid) if(!discid)
@ -27,10 +61,11 @@ bool OpeningBNR::Load(const u8 * discid)
if(memcmp(gameID, discid, 6) == 0) if(memcmp(gameID, discid, 6) == 0)
return true; return true;
memcpy(gameID, discid, 6);
if(imetHdr) if(imetHdr)
free(imetHdr); free(imetHdr);
imetHdr = NULL; imetHdr = NULL;
snprintf(gameID, sizeof(gameID), (const char *) discid);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) gameID); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) gameID);
if (!disc) if (!disc)

View File

@ -61,10 +61,12 @@ class OpeningBNR
OpeningBNR(); OpeningBNR();
~OpeningBNR(); ~OpeningBNR();
bool Load(const u8 * gameID); bool Load(const u8 * gameID);
bool Load(const u64 &tid);
const u16 * GetIMETTitle(int lang); const u16 * GetIMETTitle(int lang);
const u16 * GetIMETTitle(const u8 * gameID, int lang) { Load(gameID); return GetIMETTitle(lang); }; const u16 * GetIMETTitle(const u8 * gameID, int lang) { Load(gameID); return GetIMETTitle(lang); };
const u8 * GetBannerSound(u32 * size); const u8 * GetBannerSound(u32 * size);
const u8 * GetBannerSound(const u8 * gameID, u32 * size) { Load(gameID); return GetBannerSound(size); }; const u8 * GetBannerSound(const u8 * gameID, u32 * size) { Load(gameID); return GetBannerSound(size); };
const u8 * GetBannerSound(const u64 &tid, u32 * size) { Load(tid); return GetBannerSound(size); };
private: private:
IMETHeader *imetHdr; IMETHeader *imetHdr;
char gameID[7]; char gameID[7];

View File

@ -139,37 +139,24 @@ static int RunAppbooter()
int BootHomebrew(const char * filepath) int BootHomebrew(const char * filepath)
{ {
void *buffer = NULL;
u32 filesize = 0;
FILE *file = fopen(filepath, "rb"); FILE *file = fopen(filepath, "rb");
if (!file) return -1; if (!file) return -1;
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
filesize = ftell(file); u32 filesize = ftell(file);
rewind(file); rewind(file);
buffer = malloc(filesize); if (fread(homebrewbuffer, 1, filesize, file) != filesize)
if (fread(buffer, 1, filesize, file) != filesize)
{ {
fclose(file); fclose(file);
free(buffer);
DeviceHandler::DestroyInstance(); DeviceHandler::DestroyInstance();
Sys_BackToLoader(); Sys_BackToLoader();
} }
homebrewsize = filesize;
fclose(file); fclose(file);
CopyHomebrewMemory((u8*) buffer, 0, filesize);
if (buffer)
{
free(buffer);
buffer = NULL;
}
AddBootArgument(filepath); AddBootArgument(filepath);
return RunAppbooter(); return RunAppbooter();
} }

View File

@ -307,7 +307,7 @@ void HomebrewBrowser::MainButtonClicked(int button)
if (choice == 1) if (choice == 1)
{ {
u8 *buffer = NULL; u8 *buffer = NULL;
u64 filesize = 0; u32 filesize = 0;
LoadFileToMem(HomebrewList->GetFilepath(button), &buffer, &filesize); LoadFileToMem(HomebrewList->GetFilepath(button), &buffer, &filesize);
if(!buffer) if(!buffer)
{ {

View File

@ -269,7 +269,7 @@ GameWindow::~GameWindow()
ResumeGui(); ResumeGui();
} }
void GameWindow::LoadGameSound(const u8 * id) void GameWindow::LoadGameSound(const struct discHdr * header)
{ {
if (Settings.gamesoundvolume == 0) if (Settings.gamesoundvolume == 0)
return; return;
@ -282,7 +282,15 @@ void GameWindow::LoadGameSound(const u8 * id)
} }
u32 gameSoundDataLen; u32 gameSoundDataLen;
const u8 *gameSoundData = BNRInstance::Instance()->GetBannerSound(id, &gameSoundDataLen); const u8 *gameSoundData = NULL;
if(Settings.LoaderMode != LOAD_CHANNELS)
gameSoundData = BNRInstance::Instance()->GetBannerSound(header->id, &gameSoundDataLen);
else
{
gameSoundData = BNRInstance::Instance()->GetBannerSound(header->tid, &gameSoundDataLen);
}
if (gameSoundData) if (gameSoundData)
{ {
gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, true); gameSound = new GuiSound(gameSoundData, gameSoundDataLen, Settings.gamesoundvolume, true);
@ -412,8 +420,7 @@ void GameWindow::SetWindowEffect(int direction, int in_out)
void GameWindow::ChangeGame(int EffectDirection) void GameWindow::ChangeGame(int EffectDirection)
{ {
struct discHdr * header = (mountMethod ? dvdheader : gameList[gameSelected]); struct discHdr * header = (mountMethod ? dvdheader : gameList[gameSelected]);
if(Settings.LoaderMode != LOAD_CHANNELS) LoadGameSound(header);
LoadGameSound(header->id); // Temporary no sounds for channels, will be added later
LoadDiscImage(header->id); LoadDiscImage(header->id);
SetWindowEffect(EffectDirection, OUT); SetWindowEffect(EffectDirection, OUT);

View File

@ -4,6 +4,7 @@
#include "GUI/gui.h" #include "GUI/gui.h"
#include "GUI/gui_diskcover.h" #include "GUI/gui_diskcover.h"
#include "menu/GameBrowseMenu.hpp" #include "menu/GameBrowseMenu.hpp"
#include "usbloader/disc.h"
#define FAVORITE_STARS 5 #define FAVORITE_STARS 5
@ -17,7 +18,7 @@ class GameWindow : public GuiWindow
void SetGameBrowseMenu(GameBrowseMenu *m) { browserMenu = m; }; void SetGameBrowseMenu(GameBrowseMenu *m) { browserMenu = m; };
protected: protected:
int MainLoop(); int MainLoop();
void LoadGameSound(const u8 * id); void LoadGameSound(const struct discHdr * header);
void LoadDiscImage(const u8 * id); void LoadDiscImage(const u8 * id);
void SetWindowEffect(int direction, int in_out); void SetWindowEffect(int direction, int in_out);
void ChangeGame(int EffectDirection); void ChangeGame(int EffectDirection);

View File

@ -36,7 +36,7 @@ bool Resources::LoadFiles(const char * path)
if(CheckFile(fullpath)) if(CheckFile(fullpath))
{ {
u8 * buffer = NULL; u8 * buffer = NULL;
u64 filesize = 0; u32 filesize = 0;
LoadFileToMem(fullpath, &buffer, &filesize); LoadFileToMem(fullpath, &buffer, &filesize);

View File

@ -196,7 +196,7 @@ void ThemeMenu::SetupMainButtons()
for(int i = 0; i < ThemeDir.GetFilecount(); ++i) for(int i = 0; i < ThemeDir.GetFilecount(); ++i)
{ {
u8 *buffer = NULL; u8 *buffer = NULL;
u64 filesize; u32 filesize;
gprintf("%i %s\n", i, ThemeDir.GetFilepath(i)); gprintf("%i %s\n", i, ThemeDir.GetFilepath(i));
LoadFileToMem(ThemeDir.GetFilepath(i), &buffer, &filesize); LoadFileToMem(ThemeDir.GetFilepath(i), &buffer, &filesize);

View File

@ -328,9 +328,7 @@ int GameBooter::BootGame(const char * gameID)
/* Setup video mode */ /* Setup video mode */
Disc_SelectVMode(videoChoice); Disc_SelectVMode(videoChoice);
// Load dol // Load dol
u64 tid; AppEntrypoint = Channels::LoadChannel(gameHeader.tid);
memcpy(&tid, gameHeader.tid, 8);
AppEntrypoint = Channels::LoadChannel(tid);
} }
//! No entrypoint found...back to HBC/SystemMenu //! No entrypoint found...back to HBC/SystemMenu

View File

@ -25,7 +25,10 @@ extern "C"
u8 is_ciso; u8 is_ciso;
/* Unused, on channel list mode this is the full 64 bit tid and zeros */ /* Unused, on channel list mode this is the full 64 bit tid and zeros */
u8 tid[13]; u64 tid;
/* rest of unused */
u8 unused[5];
/* Magic word */ /* Magic word */
u32 magic; u32 magic;