-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:
fix94.1 2012-10-19 22:01:30 +00:00
parent c23025a63f
commit 3f55f129a6
23 changed files with 138 additions and 287 deletions

View File

@ -78,7 +78,7 @@ static u8 *GetDol(u32 bootcontent, u64 title)
return NULL; 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; bool ret = false;
@ -89,6 +89,7 @@ static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
u8 *data = ISFS_GetFile((u8 *) &filepath, &size, -1); u8 *data = ISFS_GetFile((u8 *) &filepath, &size, -1);
if(data == NULL || size < 0x208) if(data == NULL || size < 0x208)
return ret; return ret;
*IOS = data[0x18B];
_tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data); _tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data);
for(u16 i = 0; i < tmd_file->num_contents; ++i) for(u16 i = 0; i < tmd_file->num_contents; ++i)
@ -100,7 +101,6 @@ static bool GetAppNameFromTmd(bool dol, u32 *bootcontent, u64 title)
break; break;
} }
} }
free(data); free(data);
return ret; return ret;
@ -140,11 +140,11 @@ static u32 MoveDol(u8 *buffer)
return dolfile->entry_point; return dolfile->entry_point;
} }
u32 LoadChannel(u64 title) u32 LoadChannel(u64 title, u32 *IOS)
{ {
u32 entry = 0; u32 entry = 0;
GetAppNameFromTmd(true, &bootcontent, title); GetAppNameFromTmd(true, &bootcontent, title, IOS);
u8 *data = GetDol(bootcontent, title); u8 *data = GetDol(bootcontent, title);
entry = MoveDol(data); entry = MoveDol(data);
free(data); free(data);

View File

@ -15,6 +15,6 @@ typedef struct _dolheader
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString,
u8 patchVidModes, int aspectRatio, u64 title); u8 patchVidModes, int aspectRatio, u64 title);
u32 LoadChannel(u64 title); u32 LoadChannel(u64 title, u32 *IOS);
#endif /* __CHANHANDLE_HPP_ */ #endif /* __CHANHANDLE_HPP_ */

View File

