mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
*Added banner sounds for channels (emu and real nand)
*few cleanups
This commit is contained in:
parent
c51b2304c2
commit
f307f60c00
@ -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
18
source/Channels/chan_stub.s
Executable 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
673
source/Channels/channels.cpp
Executable 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
61
source/Channels/channels.h
Executable 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
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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];
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user