mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2025-02-17 12:36:20 +01:00
-fixed BASIC(!) channel launching, currently only booting
channels from real nand works here, also return to wiiflow seems to be broken, but its a start
This commit is contained in:
parent
bdfe989462
commit
0c32d1b0c1
@ -20,6 +20,7 @@ void __Disc_SetLowMem(void);
|
|||||||
void __Disc_SetVMode(void);
|
void __Disc_SetVMode(void);
|
||||||
void __Disc_SetTime(void);
|
void __Disc_SetTime(void);
|
||||||
void _unstub_start();
|
void _unstub_start();
|
||||||
|
u32 entryPoint;
|
||||||
|
|
||||||
extern void __exception_closeall();
|
extern void __exception_closeall();
|
||||||
|
|
||||||
@ -35,15 +36,10 @@ typedef struct _dolheader{
|
|||||||
u32 padding[7];
|
u32 padding[7];
|
||||||
} __attribute__((packed)) dolheader;
|
} __attribute__((packed)) dolheader;
|
||||||
|
|
||||||
u32 entryPoint;
|
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
|
||||||
|
|
||||||
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
|
|
||||||
{
|
{
|
||||||
u32 ios;
|
gprintf("Loading Channel...\n");
|
||||||
Identify(chantitle, &ios);
|
entryPoint = entry;
|
||||||
|
|
||||||
entryPoint = LoadChannel(data);
|
|
||||||
MEM2_free(data);
|
|
||||||
|
|
||||||
/* Select an appropriate video mode */
|
/* Select an appropriate video mode */
|
||||||
GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle);
|
GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle);
|
||||||
@ -61,11 +57,6 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
|
|||||||
|
|
||||||
entrypoint appJump = (entrypoint)entryPoint;
|
entrypoint appJump = (entrypoint)entryPoint;
|
||||||
|
|
||||||
if (disableIOSreload)
|
|
||||||
IOSReloadBlock(IOS_GetVersion(), false);
|
|
||||||
else
|
|
||||||
IOSReloadBlock(IOS_GetVersion(), true);
|
|
||||||
|
|
||||||
/* Set an appropriate video mode */
|
/* Set an appropriate video mode */
|
||||||
__Disc_SetVMode();
|
__Disc_SetVMode();
|
||||||
|
|
||||||
@ -80,14 +71,19 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
|
|||||||
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
|
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
|
||||||
DCFlushRange((void *)0x80000000, 6);
|
DCFlushRange((void *)0x80000000, 6);
|
||||||
|
|
||||||
/* Shutdown IOS subsystems */
|
|
||||||
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
|
||||||
|
|
||||||
gprintf("Jumping to entrypoint %08x\n", entryPoint);
|
gprintf("Jumping to entrypoint %08x\n", entryPoint);
|
||||||
|
|
||||||
|
/* Shutdown IOS subsystems */
|
||||||
|
u32 level = IRQ_Disable();
|
||||||
|
__IOS_ShutdownSubsystems();
|
||||||
|
__exception_closeall();
|
||||||
|
|
||||||
|
/* Originally from tueidj - taken from NeoGamma (thx) */
|
||||||
|
*(vu32*)0xCC003024 = 1;
|
||||||
|
|
||||||
if (entryPoint != 0x3400)
|
if (entryPoint != 0x3400)
|
||||||
{
|
{
|
||||||
if (hooktype != 0)
|
if(hooktype != 0)
|
||||||
{
|
{
|
||||||
__asm__(
|
__asm__(
|
||||||
"lis %r3, entryPoint@h\n"
|
"lis %r3, entryPoint@h\n"
|
||||||
@ -101,9 +97,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
|
|||||||
"bctr\n"
|
"bctr\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else appJump();
|
else
|
||||||
|
appJump();
|
||||||
}
|
}
|
||||||
else if (hooktype != 0)
|
else if(hooktype != 0)
|
||||||
{
|
{
|
||||||
__asm__(
|
__asm__(
|
||||||
"lis %r3, returnpoint@h\n"
|
"lis %r3, returnpoint@h\n"
|
||||||
@ -126,7 +123,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
|
|||||||
"rfi\n"
|
"rfi\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else _unstub_start();
|
else
|
||||||
|
_unstub_start();
|
||||||
|
|
||||||
|
IRQ_Restore(level);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -145,25 +145,25 @@ u32 LoadChannel(u8 *buffer)
|
|||||||
if(!(dolfile->bss_start & 0x80000000))
|
if(!(dolfile->bss_start & 0x80000000))
|
||||||
dolfile->bss_start |= 0x80000000;
|
dolfile->bss_start |= 0x80000000;
|
||||||
|
|
||||||
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
|
|
||||||
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
|
memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
|
||||||
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
|
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
|
||||||
|
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 18; i++)
|
for(i = 0; i < 18; i++)
|
||||||
{
|
{
|
||||||
if (!dolfile->section_size[i]) continue;
|
if(!dolfile->section_size[i]) continue;
|
||||||
if (dolfile->section_pos[i] < sizeof(dolheader)) continue;
|
if(dolfile->section_pos[i] < sizeof(dolheader)) continue;
|
||||||
if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000;
|
if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000;
|
||||||
|
|
||||||
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
|
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
|
||||||
dolchunksize[dolchunkcount] = dolfile->section_size[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], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
|
gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
|
||||||
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
|
||||||
memmove (dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
|
|
||||||
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||||
|
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
|
||||||
|
|
||||||
dolchunkcount++;
|
dolchunkcount++;
|
||||||
}
|
}
|
||||||
@ -217,37 +217,44 @@ bool Identify(u64 titleid, u32 *ios)
|
|||||||
{
|
{
|
||||||
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||||
|
|
||||||
|
gprintf("Reading TMD...");
|
||||||
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
|
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
|
||||||
u32 tmdSize;
|
u32 tmdSize;
|
||||||
u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1);
|
u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1);
|
||||||
if (tmdBuffer == NULL || tmdSize == 0)
|
if (tmdBuffer == NULL || tmdSize == 0)
|
||||||
{
|
{
|
||||||
gprintf("Reading TMD...Failed!\n");
|
gprintf("Failed!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
gprintf("Success!\n");
|
||||||
|
|
||||||
*ios = (u32)(tmdBuffer[0x18b]);
|
*ios = (u32)(tmdBuffer[0x18b]);
|
||||||
|
|
||||||
u32 tikSize;
|
u32 tikSize;
|
||||||
signed_blob *tikBuffer = NULL;
|
signed_blob *tikBuffer = NULL;
|
||||||
|
|
||||||
|
gprintf("Generating fake ticket...");
|
||||||
if(!Identify_GenerateTik(&tikBuffer,&tikSize))
|
if(!Identify_GenerateTik(&tikBuffer,&tikSize))
|
||||||
{
|
{
|
||||||
gprintf("Generating fake ticket...Failed!\n");
|
gprintf("Failed!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
gprintf("Success!\n");
|
||||||
|
|
||||||
|
gprintf("Reading certs...");
|
||||||
sprintf(filepath, "/sys/cert.sys");
|
sprintf(filepath, "/sys/cert.sys");
|
||||||
u32 certSize;
|
u32 certSize;
|
||||||
u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1);
|
u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1);
|
||||||
if (certBuffer == NULL || certSize == 0)
|
if (certBuffer == NULL || certSize == 0)
|
||||||
{
|
{
|
||||||
gprintf("Reading certs...Failed!\n");
|
gprintf("Failed!\n");
|
||||||
MEM2_free(tmdBuffer);
|
MEM2_free(tmdBuffer);
|
||||||
MEM2_free(tikBuffer);
|
MEM2_free(tikBuffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
gprintf("Success!\n");
|
||||||
|
|
||||||
|
gprintf("ES_Identify\n");
|
||||||
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL);
|
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ extern "C" {
|
|||||||
#include <gctypes.h>
|
#include <gctypes.h>
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
|
|
||||||
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio);
|
s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio);
|
||||||
|
|
||||||
u32 LoadChannel(u8 *buffer);
|
u32 LoadChannel(u8 *buffer);
|
||||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);
|
||||||
|
@ -73,15 +73,22 @@ Channels::~Channels()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 * Channels::Load(u64 title)
|
u32 Channels::Load(u64 title, u32 *ios)
|
||||||
{
|
{
|
||||||
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||||
u32 bootcontent;
|
u32 bootcontent;
|
||||||
|
u32 entry = 0;
|
||||||
|
|
||||||
if(!GetAppNameFromTmd(title, app, true, &bootcontent))
|
if(!GetAppNameFromTmd(title, app, true, &bootcontent))
|
||||||
return NULL;
|
return entry;
|
||||||
|
|
||||||
return GetDol(title, bootcontent);
|
u8* data = GetDol(title, bootcontent);
|
||||||
|
|
||||||
|
Identify(title, ios);
|
||||||
|
entry = LoadChannel(data);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 Channels::GetRequestedIOS(u64 title)
|
u8 Channels::GetRequestedIOS(u64 title)
|
||||||
@ -104,11 +111,6 @@ u8 Channels::GetRequestedIOS(u64 title)
|
|||||||
return IOS;
|
return IOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channels::Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
|
|
||||||
{
|
|
||||||
return BootChannel(data, chantitle, vidMode, vipatch, countryString, patchVidMode, disableIOSreload, aspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64* Channels::GetChannelList(u32* count)
|
u64* Channels::GetChannelList(u32* count)
|
||||||
{
|
{
|
||||||
u32 countall;
|
u32 countall;
|
||||||
|
@ -54,9 +54,8 @@ class Channels
|
|||||||
|
|
||||||
void Init(u32 channelType, string lang, bool reload = false);
|
void Init(u32 channelType, string lang, bool reload = false);
|
||||||
|
|
||||||
u8 * Load(u64 title);
|
u32 Load(u64 title, u32 *ios);
|
||||||
u8 GetRequestedIOS(u64 title);
|
u8 GetRequestedIOS(u64 title);
|
||||||
bool Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio);
|
|
||||||
|
|
||||||
int Count();
|
int Count();
|
||||||
wchar_t *GetName(int index);
|
wchar_t *GetName(int index);
|
||||||
|
@ -81,8 +81,14 @@ void Nand::Init(string path, u32 partition, bool disable)
|
|||||||
|
|
||||||
s32 Nand::Nand_Mount(NandDevice *Device)
|
s32 Nand::Nand_Mount(NandDevice *Device)
|
||||||
{
|
{
|
||||||
|
gprintf("Device: %s\n", Device->Name);
|
||||||
|
|
||||||
s32 fd = IOS_Open("fat", 0);
|
s32 fd = IOS_Open("fat", 0);
|
||||||
if (fd < 0) return fd;
|
if(fd < 0)
|
||||||
|
{
|
||||||
|
gprintf("Mount Fail 1\n");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
static ioctlv vector[1] ATTRIBUTE_ALIGN(32);
|
static ioctlv vector[1] ATTRIBUTE_ALIGN(32);
|
||||||
|
|
||||||
@ -145,17 +151,28 @@ s32 Nand::Nand_Disable(void)
|
|||||||
s32 Nand::Enable_Emu()
|
s32 Nand::Enable_Emu()
|
||||||
{
|
{
|
||||||
if(MountedDevice == EmuDevice || Disabled)
|
if(MountedDevice == EmuDevice || Disabled)
|
||||||
|
{
|
||||||
|
gprintf("Fail 1\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Disable_Emu();
|
Disable_Emu();
|
||||||
|
|
||||||
NandDevice *Device = &NandDeviceList[EmuDevice];
|
NandDevice *Device = &NandDeviceList[EmuDevice];
|
||||||
|
|
||||||
s32 ret = Nand_Mount(Device);
|
s32 ret = Nand_Mount(Device);
|
||||||
if (ret < 0) return ret;
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
gprintf("Fail 2\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = Nand_Enable(Device);
|
ret = Nand_Enable(Device);
|
||||||
if (ret < 0) return ret;
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
gprintf("Fail 3\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
MountedDevice = EmuDevice;
|
MountedDevice = EmuDevice;
|
||||||
|
|
||||||
|
@ -872,7 +872,9 @@ static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', '
|
|||||||
void CMenu::_launchChannel(dir_discHdr *hdr)
|
void CMenu::_launchChannel(dir_discHdr *hdr)
|
||||||
{
|
{
|
||||||
Channels channel;
|
Channels channel;
|
||||||
u8 *data = NULL;
|
u32 ios = 0;
|
||||||
|
u32 entry = 0;
|
||||||
|
MEM1_wrap(0);
|
||||||
|
|
||||||
string id = string((const char *) hdr->hdr.id);
|
string id = string((const char *) hdr->hdr.id);
|
||||||
|
|
||||||
@ -887,14 +889,10 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0;
|
forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0;
|
||||||
|
|
||||||
if(!forwarder)
|
if(!forwarder)
|
||||||
data = channel.Load(hdr->hdr.chantitle);
|
entry = channel.Load(hdr->hdr.chantitle, &ios);
|
||||||
|
|
||||||
Nand::Instance()->Disable_Emu();
|
Nand::Instance()->Disable_Emu();
|
||||||
|
|
||||||
if(!forwarder && data == NULL) return;
|
|
||||||
|
|
||||||
bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false));
|
bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false));
|
||||||
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false));
|
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false));
|
||||||
bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false));
|
bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false));
|
||||||
@ -987,6 +985,11 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
|
|||||||
IOS_Close(ESHandle);
|
IOS_Close(ESHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (disableIOSreload)
|
||||||
|
IOSReloadBlock(IOS_GetVersion(), false);
|
||||||
|
else
|
||||||
|
IOSReloadBlock(IOS_GetVersion(), true);
|
||||||
|
|
||||||
CheckGameSoundThread();
|
CheckGameSoundThread();
|
||||||
cleanup();
|
cleanup();
|
||||||
Close_Inputs();
|
Close_Inputs();
|
||||||
@ -1000,7 +1003,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
|
|||||||
if (WII_LaunchTitle(hdr->hdr.chantitle) < 0)
|
if (WII_LaunchTitle(hdr->hdr.chantitle) < 0)
|
||||||
Sys_LoadMenu();
|
Sys_LoadMenu();
|
||||||
}
|
}
|
||||||
else if(!channel.Launch(data, hdr->hdr.chantitle, videoMode, vipatch, countryPatch, patchVidMode, disableIOSreload, aspectRatio))
|
else if(!BootChannel(entry, hdr->hdr.chantitle, ios, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio))
|
||||||
Sys_LoadMenu();
|
Sys_LoadMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user