@ -19,6 +19,7 @@
#include "cios.h" #include "cios.h"
#include "frag.h" #include "frag.h"
#include "wip.h"
typedef struct _the_CFG { typedef struct _the_CFG {
/* needed for wii games */ /* needed for wii games */
@ -28,6 +29,8 @@ typedef struct _the_CFG {
u32 wbfsPart; u32 wbfsPart;
u8 GameBootType; u8 GameBootType;
u8 mload_rev; u8 mload_rev;
WIP_Code *wip_list;
u32 wip_count;
/* needed for channels */ /* needed for channels */
u64 title; u64 title;
/* General Stuff */ /* General Stuff */
@ -37,8 +40,8 @@ typedef struct _the_CFG {
u8 patchVidMode; u8 patchVidMode;
u8 configbytes[2]; u8 configbytes[2];
u8 debugger; u8 debugger;
bool vipatch; u8 vipatch;
bool countryString; u8 countryString;
int aspectRatio; int aspectRatio;
void *codelist; void *codelist;
u8 *codelistend; u8 *codelistend;

View File

@ -11,6 +11,7 @@
#include "fst.h" #include "fst.h"
#include "wip.h" #include "wip.h"
#include "gecko.h" #include "gecko.h"
#include "memory.h"
#include "video_tinyload.h" #include "video_tinyload.h"
/* Apploader function pointers */ /* 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 patch_NoDiscinDrive(void *buffer, u32 len);
static void Anti_002_fix(void *Address, int Size); static void Anti_002_fix(void *Address, int Size);
static bool Remove_001_Protection(void *Address, int Size); static bool Remove_001_Protection(void *Address, int Size);
static bool PrinceOfPersiaPatch(); static void PrinceOfPersiaPatch();
static bool NewSuperMarioBrosPatch(); static void NewSuperMarioBrosPatch();
bool hookpatched = false; bool hookpatched = false;
s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) 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 */ /* Set entry point from apploader */
*entry = appldr_final(); *entry = appldr_final();
/* ERROR 002 fix (WiiPower) */
*(u32 *)0x80003140 = *(u32 *)0x80003188;
DCFlushRange((void*)0x80000000, 0x3f00);
return 0; return 0;
} }
void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio, u32 returnTo) 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 do_wip_code((u8 *)dst, len);
if((CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) || CurrentIOS.Type == IOS_TYPE_HERMES) Remove_001_Protection(dst, len);
patch_NoDiscinDrive(dst, len);
if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13) if(CurrentIOS.Type == IOS_TYPE_WANIN && CurrentIOS.Revision < 13)
Anti_002_fix(dst, len); 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); patchVideoModes(dst, len, vidMode, vmode, patchVidModes);
if(hooktype != 0 && dogamehooks(dst, len, false))
hookpatched = true;
if(vipatch) if(vipatch)
vidolpatcher(dst, len); vidolpatcher(dst, len);
if(configbytes[0] != 0xCD) if(configbytes[0] != 0xCD)
@ -122,7 +119,6 @@ void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipa
PatchAspectRatio(dst, len, aspectRatio); PatchAspectRatio(dst, len, aspectRatio);
if(returnTo) if(returnTo)
PatchReturnTo(dst, len, returnTo); PatchReturnTo(dst, len, returnTo);
do_wip_code((u8 *)dst, len);
} }
static void patch_NoDiscinDrive(void *buffer, u32 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) if(memcmp("SPX", (char*)Disc_ID, 3) != 0 && memcmp("RPW", (char*)Disc_ID, 3) != 0)
return false; return;
WIP_Code * CodeList = malloc(5 * sizeof(WIP_Code)); WIP_Code CodeList[5];
CodeList[0].offset = 0x007AAC6A; CodeList[0].offset = 0x007AAC6A;
CodeList[0].srcaddress = 0x7A6B6F6A; CodeList[0].srcaddress = 0x7A6B6F6A;
CodeList[0].dstaddress = 0x6F6A7A6B; CodeList[0].dstaddress = 0x6F6A7A6B;
@ -175,26 +171,14 @@ static bool PrinceOfPersiaPatch()
CodeList[4].offset = 0x007AAC9D; CodeList[4].offset = 0x007AAC9D;
CodeList[4].srcaddress = 0x82806F3F; CodeList[4].srcaddress = 0x82806F3F;
CodeList[4].dstaddress = 0x6F3F8280; CodeList[4].dstaddress = 0x6F3F8280;
set_wip_list(CodeList, 5);
if (set_wip_list(CodeList, 5) == false)
{
free(CodeList);
CodeList = NULL;
return false;
}
return true;
} }
static bool NewSuperMarioBrosPatch() static void NewSuperMarioBrosPatch()
{ {
WIP_Code * CodeList = NULL; WIP_Code CodeList[3];
if(memcmp("SMNE01", (char*)Disc_ID, 6) == 0)
if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0)
{ {
CodeList = malloc(3 * sizeof(WIP_Code));
if(!CodeList)
return false;
CodeList[0].offset = 0x001AB610; CodeList[0].offset = 0x001AB610;
CodeList[0].srcaddress = 0x9421FFD0; CodeList[0].srcaddress = 0x9421FFD0;
CodeList[0].dstaddress = 0x4E800020; CodeList[0].dstaddress = 0x4E800020;
@ -204,12 +188,10 @@ static bool NewSuperMarioBrosPatch()
CodeList[2].offset = 0x001CED6B; CodeList[2].offset = 0x001CED6B;
CodeList[2].srcaddress = 0xDA000000; CodeList[2].srcaddress = 0xDA000000;
CodeList[2].dstaddress = 0x71000000; 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].offset = 0x001AB750;
CodeList[0].srcaddress = 0x9421FFD0; CodeList[0].srcaddress = 0x9421FFD0;
CodeList[0].dstaddress = 0x4E800020; CodeList[0].dstaddress = 0x4E800020;
@ -219,12 +201,10 @@ static bool NewSuperMarioBrosPatch()
CodeList[2].offset = 0x001CEEA8; CodeList[2].offset = 0x001CEEA8;
CodeList[2].srcaddress = 0x388000DA; CodeList[2].srcaddress = 0x388000DA;
CodeList[2].dstaddress = 0x38800071; 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].offset = 0x001AB420;
CodeList[0].srcaddress = 0x9421FFD0; CodeList[0].srcaddress = 0x9421FFD0;
CodeList[0].dstaddress = 0x4E800020; CodeList[0].dstaddress = 0x4E800020;
@ -234,14 +214,8 @@ static bool NewSuperMarioBrosPatch()
CodeList[2].offset = 0x001CEB7B; CodeList[2].offset = 0x001CEB7B;
CodeList[2].srcaddress = 0xDA000000; CodeList[2].srcaddress = 0xDA000000;
CodeList[2].dstaddress = 0x71000000; 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) 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_end = Address + Size;
u8 *Addr; 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); memcpy(Addr, PatchData, sizeof PatchData);
return true; return true;

