mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-27 13:44:15 +01:00
-WIP moved code to load channels into external game booter
This commit is contained in:
parent
f1767d5082
commit
e229aca6a5
Binary file not shown.
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 77 KiB |
@ -82,7 +82,7 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
|
||||
|
||||
free_wip();
|
||||
if(hooktype != 0 && hookpatched)
|
||||
ocarina_do_code();
|
||||
ocarina_do_code(0);
|
||||
|
||||
/* Set entry point from apploader */
|
||||
*entry = appldr_final();
|
||||
|
48
resources/wiiflow_game_booter/source/fs.c
Normal file
48
resources/wiiflow_game_booter/source/fs.c
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
#include <ogcsys.h>
|
||||
#include <locale.h>
|
||||
#include <malloc.h>
|
||||
#include <ogc/isfs.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "utils.h"
|
||||
|
||||
static fstats stats ATTRIBUTE_ALIGN(32);
|
||||
|
||||
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length)
|
||||
{
|
||||
*size = 0;
|
||||
|
||||
s32 fd = ISFS_Open((const char *)path, ISFS_OPEN_READ);
|
||||
u8 *buf = NULL;
|
||||
|
||||
if(fd >= 0)
|
||||
{
|
||||
memset(&stats, 0, sizeof(fstats));
|
||||
if(ISFS_GetFileStats(fd, &stats) >= 0)
|
||||
{
|
||||
if(length <= 0)
|
||||
length = stats.file_length;
|
||||
if(length > 0)
|
||||
buf = (u8 *)memalign(32, ALIGN32(length));
|
||||
if(buf)
|
||||
{
|
||||
*size = stats.file_length;
|
||||
if(ISFS_Read(fd, (char*)buf, length) != length)
|
||||
{
|
||||
*size = 0;
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
ISFS_Close(fd);
|
||||
}
|
||||
|
||||
if(*size > 0)
|
||||
{
|
||||
DCFlushRange(buf, *size);
|
||||
ICInvalidateRange(buf, *size);
|
||||
}
|
||||
return buf;
|
||||
}
|
15
resources/wiiflow_game_booter/source/fs.h
Normal file
15
resources/wiiflow_game_booter/source/fs.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _FS_H_
|
||||
#define _FS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ extern u8 debuggerselect;
|
||||
|
||||
void app_gameconfig_set(u32 *gameconfig, u32 tempgameconfsize);
|
||||
void ocarina_set_codes(void *list, u8 *listend, u8 *cheats, u32 cheatSize);
|
||||
int ocarina_do_code();
|
||||
int ocarina_do_code(u64 chantitle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
215
resources/wiiflow_game_booter/source/lz77.c
Normal file
215
resources/wiiflow_game_booter/source/lz77.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*******************************************************************************
|
||||
* lz77.c
|
||||
*
|
||||
* Copyright (c) 2009 The Lemon Man
|
||||
* Copyright (c) 2009 Nicksasa
|
||||
* Copyright (c) 2009 WiiPower
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License (v2)
|
||||
* See http://www.gnu.org/licenses/gpl-2.0.txt for more info.
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "lz77.h"
|
||||
#include "utils.h"
|
||||
|
||||
u32 packBytes(int a, int b, int c, int d)
|
||||
{
|
||||
return (d << 24) | (c << 16) | (b << 8) | (a);
|
||||
}
|
||||
|
||||
s32 __decompressLZ77_11(u8 *in, u32 inputLen, u8 **output, u32 *outputLen)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
u8 *out = NULL;
|
||||
|
||||
u32 compressedPos = 0x4;
|
||||
u32 decompressedPos = 0x0;
|
||||
u32 decompressedSize = 0;
|
||||
|
||||
decompressedSize = packBytes(in[0], in[1], in[2], in[3]) >> 8;
|
||||
|
||||
if (!decompressedSize)
|
||||
{
|
||||
decompressedSize = packBytes(in[4], in[5], in[6], in[7]);
|
||||
compressedPos += 0x4;
|
||||
}
|
||||
|
||||
//printf("Decompressed size : %i\n", decompressedSize);
|
||||
|
||||
out = malloc(ALIGN32(decompressedSize));
|
||||
if (out == NULL)
|
||||
{
|
||||
printf("Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (compressedPos < inputLen && decompressedPos < decompressedSize)
|
||||
{
|
||||
u8 byteFlag = in[compressedPos];
|
||||
compressedPos++;
|
||||
|
||||
for (x = 7; x >= 0; x--)
|
||||
{
|
||||
if ((byteFlag & (1 << x)) > 0)
|
||||
{
|
||||
u8 first = in[compressedPos];
|
||||
u8 second = in[compressedPos + 1];
|
||||
|
||||
u32 pos, copyLen;
|
||||
|
||||
if (first < 0x20)
|
||||
{
|
||||
u8 third = in[compressedPos + 2];
|
||||
|
||||
if (first >= 0x10)
|
||||
{
|
||||
u32 fourth = in[compressedPos + 3];
|
||||
|
||||
pos = (u32)(((third & 0xF) << 8) | fourth) + 1;
|
||||
copyLen = (u32)((second << 4) | ((first & 0xF) << 12) | (third >> 4)) + 273;
|
||||
|
||||
compressedPos += 4;
|
||||
} else
|
||||
{
|
||||
pos = (u32)(((second & 0xF) << 8) | third) + 1;
|
||||
copyLen = (u32)(((first & 0xF) << 4) | (second >> 4)) + 17;
|
||||
|
||||
compressedPos += 3;
|
||||
}
|
||||
} else
|
||||
{
|
||||
pos = (u32)(((first & 0xF) << 8) | second) + 1;
|
||||
copyLen = (u32)(first >> 4) + 1;
|
||||
|
||||
compressedPos += 2;
|
||||
}
|
||||
|
||||
for (y = 0; y < (int)copyLen; y++)
|
||||
{
|
||||
out[decompressedPos + y] = out[decompressedPos - pos + y];
|
||||
}
|
||||
|
||||
decompressedPos += copyLen;
|
||||
} else
|
||||
{
|
||||
out[decompressedPos] = in[compressedPos];
|
||||
|
||||
decompressedPos++;
|
||||
compressedPos++;
|
||||
}
|
||||
|
||||
if (compressedPos >= inputLen || decompressedPos >= decompressedSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*output = out;
|
||||
*outputLen = decompressedSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 __decompressLZ77_10(u8 *in, u8 **output, u32 *outputLen)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
u8 *out = NULL;
|
||||
|
||||
u32 compressedPos = 0;
|
||||
u32 decompressedSize = 0x4;
|
||||
u32 decompressedPos = 0;
|
||||
|
||||
decompressedSize = packBytes(in[0], in[1], in[2], in[3]) >> 8;
|
||||
|
||||
//int compressionType = (packBytes(in[0], in[1], in[2], in[3]) >> 4) & 0xF;
|
||||
|
||||
//printf("Decompressed size : %i\n", decompressedSize);
|
||||
|
||||
out = malloc(ALIGN32(decompressedSize));
|
||||
if (out == NULL)
|
||||
{
|
||||
printf("Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
compressedPos += 0x4;
|
||||
|
||||
while (decompressedPos < decompressedSize)
|
||||
{
|
||||
u8 flag = *(u8*)(in + compressedPos);
|
||||
compressedPos += 1;
|
||||
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
if (flag & 0x80)
|
||||
{
|
||||
u8 first = in[compressedPos];
|
||||
u8 second = in[compressedPos + 1];
|
||||
|
||||
u16 pos = (u16)((((first << 8) + second) & 0xFFF) + 1);
|
||||
u8 copyLen = (u8)(3 + ((first >> 4) & 0xF));
|
||||
|
||||
for (y = 0; y < copyLen; y++)
|
||||
{
|
||||
out[decompressedPos + y] = out[decompressedPos - pos + (y % pos)];
|
||||
}
|
||||
|
||||
compressedPos += 2;
|
||||
decompressedPos += copyLen;
|
||||
} else
|
||||
{
|
||||
out[decompressedPos] = in[compressedPos];
|
||||
compressedPos += 1;
|
||||
decompressedPos += 1;
|
||||
}
|
||||
|
||||
flag <<= 1;
|
||||
|
||||
if (decompressedPos >= decompressedSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*output = out;
|
||||
*outputLen = decompressedSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isLZ77compressed(u8 *buffer)
|
||||
{
|
||||
if ((buffer[0] == LZ77_0x10_FLAG) || (buffer[0] == LZ77_0x11_FLAG))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decompressLZ77content(u8 *buffer, u32 length, u8 **output, u32 *outputLen)
|
||||
{
|
||||
int ret;
|
||||
switch (buffer[0])
|
||||
{
|
||||
case LZ77_0x10_FLAG:
|
||||
//printf("LZ77 variant 0x10 compressed content...unpacking may take a while...\n");
|
||||
ret = __decompressLZ77_10(buffer, output, outputLen);
|
||||
break;
|
||||
case LZ77_0x11_FLAG:
|
||||
//printf("LZ77 variant 0x11 compressed content...unpacking may take a while...\n");
|
||||
ret = __decompressLZ77_11(buffer, length, output, outputLen);
|
||||
break;
|
||||
default:
|
||||
//printf("Not compressed ...\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
34
resources/wiiflow_game_booter/source/lz77.h
Normal file
34
resources/wiiflow_game_booter/source/lz77.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*******************************************************************************
|
||||
* lz77.h
|
||||
*
|
||||
* Copyright (c) 2009 The Lemon Man
|
||||
* Copyright (c) 2009 Nicksasa
|
||||
* Copyright (c) 2009 WiiPower
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License (v2)
|
||||
* See http://www.gnu.org/licenses/gpl-2.0.txt for more info.
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _LZ77_MODULE
|
||||
#define _LZ77_MODULE
|
||||
|
||||
#define LZ77_0x10_FLAG 0x10
|
||||
#define LZ77_0x11_FLAG 0x11
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int isLZ77compressed(u8 *buffer);
|
||||
int decompressLZ77content(u8 *buffer, u32 length, u8 **output, u32 *outputLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,10 @@
|
||||
#include "patchcode.h"
|
||||
#include "cios.h"
|
||||
#include "disc.h"
|
||||
#include "fs.h"
|
||||
#include "fst.h"
|
||||
#include "lz77.h"
|
||||
#include "utils.h"
|
||||
#include "videopatch.h"
|
||||
|
||||
using namespace std;
|
||||
@ -51,10 +54,7 @@ typedef struct _the_CFG {
|
||||
u32 gameconfsize;
|
||||
u8 BootType;
|
||||
/* needed for channels */
|
||||
void *dolchunkoffset[18];
|
||||
u32 dolchunksize[18];
|
||||
u32 dolchunkcount;
|
||||
u32 startPoint;
|
||||
u64 title;
|
||||
} the_CFG;
|
||||
|
||||
static the_CFG *conf = (the_CFG*)0x90000000;
|
||||
@ -68,21 +68,146 @@ u32 AppEntrypoint;
|
||||
|
||||
extern "C" { extern void __exception_closeall(); }
|
||||
|
||||
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;
|
||||
|
||||
void *dolchunkoffset[18];
|
||||
u32 dolchunksize[18];
|
||||
u32 dolchunkcount;
|
||||
|
||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio)
|
||||
{
|
||||
for(u32 i = 0; i < conf->dolchunkcount; i++)
|
||||
for(u32 i = 0; i < dolchunkcount; i++)
|
||||
{
|
||||
patchVideoModes(conf->dolchunkoffset[i], conf->dolchunksize[i], vidMode, vmode, patchVidModes);
|
||||
if(vipatch) vidolpatcher(conf->dolchunkoffset[i], conf->dolchunksize[i]);
|
||||
if(configbytes[0] != 0xCD) langpatcher(conf->dolchunkoffset[i], conf->dolchunksize[i]);
|
||||
if(countryString) PatchCountryStrings(conf->dolchunkoffset[i], conf->dolchunksize[i]);
|
||||
if(aspectRatio != -1) PatchAspectRatio(conf->dolchunkoffset[i], conf->dolchunksize[i], aspectRatio);
|
||||
patchVideoModes(dolchunkoffset[i], dolchunksize[i], vidMode, vmode, patchVidModes);
|
||||
if(vipatch) vidolpatcher(dolchunkoffset[i], dolchunksize[i]);
|
||||
if(configbytes[0] != 0xCD) langpatcher(dolchunkoffset[i], dolchunksize[i]);
|
||||
if(countryString) PatchCountryStrings(dolchunkoffset[i], dolchunksize[i]);
|
||||
if(aspectRatio != -1) PatchAspectRatio(dolchunkoffset[i], dolchunksize[i], aspectRatio);
|
||||
|
||||
if(hooktype != 0)
|
||||
dogamehooks(conf->dolchunkoffset[i], conf->dolchunksize[i], true);
|
||||
dogamehooks(dolchunkoffset[i], dolchunksize[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *GetDol(u32 bootcontent)
|
||||
{
|
||||
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
sprintf(filepath, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title), bootcontent);
|
||||
|
||||
u32 contentSize = 0;
|
||||
|
||||
u8 *data = ISFS_GetFile((u8 *) &filepath, &contentSize, -1);
|
||||
if(data != NULL && contentSize != 0)
|
||||
{
|
||||
if(isLZ77compressed(data))
|
||||
{
|
||||
u8 *decompressed;
|
||||
u32 size = 0;
|
||||
if(decompressLZ77content(data, contentSize, &decompressed, &size) < 0)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
free(data);
|
||||
data = decompressed;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool GetAppNameFromTmd(char *app, bool dol, u32 *bootcontent)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
char tmd[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
sprintf(tmd, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title));
|
||||
|
||||
u32 size;
|
||||
u8 *data = ISFS_GetFile((u8 *) &tmd, &size, -1);
|
||||
if (data == NULL || size < 0x208)
|
||||
return ret;
|
||||
|
||||
_tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data);
|
||||
u16 i;
|
||||
for(i = 0; i < tmd_file->num_contents; ++i)
|
||||
{
|
||||
if(tmd_file->contents[i].index == (dol ? tmd_file->boot_index : 0))
|
||||
{
|
||||
*bootcontent = tmd_file->contents[i].cid;
|
||||
sprintf(app, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title), *bootcontent);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 MoveDol(u8 *buffer)
|
||||
{
|
||||
dolchunkcount = 0;
|
||||
dolheader *dolfile = (dolheader *)buffer;
|
||||
|
||||
if(dolfile->bss_start)
|
||||
{
|
||||
if(!(dolfile->bss_start & 0x80000000))
|
||||
dolfile->bss_start |= 0x80000000;
|
||||
|
||||
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
|
||||
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
|
||||
ICInvalidateRange((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;
|
||||
|
||||
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
|
||||
dolchunksize[dolchunkcount] = dolfile->section_size[i];
|
||||
|
||||
//gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], (u32)dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
|
||||
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
|
||||
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||
|
||||
dolchunkcount++;
|
||||
}
|
||||
return dolfile->entry_point;
|
||||
}
|
||||
|
||||
u32 LoadChannel()
|
||||
{
|
||||
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
u32 bootcontent;
|
||||
u32 entry = 0;
|
||||
|
||||
if(!GetAppNameFromTmd(app, true, &bootcontent))
|
||||
return entry;
|
||||
|
||||
u8 *data = GetDol(bootcontent);
|
||||
entry = MoveDol(data);
|
||||
free(data);
|
||||
return entry;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
VIDEO_Init();
|
||||
@ -118,12 +243,13 @@ int main()
|
||||
}
|
||||
else if(conf->BootType == TYPE_CHANNEL)
|
||||
{
|
||||
if(hooktype != 0)
|
||||
ocarina_do_code();
|
||||
|
||||
ISFS_Initialize();
|
||||
AppEntrypoint = LoadChannel();
|
||||
PatchChannel(conf->vidMode, vmode, conf->vipatch, conf->countryString,
|
||||
conf->patchVidMode, conf->aspectRatio);
|
||||
AppEntrypoint = conf->startPoint;
|
||||
if(hooktype != 0)
|
||||
ocarina_do_code(conf->title);
|
||||
ISFS_Deinitialize();
|
||||
}
|
||||
|
||||
/* Set time */
|
||||
|
26
resources/wiiflow_game_booter/source/utils.h
Normal file
26
resources/wiiflow_game_booter/source/utils.h
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
#define KB_SIZE 1024.0
|
||||
#define MB_SIZE 1048576.0
|
||||
#define GB_SIZE 1073741824.0
|
||||
|
||||
#define MAX_FAT_PATH 1024
|
||||
|
||||
#define round_up(x,n) (-(-(x) & -(n)))
|
||||
|
||||
#define ALIGN(n, x) (((x) + (n - 1)) & ~(n - 1))
|
||||
#define ALIGN32(x) (((x) + 31) & ~31)
|
||||
|
||||
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
|
||||
#define TITLE_UPPER(x) ((u32)((x) >> 32))
|
||||
#define TITLE_LOWER(x) ((u32)(x) & 0xFFFFFFFF)
|
||||
|
||||
#define Write8(addr, val) *(u8 *)addr = val; DCFlushRange((void *)addr, sizeof(u8));
|
||||
#define Write16(addr, val) *(u16 *)addr = val; DCFlushRange((void *)addr, sizeof(u16));
|
||||
#define Write32(addr, val) *(u32 *)addr = val; DCFlushRange((void *)addr, sizeof(u32));
|
||||
|
||||
#endif
|
@ -15,24 +15,7 @@
|
||||
#include "unzip/lz77.h"
|
||||
#include "types.h"
|
||||
|
||||
typedef void (*entrypoint) (void);
|
||||
|
||||
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;
|
||||
|
||||
void *dolchunkoffset[18];
|
||||
u32 dolchunksize[18];
|
||||
u32 dolchunkcount;
|
||||
|
||||
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
||||
s32 BootChannel(u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
||||
{
|
||||
// IOS Version Check
|
||||
*Real_IOSVersion = ((ios << 16)) | 0xFFFF;
|
||||
@ -45,49 +28,10 @@ s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, boo
|
||||
*Disc_ID = TITLE_LOWER(chantitle);
|
||||
DCFlushRange((void*)Disc_ID, 4);
|
||||
|
||||
ExternalBooter_ChannelSetup(dolchunkoffset, dolchunksize, dolchunkcount, entry);
|
||||
WiiFlow_ExternalBooter(vidMode, vipatch, countryString, patchVidMode, aspectRatio, 0, TYPE_CHANNEL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 LoadChannel(u8 *buffer)
|
||||
{
|
||||
dolchunkcount = 0;
|
||||
dolheader *dolfile = (dolheader *)buffer;
|
||||
|
||||
if(dolfile->bss_start)
|
||||
{
|
||||
if(!(dolfile->bss_start & 0x80000000))
|
||||
dolfile->bss_start |= 0x80000000;
|
||||
|
||||
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
|
||||
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
|
||||
ICInvalidateRange((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;
|
||||
|
||||
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
|
||||
dolchunksize[dolchunkcount] = dolfile->section_size[i];
|
||||
|
||||
gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], (u32)dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
|
||||
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
|
||||
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||
|
||||
dolchunkcount++;
|
||||
}
|
||||
return dolfile->entry_point;
|
||||
}
|
||||
|
||||
bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
|
||||
{
|
||||
signed_blob *buffer = (signed_blob *)memalign(32, ALIGN32(STD_SIGNED_TIK_SIZE));
|
||||
@ -177,34 +121,3 @@ bool Identify(u64 titleid)
|
||||
|
||||
return ret < 0 ? false : true;
|
||||
}
|
||||
|
||||
u8 *GetDol(u64 title, u32 bootcontent)
|
||||
{
|
||||
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
sprintf(filepath, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(title), TITLE_LOWER(title), bootcontent);
|
||||
|
||||
gprintf("Loading DOL: %s...", filepath);
|
||||
u32 contentSize = 0;
|
||||
u8 *data = ISFS_GetFile((u8 *) &filepath, &contentSize, -1);
|
||||
if (data != NULL && contentSize != 0)
|
||||
{
|
||||
gprintf("Done!\n");
|
||||
|
||||
if (isLZ77compressed(data))
|
||||
{
|
||||
u8 *decompressed;
|
||||
u32 size = 0;
|
||||
if (decompressLZ77content(data, contentSize, &decompressed, &size) < 0)
|
||||
{
|
||||
gprintf("Decompression failed\n");
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
free(data);
|
||||
data = decompressed;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
gprintf("Failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <gctypes.h>
|
||||
#include <gccore.h>
|
||||
|
||||
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio);
|
||||
s32 BootChannel(u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio);
|
||||
|
||||
u32 LoadChannel(u8 *buffer);
|
||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
||||
|
@ -67,24 +67,6 @@ Channels::~Channels()
|
||||
{
|
||||
}
|
||||
|
||||
u32 Channels::Load(u64 title)
|
||||
{
|
||||
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
u32 bootcontent;
|
||||
u32 entry = 0;
|
||||
|
||||
if(!GetAppNameFromTmd(title, app, true, &bootcontent))
|
||||
return entry;
|
||||
|
||||
u8 *data = GetDol(title, bootcontent);
|
||||
|
||||
Identify(title);
|
||||
entry = LoadChannel(data);
|
||||
free(data);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
u8 Channels::GetRequestedIOS(u64 title)
|
||||
{
|
||||
u8 IOS = 0;
|
||||
|
@ -54,10 +54,7 @@ typedef struct _the_CFG {
|
||||
u32 gameconfsize;
|
||||
u8 BootType;
|
||||
/* needed for channels */
|
||||
void *dolchunkoffset[18];
|
||||
u32 dolchunksize[18];
|
||||
u32 dolchunkcount;
|
||||
u32 startPoint;
|
||||
u64 title;
|
||||
} the_CFG;
|
||||
|
||||
the_CFG normalCFG;
|
||||
@ -98,15 +95,9 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
|
||||
BootHomebrew();
|
||||
}
|
||||
|
||||
void ExternalBooter_ChannelSetup(void *dolchunkoffset[18], u32 dolchunksize[18], u32 dolchunkcount, u32 StartPoint)
|
||||
void ExternalBooter_ChannelSetup(u64 title)
|
||||
{
|
||||
for(u8 i = 0; i < 18; i++)
|
||||
{
|
||||
normalCFG.dolchunkoffset[i] = dolchunkoffset[i];
|
||||
normalCFG.dolchunksize[i] = dolchunksize[i];
|
||||
}
|
||||
normalCFG.dolchunkcount = dolchunkcount;
|
||||
normalCFG.startPoint = StartPoint;
|
||||
normalCFG.title = title;
|
||||
}
|
||||
|
||||
void ShutdownBeforeExit(bool KeepPatches)
|
||||
|
@ -30,7 +30,7 @@ extern u32 hooktype;
|
||||
|
||||
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode,
|
||||
int aspectRatio, u32 returnTo, u8 BootType);
|
||||
void ExternalBooter_ChannelSetup(void *dolchunkoffset[18], u32 dolchunksize[18], u32 dolchunkcount, u32 StartPoint);
|
||||
void ExternalBooter_ChannelSetup(u64 title);
|
||||
void ShutdownBeforeExit(bool KeepPatches = false);
|
||||
|
||||
#endif
|
||||
|
@ -1134,14 +1134,15 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = channel.Load(gameTitle);
|
||||
setLanguage(language);
|
||||
SmartBuf cheatFile;
|
||||
u32 cheatSize = 0;
|
||||
if(cheat)
|
||||
_loadFile(cheatFile, cheatSize, m_cheatDir.c_str(), fmt("%s.gct", id.c_str()));
|
||||
ocarina_load_code(cheatFile.get(), cheatSize);
|
||||
BootChannel(entry, gameTitle, gameIOS, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio);
|
||||
Identify(gameTitle);
|
||||
ExternalBooter_ChannelSetup(gameTitle);
|
||||
BootChannel(gameTitle, gameIOS, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user