mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
-fixed fucked up channel view
-fixed using .wip codes in wii games -cleaned up this and that -more compatible way of fixing 002 error (thanks uLoader)
This commit is contained in:
parent
c23025a63f
commit
3f55f129a6
@ -78,7 +78,7 @@ static u8 *GetDol(u32 bootcontent, u64 title)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
|
||||
static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title, u32 *IOS)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@ -89,6 +89,7 @@ static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
|
||||
u8 *data = ISFS_GetFile((u8 *) &filepath, &size, -1);
|
||||
if(data == NULL || size < 0x208)
|
||||
return ret;
|
||||
*IOS = data[0x18B];
|
||||
|
||||
_tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data);
|
||||
for(u16 i = 0; i < tmd_file->num_contents; ++i)
|
||||
@ -100,7 +101,6 @@ static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
return ret;
|
||||
@ -140,11 +140,11 @@ static u32 MoveDol(u8 *buffer)
|
||||
return dolfile->entry_point;
|
||||
}
|
||||
|
||||
u32 LoadChannel(u64 title)
|
||||
u32 LoadChannel(u64 title, u32 *IOS)
|
||||
{
|
||||
u32 entry = 0;
|
||||
|
||||
GetAppNameFromTmd(true, &bootcontent, title);
|
||||
GetAppNameFromTmd(true, &bootcontent, title, IOS);
|
||||
u8 *data = GetDol(bootcontent, title);
|
||||
entry = MoveDol(data);
|
||||
free(data);
|
||||
|
@ -15,6 +15,6 @@ typedef struct _dolheader
|
||||
|
||||
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString,
|
||||
u8 patchVidModes, int aspectRatio, u64 title);
|
||||
u32 LoadChannel(u64 title);
|
||||
u32 LoadChannel(u64 title, u32 *IOS);
|
||||
|
||||
#endif /* __CHANHANDLE_HPP_ */
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "cios.h"
|
||||
#include "frag.h"
|
||||
#include "wip.h"
|
||||
|
||||
typedef struct _the_CFG {
|
||||
/* needed for wii games */
|
||||
@ -28,6 +29,8 @@ typedef struct _the_CFG {
|
||||
u32 wbfsPart;
|
||||
u8 GameBootType;
|
||||
u8 mload_rev;
|
||||
WIP_Code *wip_list;
|
||||
u32 wip_count;
|
||||
/* needed for channels */
|
||||
u64 title;
|
||||
/* General Stuff */
|
||||
@ -37,8 +40,8 @@ typedef struct _the_CFG {
|
||||
u8 patchVidMode;
|
||||
u8 configbytes[2];
|
||||
u8 debugger;
|
||||
bool vipatch;
|
||||
bool countryString;
|
||||
u8 vipatch;
|
||||
u8 countryString;
|
||||
int aspectRatio;
|
||||
void *codelist;
|
||||
u8 *codelistend;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "fst.h"
|
||||
#include "wip.h"
|
||||
#include "gecko.h"
|
||||
#include "memory.h"
|
||||
#include "video_tinyload.h"
|
||||
|
||||
/* Apploader function pointers */
|
||||
@ -32,8 +33,8 @@ void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipa
|
||||
static void patch_NoDiscinDrive(void *buffer, u32 len);
|
||||
static void Anti_002_fix(void *Address, int Size);
|
||||
static bool Remove_001_Protection(void *Address, int Size);
|
||||
static bool PrinceOfPersiaPatch();
|
||||
static bool NewSuperMarioBrosPatch();
|
||||
static void PrinceOfPersiaPatch();
|
||||
static void NewSuperMarioBrosPatch();
|
||||
bool hookpatched = false;
|
||||
|
||||
s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
||||
@ -93,25 +94,21 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc
|
||||
/* Set entry point from apploader */
|
||||
*entry = appldr_final();
|
||||
|
||||
/* ERROR 002 fix (WiiPower) */
|
||||
*(u32 *)0x80003140 = *(u32 *)0x80003188;
|
||||
DCFlushRange((void*)0x80000000, 0x3f00);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo)
|
||||
{
|
||||
// Patch NoDiscInDrive only for IOS 249 < rev13 or IOS 222/223/224
|
||||
if((CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) || CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||
patch_NoDiscinDrive(dst, len);
|
||||
do_wip_code((u8 *)dst, len);
|
||||
Remove_001_Protection(dst, len);
|
||||
if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13)
|
||||
Anti_002_fix(dst, len);
|
||||
Remove_001_Protection(dst, len);
|
||||
if((CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) || CurrentIOS.Type == IOS_TYPE_HERMES)
|
||||
patch_NoDiscinDrive(dst, len);
|
||||
|
||||
if(hooktype != 0 && hookpatched == false)
|
||||
hookpatched = dogamehooks(dst, len, false);
|
||||
patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
|
||||
if(hooktype != 0 && dogamehooks(dst, len, false))
|
||||
hookpatched = true;
|
||||
if(vipatch)
|
||||
vidolpatcher(dst, len);
|
||||
if(configbytes[0] != 0xCD)
|
||||
@ -122,7 +119,6 @@ void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipa
|
||||
PatchAspectRatio(dst, len, aspectRatio);
|
||||
if(returnTo)
|
||||
PatchReturnTo(dst, len, returnTo);
|
||||
do_wip_code((u8 *)dst, len);
|
||||
}
|
||||
|
||||
static void patch_NoDiscinDrive(void *buffer, u32 len)
|
||||
@ -154,12 +150,12 @@ static void Anti_002_fix(void *Address, int Size)
|
||||
}
|
||||
}
|
||||
|
||||
static bool PrinceOfPersiaPatch()
|
||||
static void PrinceOfPersiaPatch()
|
||||
{
|
||||
if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0)
|
||||
return false;
|
||||
if(memcmp("SPX", (char*)Disc_ID, 3) != 0 && memcmp("RPW", (char*)Disc_ID, 3) != 0)
|
||||
return;
|
||||
|
||||
WIP_Code * CodeList = malloc(5 * sizeof(WIP_Code));
|
||||
WIP_Code CodeList[5];
|
||||
CodeList[0].offset = 0x007AAC6A;
|
||||
CodeList[0].srcaddress = 0x7A6B6F6A;
|
||||
CodeList[0].dstaddress = 0x6F6A7A6B;
|
||||
@ -175,26 +171,14 @@ static bool PrinceOfPersiaPatch()
|
||||
CodeList[4].offset = 0x007AAC9D;
|
||||
CodeList[4].srcaddress = 0x82806F3F;
|
||||
CodeList[4].dstaddress = 0x6F3F8280;
|
||||
|
||||
if (set_wip_list(CodeList, 5) == false)
|
||||
{
|
||||
free(CodeList);
|
||||
CodeList = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
set_wip_list(CodeList, 5);
|
||||
}
|
||||
|
||||
static bool NewSuperMarioBrosPatch()
|
||||
static void NewSuperMarioBrosPatch()
|
||||
{
|
||||
WIP_Code * CodeList = NULL;
|
||||
|
||||
if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0)
|
||||
WIP_Code CodeList[3];
|
||||
if(memcmp("SMNE01", (char*)Disc_ID, 6) == 0)
|
||||
{
|
||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB610;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
@ -204,12 +188,10 @@ static bool NewSuperMarioBrosPatch()
|
||||
CodeList[2].offset = 0x001CED6B;
|
||||
CodeList[2].srcaddress = 0xDA000000;
|
||||
CodeList[2].dstaddress = 0x71000000;
|
||||
set_wip_list(CodeList, 3);
|
||||
}
|
||||
else if (memcmp("SMNP01", (char *) 0x80000000, 6) == 0)
|
||||
else if(memcmp("SMNP01", (char*)Disc_ID, 6) == 0)
|
||||
{
|
||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB750;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
@ -219,12 +201,10 @@ static bool NewSuperMarioBrosPatch()
|
||||
CodeList[2].offset = 0x001CEEA8;
|
||||
CodeList[2].srcaddress = 0x388000DA;
|
||||
CodeList[2].dstaddress = 0x38800071;
|
||||
set_wip_list(CodeList, 3);
|
||||
}
|
||||
else if (memcmp("SMNJ01", (char *) 0x80000000, 6) == 0)
|
||||
else if(memcmp("SMNJ01", (char*)Disc_ID, 6) == 0)
|
||||
{
|
||||
CodeList = malloc(3 * sizeof(WIP_Code));
|
||||
if(!CodeList)
|
||||
return false;
|
||||
CodeList[0].offset = 0x001AB420;
|
||||
CodeList[0].srcaddress = 0x9421FFD0;
|
||||
CodeList[0].dstaddress = 0x4E800020;
|
||||
@ -234,14 +214,8 @@ static bool NewSuperMarioBrosPatch()
|
||||
CodeList[2].offset = 0x001CEB7B;
|
||||
CodeList[2].srcaddress = 0xDA000000;
|
||||
CodeList[2].dstaddress = 0x71000000;
|
||||
set_wip_list(CodeList, 3);
|
||||
}
|
||||
if (CodeList && set_wip_list(CodeList, 3) == false)
|
||||
{
|
||||
free(CodeList);
|
||||
CodeList = NULL;
|
||||
return false;
|
||||
}
|
||||
return CodeList != NULL;
|
||||
}
|
||||
|
||||
static bool Remove_001_Protection(void *Address, int Size)
|
||||
@ -251,9 +225,9 @@ static bool Remove_001_Protection(void *Address, int Size)
|
||||
u8 *Addr_end = Address + Size;
|
||||
u8 *Addr;
|
||||
|
||||
for (Addr = Address; Addr <= Addr_end - sizeof SearchPattern; Addr += 4)
|
||||
for(Addr = Address; Addr <= Addr_end - sizeof SearchPattern; Addr += 4)
|
||||
{
|
||||
if (memcmp(Addr, SearchPattern, sizeof SearchPattern) == 0)
|
||||
if(memcmp(Addr, SearchPattern, sizeof SearchPattern) == 0)
|
||||
{
|
||||
memcpy(Addr, PatchData, sizeof PatchData);
|
||||
return true;
|
||||
|
@ -31,7 +31,7 @@ s32 Disc_Open()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Disc_SetLowMem()
|
||||
void Disc_SetLowMem(u32 IOS)
|
||||
{
|
||||
/* Setup low memory */
|
||||
*Sys_Magic = 0x0D15EA5E; // Standard Boot Code
|
||||
@ -52,6 +52,14 @@ void Disc_SetLowMem()
|
||||
|
||||
/* Copy disc ID */
|
||||
memcpy((void *)Online_Check, (void *)Disc_ID, 4);
|
||||
|
||||
/* Error 002 Fix (thanks WiiPower and uLoader) */
|
||||
*(vu32*)0x80003140 = (IOS << 16) | 0xffff;
|
||||
//*(u32 *)0x80003140 = *(u32 *)0x80003188; // removes 002-Error (by WiiPower: http://gbatemp.net/index.php?showtopic=158885&hl=)
|
||||
*(vu32*)0x80003188 = *(vu32*)0x80003140;
|
||||
|
||||
/* Flush everything */
|
||||
DCFlushRange((void*)0x80000000, 0x3f00);
|
||||
}
|
||||
|
||||
s32 Disc_FindPartition(u64 *outbuf)
|
||||
|
@ -9,7 +9,7 @@ extern "C" {
|
||||
s32 Disc_Open();
|
||||
s32 Disc_FindPartition(u64 *outbuf);
|
||||
s32 Disc_SetUSB(const u8 *id, bool frag);
|
||||
void Disc_SetLowMem();
|
||||
void Disc_SetLowMem(u32 IOS);
|
||||
void Disc_SetTime();
|
||||
|
||||
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);
|
||||
|
@ -35,6 +35,7 @@ using namespace std;
|
||||
IOS_Info CurrentIOS;
|
||||
|
||||
/* Boot Variables */
|
||||
u32 GameIOS = 0;
|
||||
u32 vmode_reg = 0;
|
||||
entry_point p_entry;
|
||||
GXRModeObj *vmode = NULL;
|
||||
@ -63,6 +64,7 @@ int main()
|
||||
hooktype = normalCFG.hooktype;
|
||||
debuggerselect = normalCFG.debugger;
|
||||
CurrentIOS = normalCFG.IOS;
|
||||
set_wip_list(normalCFG.wip_list, normalCFG.wip_count);
|
||||
app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize);
|
||||
ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize);
|
||||
frag_list = normalCFG.fragments;
|
||||
@ -86,11 +88,9 @@ int main()
|
||||
}
|
||||
prog10();
|
||||
Disc_Open();
|
||||
Disc_SetLowMem();
|
||||
prog10();
|
||||
u64 offset = 0;
|
||||
Disc_FindPartition(&offset);
|
||||
WDVD_OpenPartition(offset);
|
||||
WDVD_OpenPartition(offset, &GameIOS);
|
||||
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
|
||||
prog10();
|
||||
Apploader_Run(&p_entry, normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode,
|
||||
@ -101,21 +101,23 @@ int main()
|
||||
else if(normalCFG.BootType == TYPE_CHANNEL)
|
||||
{
|
||||
ISFS_Initialize();
|
||||
Disc_SetLowMem();
|
||||
prog10();
|
||||
AppEntrypoint = LoadChannel(normalCFG.title);
|
||||
AppEntrypoint = LoadChannel(normalCFG.title, &GameIOS);
|
||||
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
|
||||
PatchChannel(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString,
|
||||
normalCFG.patchVidMode, normalCFG.aspectRatio, normalCFG.title);
|
||||
ISFS_Deinitialize();
|
||||
}
|
||||
gprintf("Entrypoint: %08x\n", AppEntrypoint);
|
||||
gprintf("Entrypoint: %08x, Requested Game IOS: %i\n", AppEntrypoint, GameIOS);
|
||||
setprog(320);
|
||||
|
||||
/* Setup Low Memory */
|
||||
Disc_SetLowMem(GameIOS);
|
||||
|
||||
/* Set time */
|
||||
Disc_SetTime();
|
||||
|
||||
/* Set an appropriate video mode */
|
||||
video_clear();
|
||||
Disc_SetVMode(vmode, vmode_reg);
|
||||
|
||||
/* Shutdown IOS subsystems */
|
||||
|
@ -100,3 +100,11 @@ void video_init(void)
|
||||
|
||||
prog(0);
|
||||
}
|
||||
|
||||
void video_clear(void)
|
||||
{
|
||||
memset32(framebuffer, COLOR_BLACK, 320*574);
|
||||
// this sets VI to black, but I can't fit it in yet...
|
||||
viw(0x0, oldvtrdcr);
|
||||
*(vu64*)(0xCC00200c) = oldvtovte;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void video_init(void);
|
||||
void video_clear(void);
|
||||
void prog(int p);
|
||||
void prog10(void);
|
||||
void setprog(int p);
|
||||
|
@ -169,7 +169,7 @@ s32 WDVD_Eject(void)
|
||||
return (ret == 1) ? 0 : -ret;
|
||||
}
|
||||
|
||||
s32 WDVD_OpenPartition(u64 offset)
|
||||
s32 WDVD_OpenPartition(u64 offset, u32 *IOS)
|
||||
{
|
||||
if (di_fd < 0)
|
||||
return di_fd;
|
||||
@ -196,7 +196,7 @@ s32 WDVD_OpenPartition(u64 offset)
|
||||
Vectors[4].len = 0x20;
|
||||
|
||||
ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors);
|
||||
|
||||
*IOS = (u32)(Tmd_Buffer[0x18b]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -15,7 +15,7 @@ s32 WDVD_Seek(u64);
|
||||
s32 WDVD_Offset(u64);
|
||||
s32 WDVD_StopLaser(void);
|
||||
s32 WDVD_StopMotor(void);
|
||||
s32 WDVD_OpenPartition(u64 offset);
|
||||
s32 WDVD_OpenPartition(u64 offset, u32 *IOS);
|
||||
s32 WDVD_ClosePartition(void);
|
||||
s32 WDVD_UnencryptedRead(void *, u32, u64);
|
||||
s32 WDVD_Read(void *, u32, u64);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "wip.h"
|
||||
#include "gecko.h"
|
||||
|
||||
static WIP_Code * CodeList = NULL;
|
||||
static WIP_Code *CodeList = NULL;
|
||||
static u32 CodesCount = 0;
|
||||
static u32 ProcessedLength = 0;
|
||||
static u32 Counter = 0;
|
||||
@ -56,15 +56,17 @@ void do_wip_code(u8 * dst, u32 len)
|
||||
//! .wip files override internal patches
|
||||
//! the codelist has to be freed if the set fails
|
||||
//! if set was successful the codelist will be freed when it's done
|
||||
bool set_wip_list(WIP_Code * list, int size)
|
||||
bool set_wip_list(WIP_Code *list, int size)
|
||||
{
|
||||
if(!CodeList && size > 0)
|
||||
if(CodeList == NULL && size > 0)
|
||||
{
|
||||
CodeList = list;
|
||||
WIP_Code *newlist = malloc(size * sizeof(WIP_Code));
|
||||
memcpy(newlist, list, size * sizeof(WIP_Code));
|
||||
DCFlushRange(newlist, size * sizeof(WIP_Code));
|
||||
CodeList = newlist;
|
||||
CodesCount = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -77,65 +79,8 @@ void wip_reset_counter()
|
||||
|
||||
void free_wip()
|
||||
{
|
||||
if(CodeList)
|
||||
if(CodeList != NULL)
|
||||
free(CodeList);
|
||||
|
||||
CodesCount = 0;
|
||||
ProcessedLength = 0;
|
||||
}
|
||||
|
||||
int load_wip_patches(u8 *dir, u8 *gameid)
|
||||
{
|
||||
char filepath[150];
|
||||
char GameID[8];
|
||||
memset(GameID, 0, sizeof(GameID));
|
||||
memcpy(GameID, gameid, 6);
|
||||
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
||||
|
||||
FILE *fp = fopen(filepath, "rb");
|
||||
if(!fp)
|
||||
{
|
||||
memset(GameID, 0, sizeof(GameID));
|
||||
memcpy(GameID, gameid, 3);
|
||||
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
||||
fp = fopen(filepath, "rb");
|
||||
}
|
||||
|
||||
if(!fp)
|
||||
return -1;
|
||||
|
||||
char line[255];
|
||||
//printf("\nLoading WIP code from %s.\n", filepath);
|
||||
|
||||
while(fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if(line[0] == '#' || strlen(line) < 26)
|
||||
continue;
|
||||
|
||||
u32 offset = (u32) strtoul(line, NULL, 16);
|
||||
u32 srcaddress = (u32) strtoul(line+9, NULL, 16);
|
||||
u32 dstaddress = (u32) strtoul(line+18, NULL, 16);
|
||||
|
||||
if(!CodeList)
|
||||
CodeList = malloc(sizeof(WIP_Code));
|
||||
|
||||
WIP_Code *tmp = realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code));
|
||||
if(!tmp)
|
||||
{
|
||||
free(CodeList);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CodeList = tmp;
|
||||
|
||||
CodeList[CodesCount].offset = offset;
|
||||
CodeList[CodesCount].srcaddress = srcaddress;
|
||||
CodeList[CodesCount].dstaddress = dstaddress;
|
||||
CodesCount++;
|
||||
}
|
||||
fclose(fp);
|
||||
//printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "loader/cios.h"
|
||||
#include "loader/frag.h"
|
||||
#include "loader/wip.h"
|
||||
|
||||
typedef struct _the_CFG {
|
||||
/* needed for wii games */
|
||||
@ -28,6 +29,8 @@ typedef struct _the_CFG {
|
||||
u32 wbfsPart;
|
||||
u8 GameBootType;
|
||||
u8 mload_rev;
|
||||
WIP_Code *wip_list;
|
||||
u32 wip_count;
|
||||
/* needed for channels */
|
||||
u64 title;
|
||||
/* General Stuff */
|
||||
|
@ -75,6 +75,8 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
|
||||
normalCFG.gameconf = gameconf;
|
||||
normalCFG.gameconfsize = gameconfsize;
|
||||
normalCFG.BootType = BootType;
|
||||
normalCFG.wip_list = get_wip_list();
|
||||
normalCFG.wip_count = get_wip_count();
|
||||
|
||||
ShutdownBeforeExit();
|
||||
/* Copy CFG into new memory region */
|
||||
|
@ -91,6 +91,8 @@ void Banner::ClearBanner()
|
||||
free(opening);
|
||||
opening = NULL;
|
||||
opening_size = 0;
|
||||
title = 0;
|
||||
imet = NULL;
|
||||
}
|
||||
|
||||
bool Banner::IsValid()
|
||||
|
@ -41,29 +41,23 @@
|
||||
|
||||
#define DOWNLOADED_CHANNELS 0x00010001
|
||||
#define SYSTEM_CHANNELS 0x00010002
|
||||
#define GAME_CHANNELS 0x00010004
|
||||
|
||||
#define RF_NEWS_CHANNEL 0x48414741
|
||||
#define RF_FORECAST_CHANNEL 0x48414641
|
||||
|
||||
Channels ChannelHandle;
|
||||
|
||||
void Channels::Init(u32 channelType, string lang, bool reload)
|
||||
void Channels::Init(string lang)
|
||||
{
|
||||
if (reload) init = !reload;
|
||||
if (!init || channelType != this->channelType ||
|
||||
lang != this->langCode)
|
||||
{
|
||||
this->channelType = channelType;
|
||||
this->langCode = lang;
|
||||
|
||||
this->channels.clear();
|
||||
Search(channelType, lang);
|
||||
init = true;
|
||||
}
|
||||
this->langCode = lang;
|
||||
this->clear();
|
||||
Search();
|
||||
}
|
||||
|
||||
void Channels::Cleanup()
|
||||
{
|
||||
this->channels.clear();
|
||||
this->clear();
|
||||
}
|
||||
|
||||
u8 Channels::GetRequestedIOS(u64 title)
|
||||
@ -86,41 +80,24 @@ u8 Channels::GetRequestedIOS(u64 title)
|
||||
return IOS;
|
||||
}
|
||||
|
||||
u64* Channels::GetChannelList(u32* count)
|
||||
u64 *Channels::GetChannelList(u32 *count)
|
||||
{
|
||||
*count = 0;
|
||||
u32 countall;
|
||||
if (ES_GetNumTitles(&countall) < 0 || !countall) return NULL;
|
||||
if(ES_GetNumTitles(&countall) < 0 || countall == 0)
|
||||
return NULL;
|
||||
|
||||
u64* titles = (u64*)MEM2_alloc(countall * sizeof(u64));
|
||||
if (!titles)
|
||||
u64 *titles = (u64*)MEM2_alloc(countall*sizeof(u64));
|
||||
if(titles == NULL)
|
||||
return NULL;
|
||||
|
||||
if(ES_GetTitles(titles, countall) < 0)
|
||||
{
|
||||
free(titles);
|
||||
MEM2_free(titles);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u64* channels = (u64*)MEM2_alloc(countall * sizeof(u64));
|
||||
if (!channels)
|
||||
return NULL;
|
||||
|
||||
*count = 0;
|
||||
for (u32 i = 0; i < countall; i++)
|
||||
{
|
||||
u32 type = TITLE_UPPER(titles[i]);
|
||||
|
||||
if (type == DOWNLOADED_CHANNELS || type == SYSTEM_CHANNELS)
|
||||
{
|
||||
if (TITLE_LOWER(titles[i]) == RF_NEWS_CHANNEL || // skip region free news and forecast channel
|
||||
TITLE_LOWER(titles[i]) == RF_FORECAST_CHANNEL)
|
||||
continue;
|
||||
channels[(*count)++] = titles[i];
|
||||
}
|
||||
}
|
||||
free(titles);
|
||||
|
||||
return(u64*)MEM2_realloc(channels, *count * sizeof(u64));
|
||||
*count = countall;
|
||||
return titles;
|
||||
}
|
||||
|
||||
bool Channels::GetAppNameFromTmd(u64 title, char *app, bool dol, u32 *bootcontent)
|
||||
@ -155,9 +132,10 @@ bool Channels::GetAppNameFromTmd(u64 title, char *app, bool dol, u32 *bootconten
|
||||
|
||||
void Channels::GetBanner(u64 title, bool imetOnly)
|
||||
{
|
||||
CurrentBanner.ClearBanner();
|
||||
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
|
||||
u32 cid;
|
||||
if (!GetAppNameFromTmd(title, app, false, &cid))
|
||||
if(!GetAppNameFromTmd(title, app, false, &cid))
|
||||
{
|
||||
gprintf("No title found\n");
|
||||
return;
|
||||
@ -198,33 +176,34 @@ int Channels::GetLanguage(const char *lang)
|
||||
return CONF_LANG_ENGLISH; // Default to EN
|
||||
}
|
||||
|
||||
void Channels::Search(u32 channelType, string lang)
|
||||
void Channels::Search()
|
||||
{
|
||||
u32 count;
|
||||
u64* list = GetChannelList(&count);
|
||||
if (list == NULL)
|
||||
u64 *list = GetChannelList(&count);
|
||||
if(list == NULL)
|
||||
return;
|
||||
|
||||
int language = lang.size() == 0 ? CONF_GetLanguage() : GetLanguage(lang.c_str());
|
||||
int language = langCode.size() == 0 ? CONF_GetLanguage() : GetLanguage(langCode.c_str());
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
for(u32 i = 0; i < count; i++)
|
||||
{
|
||||
if (channelType == 0 || channelType == TITLE_UPPER(list[i]))
|
||||
u32 Type = TITLE_UPPER(list[i]);
|
||||
if(Type == SYSTEM_CHANNELS || Type == DOWNLOADED_CHANNELS || Type == GAME_CHANNELS)
|
||||
{
|
||||
Channel channel;
|
||||
if (GetChannelNameFromApp(list[i], channel.name, language))
|
||||
Channel CurrentChan;
|
||||
memset(&CurrentChan, 0, sizeof(Channel));
|
||||
if(GetChannelNameFromApp(list[i], CurrentChan.name, language))
|
||||
{
|
||||
channel.title = list[i];
|
||||
|
||||
u32 title_h = (u32)channel.title;
|
||||
sprintf(channel.id, "%c%c%c%c", title_h >> 24, title_h >> 16, title_h >> 8, title_h);
|
||||
|
||||
channels.push_back(channel);
|
||||
u32 Title = TITLE_LOWER(list[i]);
|
||||
if(Title == RF_NEWS_CHANNEL || Title == RF_FORECAST_CHANNEL)
|
||||
continue; //skip region free news and forecast channel
|
||||
CurrentChan.title = list[i];
|
||||
memcpy(CurrentChan.id, &Title, sizeof(CurrentChan.id));
|
||||
this->push_back(CurrentChan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(list);
|
||||
MEM2_free(list);
|
||||
}
|
||||
|
||||
wchar_t * Channels::GetName(int index)
|
||||
@ -233,28 +212,28 @@ wchar_t * Channels::GetName(int index)
|
||||
{
|
||||
return (wchar_t *) "";
|
||||
}
|
||||
return channels.at(index).name;
|
||||
return this->at(index).name;
|
||||
}
|
||||
|
||||
u32 Channels::Count()
|
||||
{
|
||||
return channels.size();
|
||||
return this->size();
|
||||
}
|
||||
|
||||
char * Channels::GetId(int index)
|
||||
{
|
||||
if (index < 0 || index > (int)Count() - 1) return (char *) "";
|
||||
return channels.at(index).id;
|
||||
return this->at(index).id;
|
||||
}
|
||||
|
||||
u64 Channels::GetTitle(int index)
|
||||
{
|
||||
if (index < 0 || index > (int)Count() - 1) return 0;
|
||||
return channels.at(index).title;
|
||||
return this->at(index).title;
|
||||
}
|
||||
|
||||
Channel * Channels::GetChannel(int index)
|
||||
{
|
||||
if (index < 0 || index > (int)Count() - 1) return NULL;
|
||||
return &channels.at(index);
|
||||
return &this->at(index);
|
||||
}
|
||||
|
@ -46,10 +46,10 @@ typedef struct
|
||||
wchar_t name[IMET_MAX_NAME_LEN+1];
|
||||
} Channel;
|
||||
|
||||
class Channels
|
||||
class Channels : private vector<Channel>
|
||||
{
|
||||
public:
|
||||
void Init(u32 channelType, string lang, bool reload = false);
|
||||
void Init(string lang);
|
||||
void Cleanup();
|
||||
|
||||
u32 Load(u64 title);
|
||||
@ -63,18 +63,14 @@ public:
|
||||
|
||||
void GetBanner(u64 title, bool imetOnly = false);
|
||||
private:
|
||||
bool init;
|
||||
u32 channelType;
|
||||
string langCode;
|
||||
|
||||
vector<Channel> channels;
|
||||
|
||||
int GetLanguage(const char *lang);
|
||||
u64* GetChannelList(u32* count);
|
||||
bool GetAppNameFromTmd(u64 title, char* app, bool dol = false, u32* bootcontent = NULL);
|
||||
bool GetChannelNameFromApp(u64 title, wchar_t* name, int language);
|
||||
|
||||
void Search(u32 channelType, string lang);
|
||||
void Search();
|
||||
};
|
||||
|
||||
extern Channels ChannelHandle;
|
||||
|
@ -245,7 +245,7 @@ void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const v
|
||||
}
|
||||
else if(Flow == COVERFLOW_CHANNEL)
|
||||
{
|
||||
ChannelHandle.Init(0, gameTDB_Language, true);
|
||||
ChannelHandle.Init(gameTDB_Language);
|
||||
Create_Channel_List();
|
||||
}
|
||||
else if(DeviceHandle.GetFSType(Device) != PART_FS_WBFS)
|
||||
|
@ -8,81 +8,17 @@
|
||||
#include "gecko/gecko.h"
|
||||
#include "memory/mem2.hpp"
|
||||
|
||||
static WIP_Code * CodeList = NULL;
|
||||
static WIP_Code *CodeList = NULL;
|
||||
static u32 CodesCount = 0;
|
||||
static u32 ProcessedLength = 0;
|
||||
static u32 Counter = 0;
|
||||
|
||||
void do_wip_code(u8 * dst, u32 len)
|
||||
u32 get_wip_count()
|
||||
{
|
||||
if(!CodeList)
|
||||
return;
|
||||
|
||||
if(Counter < 3)
|
||||
{
|
||||
Counter++;
|
||||
return;
|
||||
}
|
||||
|
||||
u32 i = 0;
|
||||
s32 n = 0;
|
||||
s32 offset = 0;
|
||||
|
||||
for(i = 0; i < CodesCount; i++)
|
||||
{
|
||||
for(n = 0; n < 4; n++)
|
||||
{
|
||||
offset = CodeList[i].offset+n-ProcessedLength;
|
||||
|
||||
if(offset < 0 || (u32)offset >= len)
|
||||
continue;
|
||||
|
||||
if(dst[offset] == ((u8 *)&CodeList[i].srcaddress)[n])
|
||||
{
|
||||
dst[offset] = ((u8 *)&CodeList[i].dstaddress)[n];
|
||||
gprintf("WIP: %08X Address Patched.\n", CodeList[i].offset + n);
|
||||
}
|
||||
else
|
||||
{
|
||||
gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n);
|
||||
gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessedLength += len;
|
||||
Counter++;
|
||||
return CodesCount;
|
||||
}
|
||||
|
||||
//! for internal patches only
|
||||
//! .wip files override internal patches
|
||||
//! the codelist has to be freed if the set fails
|
||||
//! if set was successful the codelist will be freed when it's done
|
||||
bool set_wip_list(WIP_Code * list, int size)
|
||||
WIP_Code *get_wip_list()
|
||||
{
|
||||
if(!CodeList && size > 0)
|
||||
{
|
||||
CodeList = list;
|
||||
CodesCount = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void wip_reset_counter()
|
||||
{
|
||||
ProcessedLength = 0;
|
||||
//alternative dols don't need a skip. only main.dol.
|
||||
Counter = 3;
|
||||
}
|
||||
|
||||
void free_wip()
|
||||
{
|
||||
if(CodeList)
|
||||
free(CodeList);
|
||||
|
||||
CodesCount = 0;
|
||||
ProcessedLength = 0;
|
||||
return CodeList;
|
||||
}
|
||||
|
||||
int load_wip_patches(u8 *dir, u8 *gameid)
|
||||
@ -101,7 +37,6 @@ int load_wip_patches(u8 *dir, u8 *gameid)
|
||||
snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
|
||||
fp = fopen(filepath, "rb");
|
||||
}
|
||||
|
||||
if(!fp)
|
||||
return -1;
|
||||
|
||||
@ -127,16 +62,13 @@ int load_wip_patches(u8 *dir, u8 *gameid)
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CodeList = tmp;
|
||||
|
||||
CodeList[CodesCount].offset = offset;
|
||||
CodeList[CodesCount].srcaddress = srcaddress;
|
||||
CodeList[CodesCount].dstaddress = dstaddress;
|
||||
CodesCount++;
|
||||
}
|
||||
fclose(fp);
|
||||
gprintf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,10 +12,8 @@ typedef struct
|
||||
u32 dstaddress;
|
||||
} WIP_Code;
|
||||
|
||||
bool set_wip_list(WIP_Code *list, int size);
|
||||
void wip_reset_counter();
|
||||
void free_wip();
|
||||
void do_wip_code(u8 *dst, u32 len);
|
||||
u32 get_wip_count();
|
||||
WIP_Code *get_wip_list();
|
||||
int load_wip_patches(u8 *dir, u8 *gameid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -77,7 +77,7 @@ void CMenu::_showConfig4(void)
|
||||
wstringEx channelName = m_loc.getWString(m_curLanguage, "disabled", L"Disabled");
|
||||
|
||||
NandHandle.Disable_Emu();
|
||||
ChannelHandle.Init(0, m_loc.getString(m_curLanguage, "gametdb_code", "EN"), true);
|
||||
ChannelHandle.Init(m_loc.getString(m_curLanguage, "gametdb_code", "EN"));
|
||||
amountOfChannels = ChannelHandle.Count();
|
||||
|
||||
string currentChanId = m_cfg.getString("GENERAL", "returnto" );
|
||||
|
@ -461,7 +461,7 @@ void CMenu::_showGameSettings(void)
|
||||
i = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u);
|
||||
m_btnMgr.setText(m_gameSettingsLblPatchVidModesVal, _t(CMenu::_vidModePatch[i].id, CMenu::_vidModePatch[i].text));
|
||||
|
||||
i = min((u32)m_gcfg2.getInt(id, "hooktype", 1), ARRAY_SIZE(CMenu::_hooktype) - 1u);
|
||||
i = min((u32)m_gcfg2.getInt(id, "hooktype", 0), ARRAY_SIZE(CMenu::_hooktype) - 1u);
|
||||
m_btnMgr.setText(m_gameSettingsLblHooktypeVal, _t(CMenu::_hooktype[i].id, CMenu::_hooktype[i].text));
|
||||
|
||||
m_btnMgr.setText(m_gameSettingsBtnCategoryMain, _fmt("cfgg16", wfmt(L"Select",i).c_str() ));
|
||||
|
@ -1217,9 +1217,9 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
}
|
||||
|
||||
bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false));
|
||||
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("GAMES", "cheat", false));
|
||||
bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false));
|
||||
|
||||
u8 patchVidMode = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u);
|
||||
u8 videoMode = (u8)min((u32)m_gcfg2.getInt(id, "video_mode", 0), ARRAY_SIZE(CMenu::_VideoModes) - 1u);
|
||||
videoMode = (videoMode == 0) ? (u8)min((u32)m_cfg.getInt("GENERAL", "video_mode", 0), ARRAY_SIZE(CMenu::_GlobalVideoModes) - 1) : videoMode-1;
|
||||
|
||||
@ -1296,13 +1296,11 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
|
||||
NandHandle.Do_Region_Change(id);
|
||||
}
|
||||
}
|
||||
|
||||
u8 patchVidMode = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u);
|
||||
hooktype = (u32) m_gcfg2.getInt(id, "hooktype", 0); // hooktype is defined in patchcode.h
|
||||
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("GAMES", "cheat", false));
|
||||
debuggerselect = m_gcfg2.getBool(id, "debugger", false) ? 1 : 0; // debuggerselect is defined in fst.h
|
||||
|
||||
if ((debuggerselect || cheat) && hooktype == 0) hooktype = 1;
|
||||
if (!debuggerselect && !cheat) hooktype = 0;
|
||||
hooktype = (u32)m_gcfg2.getInt(id, "hooktype", 0); // hooktype is defined in patchcode.h
|
||||
if(!debuggerselect && !cheat)
|
||||
hooktype = 0;
|
||||
|
||||
if(id == "RPWE41" || id == "RPWZ41" || id == "SPXP41") // Prince of Persia, Rival Swords
|
||||
debuggerselect = false;
|
||||
|
Loading…
Reference in New Issue
Block a user