View File

@ -31,7 +31,7 @@ s32 Disc_Open()
return ret; return ret;
} }
void Disc_SetLowMem() void Disc_SetLowMem(u32 IOS)
{ {
/* Setup low memory */ /* Setup low memory */
*Sys_Magic = 0x0D15EA5E; // Standard Boot Code *Sys_Magic = 0x0D15EA5E; // Standard Boot Code
@ -52,6 +52,14 @@ void Disc_SetLowMem()
/* Copy disc ID */ /* Copy disc ID */
memcpy((void *)Online_Check, (void *)Disc_ID, 4); 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) s32 Disc_FindPartition(u64 *outbuf)

View File

@ -9,7 +9,7 @@ extern "C" {
s32 Disc_Open(); s32 Disc_Open();
s32 Disc_FindPartition(u64 *outbuf); s32 Disc_FindPartition(u64 *outbuf);
s32 Disc_SetUSB(const u8 *id, bool frag); s32 Disc_SetUSB(const u8 *id, bool frag);
void Disc_SetLowMem(); void Disc_SetLowMem(u32 IOS);
void Disc_SetTime(); void Disc_SetTime();
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg); GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);

View File

@ -35,6 +35,7 @@ using namespace std;
IOS_Info CurrentIOS; IOS_Info CurrentIOS;
/* Boot Variables */ /* Boot Variables */
u32 GameIOS = 0;
u32 vmode_reg = 0; u32 vmode_reg = 0;
entry_point p_entry; entry_point p_entry;
GXRModeObj *vmode = NULL; GXRModeObj *vmode = NULL;
@ -63,6 +64,7 @@ int main()
hooktype = normalCFG.hooktype; hooktype = normalCFG.hooktype;
debuggerselect = normalCFG.debugger; debuggerselect = normalCFG.debugger;
CurrentIOS = normalCFG.IOS; CurrentIOS = normalCFG.IOS;
set_wip_list(normalCFG.wip_list, normalCFG.wip_count);
app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize); app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize);
ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize); ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize);
frag_list = normalCFG.fragments; frag_list = normalCFG.fragments;
@ -86,11 +88,9 @@ int main()
} }
prog10(); prog10();
Disc_Open(); Disc_Open();
Disc_SetLowMem();
prog10();
u64 offset = 0; u64 offset = 0;
Disc_FindPartition(&offset); Disc_FindPartition(&offset);
WDVD_OpenPartition(offset); WDVD_OpenPartition(offset, &GameIOS);
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg); vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
prog10(); prog10();
Apploader_Run(&p_entry, normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, normalCFG.patchVidMode, 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) else if(normalCFG.BootType == TYPE_CHANNEL)
{ {
ISFS_Initialize(); ISFS_Initialize();
Disc_SetLowMem(); AppEntrypoint = LoadChannel(normalCFG.title, &GameIOS);
prog10();
AppEntrypoint = LoadChannel(normalCFG.title);
vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg); vmode = Disc_SelectVMode(normalCFG.vidMode, &vmode_reg);
PatchChannel(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString, PatchChannel(normalCFG.vidMode, vmode, normalCFG.vipatch, normalCFG.countryString,
normalCFG.patchVidMode, normalCFG.aspectRatio, normalCFG.title); normalCFG.patchVidMode, normalCFG.aspectRatio, normalCFG.title);
ISFS_Deinitialize(); ISFS_Deinitialize();
} }
gprintf("Entrypoint: %08x\n", AppEntrypoint); gprintf("Entrypoint: %08x, Requested Game IOS: %i\n", AppEntrypoint, GameIOS);
setprog(320); setprog(320);
/* Setup Low Memory */
Disc_SetLowMem(GameIOS);
/* Set time */ /* Set time */
Disc_SetTime(); Disc_SetTime();
/* Set an appropriate video mode */ /* Set an appropriate video mode */
video_clear();
Disc_SetVMode(vmode, vmode_reg); Disc_SetVMode(vmode, vmode_reg);
/* Shutdown IOS subsystems */ /* Shutdown IOS subsystems */

View File

@ -100,3 +100,11 @@ void video_init(void)
prog(0); 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;
}

View File

@ -16,6 +16,7 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void video_init(void); void video_init(void);
void video_clear(void);
void prog(int p); void prog(int p);
void prog10(void); void prog10(void);
void setprog(int p); void setprog(int p);

View File

@ -169,7 +169,7 @@ s32 WDVD_Eject(void)
return (ret == 1) ? 0 : -ret; return (ret == 1) ? 0 : -ret;
} }
s32 WDVD_OpenPartition(u64 offset) s32 WDVD_OpenPartition(u64 offset, u32 *IOS)
{ {
if (di_fd < 0) if (di_fd < 0)
return di_fd; return di_fd;
@ -196,7 +196,7 @@ s32 WDVD_OpenPartition(u64 offset)
Vectors[4].len = 0x20; Vectors[4].len = 0x20;
ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors); ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors);
*IOS = (u32)(Tmd_Buffer[0x18b]);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -15,7 +15,7 @@ s32 WDVD_Seek(u64);
s32 WDVD_Offset(u64); s32 WDVD_Offset(u64);
s32 WDVD_StopLaser(void); s32 WDVD_StopLaser(void);
s32 WDVD_StopMotor(void); s32 WDVD_StopMotor(void);
s32 WDVD_OpenPartition(u64 offset); s32 WDVD_OpenPartition(u64 offset, u32 *IOS);
s32 WDVD_ClosePartition(void); s32 WDVD_ClosePartition(void);
s32 WDVD_UnencryptedRead(void *, u32, u64); s32 WDVD_UnencryptedRead(void *, u32, u64);
s32 WDVD_Read(void *, u32, u64); s32 WDVD_Read(void *, u32, u64);

View File

@ -7,7 +7,7 @@
#include "wip.h" #include "wip.h"
#include "gecko.h" #include "gecko.h"
static WIP_Code * CodeList = NULL; static WIP_Code *CodeList = NULL;
static u32 CodesCount = 0; static u32 CodesCount = 0;
static u32 ProcessedLength = 0; static u32 ProcessedLength = 0;
static u32 Counter = 0; static u32 Counter = 0;
@ -56,15 +56,17 @@ void do_wip_code(u8 * dst, u32 len)
//! .wip files override internal patches //! .wip files override internal patches
//! the codelist has to be freed if the set fails //! the codelist has to be freed if the set fails
//! if set was successful the codelist will be freed when it's done //! 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; CodesCount = size;
return true; return true;
} }
return false; return false;
} }
@ -77,65 +79,8 @@ void wip_reset_counter()
void free_wip() void free_wip()
{ {
if(CodeList) if(CodeList != NULL)
free(CodeList); free(CodeList);
CodesCount = 0; CodesCount = 0;
ProcessedLength = 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;
}

View File

@ -19,6 +19,7 @@
#include "loader/cios.h" #include "loader/cios.h"
#include "loader/frag.h" #include "loader/frag.h"
#include "loader/wip.h"
typedef struct _the_CFG { typedef struct _the_CFG {
/* needed for wii games */ /* needed for wii games */
@ -28,6 +29,8 @@ typedef struct _the_CFG {
u32 wbfsPart; u32 wbfsPart;
u8 GameBootType; u8 GameBootType;
u8 mload_rev; u8 mload_rev;
WIP_Code *wip_list;
u32 wip_count;
/* needed for channels */ /* needed for channels */
u64 title; u64 title;
/* General Stuff */ /* General Stuff */

View File

@ -75,6 +75,8 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
normalCFG.gameconf = gameconf; normalCFG.gameconf = gameconf;
normalCFG.gameconfsize = gameconfsize; normalCFG.gameconfsize = gameconfsize;
normalCFG.BootType = BootType; normalCFG.BootType = BootType;
normalCFG.wip_list = get_wip_list();
normalCFG.wip_count = get_wip_count();
ShutdownBeforeExit(); ShutdownBeforeExit();
/* Copy CFG into new memory region */ /* Copy CFG into new memory region */

View File

@ -91,6 +91,8 @@ void Banner::ClearBanner()
free(opening); free(opening);
opening = NULL; opening = NULL;
opening_size = 0; opening_size = 0;
title = 0;
imet = NULL;
} }
bool Banner::IsValid() bool Banner::IsValid()

View File

@ -41,29 +41,23 @@
#define DOWNLOADED_CHANNELS 0x00010001 #define DOWNLOADED_CHANNELS 0x00010001
#define SYSTEM_CHANNELS 0x00010002 #define SYSTEM_CHANNELS 0x00010002
#define GAME_CHANNELS 0x00010004
#define RF_NEWS_CHANNEL 0x48414741 #define RF_NEWS_CHANNEL 0x48414741
#define RF_FORECAST_CHANNEL 0x48414641 #define RF_FORECAST_CHANNEL 0x48414641
Channels ChannelHandle; Channels ChannelHandle;
void Channels::Init(u32 channelType, string lang, bool reload) void Channels::Init(string lang)
{ {
if (reload) init = !reload; this->langCode = lang;
if (!init || channelType != this->channelType || this->clear();
lang != this->langCode) Search();
{
this->channelType = channelType;
this->langCode = lang;
this->channels.clear();
Search(channelType, lang);
init = true;
}
} }
void Channels::Cleanup() void Channels::Cleanup()
{ {
this->channels.clear(); this->clear();
} }
u8 Channels::GetRequestedIOS(u64 title) u8 Channels::GetRequestedIOS(u64 title)
@ -86,41 +80,24 @@ u8 Channels::GetRequestedIOS(u64 title)
return IOS; return IOS;
} }
u64* Channels::GetChannelList(u32* count) u64 *Channels::GetChannelList(u32 *count)
{ {
*count = 0;
u32 countall; 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)); u64 *titles = (u64*)MEM2_alloc(countall*sizeof(u64));
if (!titles) if(titles == NULL)
return NULL; return NULL;
if(ES_GetTitles(titles, countall) < 0) if(ES_GetTitles(titles, countall) < 0)
{ {
free(titles); MEM2_free(titles);
return NULL; return NULL;
} }
*count = countall;
u64* channels = (u64*)MEM2_alloc(countall * sizeof(u64)); return titles;
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));
} }
bool Channels::GetAppNameFromTmd(u64 title, char *app, bool dol, u32 *bootcontent) 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) void Channels::GetBanner(u64 title, bool imetOnly)
{ {
CurrentBanner.ClearBanner();
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
u32 cid; u32 cid;
if (!GetAppNameFromTmd(title, app, false, &cid)) if(!GetAppNameFromTmd(title, app, false, &cid))
{ {
gprintf("No title found\n"); gprintf("No title found\n");
return; return;
@ -198,33 +176,34 @@ int Channels::GetLanguage(const char *lang)
return CONF_LANG_ENGLISH; // Default to EN return CONF_LANG_ENGLISH; // Default to EN
} }
void Channels::Search(u32 channelType, string lang) void Channels::Search()
{ {
u32 count; u32 count;
u64* list = GetChannelList(&count); u64 *list = GetChannelList(&count);
if (list == NULL) if(list == NULL)
return; 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; Channel CurrentChan;
if (GetChannelNameFromApp(list[i], channel.name, language)) memset(&CurrentChan, 0, sizeof(Channel));
if(GetChannelNameFromApp(list[i], CurrentChan.name, language))
{ {
channel.title = list[i]; u32 Title = TITLE_LOWER(list[i]);
if(Title == RF_NEWS_CHANNEL || Title == RF_FORECAST_CHANNEL)
u32 title_h = (u32)channel.title; continue; //skip region free news and forecast channel
sprintf(channel.id, "%c%c%c%c", title_h >> 24, title_h >> 16, title_h >> 8, title_h); CurrentChan.title = list[i];
memcpy(CurrentChan.id, &Title, sizeof(CurrentChan.id));
channels.push_back(channel); this->push_back(CurrentChan);
} }
} }
} }
MEM2_free(list);
free(list);
} }
wchar_t * Channels::GetName(int index) wchar_t * Channels::GetName(int index)
@ -233,28 +212,28 @@ wchar_t * Channels::GetName(int index)
{ {
return (wchar_t *) ""; return (wchar_t *) "";
} }
return channels.at(index).name; return this->at(index).name;
} }
u32 Channels::Count() u32 Channels::Count()
{ {
return channels.size(); return this->size();
} }
char * Channels::GetId(int index) char * Channels::GetId(int index)
{ {
if (index < 0 || index > (int)Count() - 1) return (char *) ""; if (index < 0 || index > (int)Count() - 1) return (char *) "";
return channels.at(index).id; return this->at(index).id;
} }
u64 Channels::GetTitle(int index) u64 Channels::GetTitle(int index)
{ {
if (index < 0 || index > (int)Count() - 1) return 0; if (index < 0 || index > (int)Count() - 1) return 0;
return channels.at(index).title; return this->at(index).title;
} }
Channel * Channels::GetChannel(int index) Channel * Channels::GetChannel(int index)
{ {
if (index < 0 || index > (int)Count() - 1) return NULL; if (index < 0 || index > (int)Count() - 1) return NULL;
return &channels.at(index); return &this->at(index);
} }

View File

@ -46,10 +46,10 @@ typedef struct
wchar_t name[IMET_MAX_NAME_LEN+1]; wchar_t name[IMET_MAX_NAME_LEN+1];
} Channel; } Channel;
class Channels class Channels : private vector<Channel>
{ {
public: public:
void Init(u32 channelType, string lang, bool reload = false); void Init(string lang);
void Cleanup(); void Cleanup();
u32 Load(u64 title); u32 Load(u64 title);
@ -63,18 +63,14 @@ public:
void GetBanner(u64 title, bool imetOnly = false); void GetBanner(u64 title, bool imetOnly = false);
private: private:
bool init;
u32 channelType;
string langCode; string langCode;
vector<Channel> channels;
int GetLanguage(const char *lang); int GetLanguage(const char *lang);
u64* GetChannelList(u32* count); u64* GetChannelList(u32* count);
bool GetAppNameFromTmd(u64 title, char* app, bool dol = false, u32* bootcontent = NULL); bool GetAppNameFromTmd(u64 title, char* app, bool dol = false, u32* bootcontent = NULL);
bool GetChannelNameFromApp(u64 title, wchar_t* name, int language); bool GetChannelNameFromApp(u64 title, wchar_t* name, int language);
void Search(u32 channelType, string lang); void Search();
}; };
extern Channels ChannelHandle; extern Channels ChannelHandle;

View File

@ -245,7 +245,7 @@ void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const v
} }
else if(Flow == COVERFLOW_CHANNEL) else if(Flow == COVERFLOW_CHANNEL)
{ {
ChannelHandle.Init(0, gameTDB_Language, true); ChannelHandle.Init(gameTDB_Language);
Create_Channel_List(); Create_Channel_List();
} }
else if(DeviceHandle.GetFSType(Device) != PART_FS_WBFS) else if(DeviceHandle.GetFSType(Device) != PART_FS_WBFS)

View File

@ -8,81 +8,17 @@
#include "gecko/gecko.h" #include "gecko/gecko.h"
#include "memory/mem2.hpp" #include "memory/mem2.hpp"
static WIP_Code * CodeList = NULL; static WIP_Code *CodeList = NULL;
static u32 CodesCount = 0; 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 CodesCount;
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++;
} }
//! for internal patches only WIP_Code *get_wip_list()
//! .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)
{ {
if(!CodeList && size > 0) return CodeList;
{
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;
} }
int load_wip_patches(u8 *dir, u8 *gameid) 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); snprintf(filepath, sizeof(filepath), "%s/%s.wip", dir, GameID);
fp = fopen(filepath, "rb"); fp = fopen(filepath, "rb");
} }
if(!fp) if(!fp)
return -1; return -1;
@ -127,16 +62,13 @@ int load_wip_patches(u8 *dir, u8 *gameid)
fclose(fp); fclose(fp);
return -1; return -1;
} }
CodeList = tmp; CodeList = tmp;
CodeList[CodesCount].offset = offset; CodeList[CodesCount].offset = offset;
CodeList[CodesCount].srcaddress = srcaddress; CodeList[CodesCount].srcaddress = srcaddress;
CodeList[CodesCount].dstaddress = dstaddress; CodeList[CodesCount].dstaddress = dstaddress;
CodesCount++; CodesCount++;
} }
fclose(fp); fclose(fp);
gprintf("\n");
return 0; return 0;
} }

View File

@ -12,10 +12,8 @@ typedef struct
u32 dstaddress; u32 dstaddress;
} WIP_Code; } WIP_Code;
bool set_wip_list(WIP_Code *list, int size); u32 get_wip_count();
void wip_reset_counter(); WIP_Code *get_wip_list();
void free_wip();
void do_wip_code(u8 *dst, u32 len);
int load_wip_patches(u8 *dir, u8 *gameid); int load_wip_patches(u8 *dir, u8 *gameid);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -77,7 +77,7 @@ void CMenu::_showConfig4(void)
wstringEx channelName = m_loc.getWString(m_curLanguage, "disabled", L"Disabled"); wstringEx channelName = m_loc.getWString(m_curLanguage, "disabled", L"Disabled");
NandHandle.Disable_Emu(); 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(); amountOfChannels = ChannelHandle.Count();
string currentChanId = m_cfg.getString("GENERAL", "returnto" ); string currentChanId = m_cfg.getString("GENERAL", "returnto" );

View File

@ -461,7 +461,7 @@ void CMenu::_showGameSettings(void)
i = min((u32)m_gcfg2.getInt(id, "patch_video_modes", 0), ARRAY_SIZE(CMenu::_vidModePatch) - 1u); 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)); 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_gameSettingsLblHooktypeVal, _t(CMenu::_hooktype[i].id, CMenu::_hooktype[i].text));
m_btnMgr.setText(m_gameSettingsBtnCategoryMain, _fmt("cfgg16", wfmt(L"Select",i).c_str() )); m_btnMgr.setText(m_gameSettingsBtnCategoryMain, _fmt("cfgg16", wfmt(L"Select",i).c_str() ));

View File

@ -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 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)); 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); 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; 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); NandHandle.Do_Region_Change(id);
} }
} }
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("GAMES", "cheat", false));
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
debuggerselect = m_gcfg2.getBool(id, "debugger", false) ? 1 : 0; // debuggerselect is defined in fst.h debuggerselect = m_gcfg2.getBool(id, "debugger", false) ? 1 : 0; // debuggerselect is defined in fst.h
hooktype = (u32)m_gcfg2.getInt(id, "hooktype", 0); // hooktype is defined in patchcode.h
if ((debuggerselect || cheat) && hooktype == 0) hooktype = 1; if(!debuggerselect && !cheat)
if (!debuggerselect && !cheat) hooktype = 0; hooktype = 0;
if(id == "RPWE41" || id == "RPWZ41" || id == "SPXP41") // Prince of Persia, Rival Swords if(id == "RPWE41" || id == "RPWZ41" || id == "SPXP41") // Prince of Persia, Rival Swords
debuggerselect = false; debuggerselect = false;