mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-12-23 02:11:55 +01:00
*Added PoP Patch to apply automatically. The internal patch is not applied if you have a .wip file for PoP. So the .wip patches override the internal patch.
*Cleanup inside the apploader
This commit is contained in:
parent
1e9951f586
commit
a5ca9235ca
@ -2,8 +2,8 @@
|
||||
<app version="1">
|
||||
<name> USB Loader GX</name>
|
||||
<coder>USB Loader GX Team</coder>
|
||||
<version>1.0 r934</version>
|
||||
<release_date>201005300653</release_date>
|
||||
<version>1.0 r935</version>
|
||||
<release_date>201005300742</release_date>
|
||||
<short_description>Loads games from USB-devices</short_description>
|
||||
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
|
||||
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,185 +1,188 @@
|
||||
|
||||
#include "mem2.h"
|
||||
#include "mem2alloc.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MEM2_PRIORITY_SIZE 0x40
|
||||
|
||||
// Forbid the use of MEM2 through malloc
|
||||
u32 MALLOC_MEM2 = 0;
|
||||
|
||||
static CMEM2Alloc g_mem2gp;
|
||||
|
||||
void MEM2_init(unsigned int mem2Size)
|
||||
{
|
||||
g_mem2gp.init(mem2Size);
|
||||
}
|
||||
|
||||
void MEM2_cleanup(void)
|
||||
{
|
||||
g_mem2gp.cleanup();
|
||||
}
|
||||
|
||||
extern "C" void *MEM2_alloc(unsigned int s)
|
||||
{
|
||||
return g_mem2gp.allocate(s);
|
||||
}
|
||||
|
||||
extern "C" void MEM2_free(void *p)
|
||||
{
|
||||
g_mem2gp.release(p);
|
||||
}
|
||||
|
||||
extern "C" void *MEM2_realloc(void *p, unsigned int s)
|
||||
{
|
||||
return g_mem2gp.reallocate(p, s);
|
||||
}
|
||||
|
||||
extern "C" unsigned int MEM2_usableSize(void *p)
|
||||
{
|
||||
return CMEM2Alloc::usableSize(p);
|
||||
}
|
||||
|
||||
// Give priority to MEM2 for big allocations
|
||||
// Used for saving some space in malloc, which is required for 2 reasons :
|
||||
// - decent speed on small and frequent allocations
|
||||
// - newlib uses its malloc internally (for *printf for example) so it should always have some memory left
|
||||
bool g_bigGoesToMem2 = false;
|
||||
|
||||
void MEM2_takeBigOnes(bool b)
|
||||
{
|
||||
g_bigGoesToMem2 = b;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
extern __typeof(malloc) __real_malloc;
|
||||
extern __typeof(calloc) __real_calloc;
|
||||
extern __typeof(realloc) __real_realloc;
|
||||
extern __typeof(memalign) __real_memalign;
|
||||
extern __typeof(free) __real_free;
|
||||
extern __typeof(malloc_usable_size) __real_malloc_usable_size;
|
||||
|
||||
void *__wrap_malloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
p = MEM2_alloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
return __real_malloc(size);
|
||||
}
|
||||
p = __real_malloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
return MEM2_alloc(size);
|
||||
}
|
||||
|
||||
void *__wrap_calloc(size_t n, size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
p = MEM2_alloc(n * size);
|
||||
if (p != 0)
|
||||
{
|
||||
memset(p, 0, n * size);
|
||||
return p;
|
||||
}
|
||||
return __real_calloc(n, size);
|
||||
}
|
||||
p = __real_calloc(n, size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
p = MEM2_alloc(n * size);
|
||||
if (p != 0) {
|
||||
memset(p, 0, n * size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *__wrap_memalign(size_t a, size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
if (a <= 32 && 32 % a == 0)
|
||||
{
|
||||
p = MEM2_alloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return __real_memalign(a, size);
|
||||
}
|
||||
p = __real_memalign(a, size);
|
||||
if (p != 0 || a > 32 || 32 % a != 0) {
|
||||
return p;
|
||||
}
|
||||
|
||||
return MEM2_alloc(size);
|
||||
}
|
||||
|
||||
void __wrap_free(void *p)
|
||||
{
|
||||
if (((u32)p & 0x10000000) != 0) {
|
||||
MEM2_free(p);
|
||||
} else {
|
||||
__real_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void *__wrap_realloc(void *p, size_t size)
|
||||
{
|
||||
void *n;
|
||||
// ptr from mem2
|
||||
if (((u32)p & 0x10000000) != 0 || (p == 0 && g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE))
|
||||
{
|
||||
n = MEM2_realloc(p, size);
|
||||
if (n != 0) {
|
||||
return n;
|
||||
}
|
||||
n = __real_malloc(size);
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (p != 0)
|
||||
{
|
||||
memcpy(n, p, MEM2_usableSize(p) < size ? MEM2_usableSize(p) : size);
|
||||
MEM2_free(p);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
// ptr from malloc
|
||||
n = __real_realloc(p, size);
|
||||
if (n != 0) {
|
||||
return n;
|
||||
}
|
||||
n = MEM2_alloc(size);
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (p != 0)
|
||||
{
|
||||
memcpy(n, p, __real_malloc_usable_size(p) < size ? __real_malloc_usable_size(p) : size);
|
||||
__real_free(p);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t __wrap_malloc_usable_size(void *p)
|
||||
{
|
||||
if (((u32)p & 0x10000000) != 0)
|
||||
return MEM2_usableSize(p);
|
||||
return __real_malloc_usable_size(p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "mem2.h"
|
||||
#include "mem2alloc.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MEM2_PRIORITY_SIZE 0x40
|
||||
|
||||
// Forbid the use of MEM2 through malloc
|
||||
u32 MALLOC_MEM2 = 0;
|
||||
|
||||
static CMEM2Alloc g_mem2gp;
|
||||
|
||||
void MEM2_init(unsigned int mem2Size)
|
||||
{
|
||||
g_mem2gp.init(mem2Size);
|
||||
}
|
||||
|
||||
void MEM2_cleanup(void)
|
||||
{
|
||||
g_mem2gp.cleanup();
|
||||
}
|
||||
|
||||
extern "C" void *MEM2_alloc(unsigned int s)
|
||||
{
|
||||
return g_mem2gp.allocate(s);
|
||||
}
|
||||
|
||||
extern "C" void MEM2_free(void *p)
|
||||
{
|
||||
g_mem2gp.release(p);
|
||||
}
|
||||
|
||||
extern "C" void *MEM2_realloc(void *p, unsigned int s)
|
||||
{
|
||||
return g_mem2gp.reallocate(p, s);
|
||||
}
|
||||
|
||||
extern "C" unsigned int MEM2_usableSize(void *p)
|
||||
{
|
||||
return CMEM2Alloc::usableSize(p);
|
||||
}
|
||||
|
||||
// Give priority to MEM2 for big allocations
|
||||
// Used for saving some space in malloc, which is required for 2 reasons :
|
||||
// - decent speed on small and frequent allocations
|
||||
// - newlib uses its malloc internally (for *printf for example) so it should always have some memory left
|
||||
bool g_bigGoesToMem2 = false;
|
||||
|
||||
void MEM2_takeBigOnes(bool b)
|
||||
{
|
||||
g_bigGoesToMem2 = b;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
extern __typeof(malloc) __real_malloc;
|
||||
extern __typeof(calloc) __real_calloc;
|
||||
extern __typeof(realloc) __real_realloc;
|
||||
extern __typeof(memalign) __real_memalign;
|
||||
extern __typeof(free) __real_free;
|
||||
extern __typeof(malloc_usable_size) __real_malloc_usable_size;
|
||||
|
||||
void *__wrap_malloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
p = MEM2_alloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
return __real_malloc(size);
|
||||
}
|
||||
p = __real_malloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
return MEM2_alloc(size);
|
||||
}
|
||||
|
||||
void *__wrap_calloc(size_t n, size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
p = MEM2_alloc(n * size);
|
||||
if (p != 0)
|
||||
{
|
||||
memset(p, 0, n * size);
|
||||
return p;
|
||||
}
|
||||
return __real_calloc(n, size);
|
||||
}
|
||||
p = __real_calloc(n, size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
p = MEM2_alloc(n * size);
|
||||
if (p != 0) {
|
||||
memset(p, 0, n * size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *__wrap_memalign(size_t a, size_t size)
|
||||
{
|
||||
void *p;
|
||||
if (g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE)
|
||||
{
|
||||
if (a <= 32 && 32 % a == 0)
|
||||
{
|
||||
p = MEM2_alloc(size);
|
||||
if (p != 0) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return __real_memalign(a, size);
|
||||
}
|
||||
p = __real_memalign(a, size);
|
||||
if (p != 0 || a > 32 || 32 % a != 0) {
|
||||
return p;
|
||||
}
|
||||
|
||||
return MEM2_alloc(size);
|
||||
}
|
||||
|
||||
void __wrap_free(void *p)
|
||||
{
|
||||
if(!p)
|
||||
return;
|
||||
|
||||
if (((u32)p & 0x10000000) != 0) {
|
||||
MEM2_free(p);
|
||||
} else {
|
||||
__real_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
void *__wrap_realloc(void *p, size_t size)
|
||||
{
|
||||
void *n;
|
||||
// ptr from mem2
|
||||
if (((u32)p & 0x10000000) != 0 || (p == 0 && g_bigGoesToMem2 && size > MEM2_PRIORITY_SIZE))
|
||||
{
|
||||
n = MEM2_realloc(p, size);
|
||||
if (n != 0) {
|
||||
return n;
|
||||
}
|
||||
n = __real_malloc(size);
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (p != 0)
|
||||
{
|
||||
memcpy(n, p, MEM2_usableSize(p) < size ? MEM2_usableSize(p) : size);
|
||||
MEM2_free(p);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
// ptr from malloc
|
||||
n = __real_realloc(p, size);
|
||||
if (n != 0) {
|
||||
return n;
|
||||
}
|
||||
n = MEM2_alloc(size);
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (p != 0)
|
||||
{
|
||||
memcpy(n, p, __real_malloc_usable_size(p) < size ? __real_malloc_usable_size(p) : size);
|
||||
__real_free(p);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t __wrap_malloc_usable_size(void *p)
|
||||
{
|
||||
if (((u32)p & 0x10000000) != 0)
|
||||
return MEM2_usableSize(p);
|
||||
return __real_malloc_usable_size(p);
|
||||
}
|
||||
|
||||
}
|
||||
|
19
source/patches/dolpatcher.c
Normal file
19
source/patches/dolpatcher.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <string.h>
|
||||
#include <gctypes.h>
|
||||
|
||||
bool PatchDOL(u8 * Address, int Size, const u8 * SearchPattern, int SearchSize, const u8 * PatchData, int PatchSize)
|
||||
{
|
||||
u8 * Addr = Address;
|
||||
u8 * Addr_end = Address+Size;
|
||||
|
||||
while(Addr <= Addr_end-SearchSize)
|
||||
{
|
||||
if(memcmp(Addr, SearchPattern, SearchSize)==0)
|
||||
{
|
||||
memcpy(Addr, PatchData, PatchSize);
|
||||
return true;
|
||||
}
|
||||
Addr += 4;
|
||||
}
|
||||
return false;
|
||||
}
|
8
source/patches/dolpatcher.h
Normal file
8
source/patches/dolpatcher.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef DOLPATCHER_C_
|
||||
#define DOLPATCHER_C_
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
bool PatchDOL(u8 * Address, int Size, const u8 * SearchPattern, int SearchSize, const u8 * PatchData, int PatchSize);
|
||||
|
||||
#endif
|
269
source/patches/gamepatches.c
Normal file
269
source/patches/gamepatches.c
Normal file
@ -0,0 +1,269 @@
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include "dolpatcher.h"
|
||||
#include "wip.h"
|
||||
|
||||
/** Anti 002 fix for IOS 249 rev > 12 thanks to WiiPower **/
|
||||
bool Anti_002_fix(u8 * Address, int Size)
|
||||
{
|
||||
u8 SearchPattern[12] = { 0x2C, 0x00, 0x00, 0x00, 0x48, 0x00, 0x02, 0x14, 0x3C, 0x60, 0x80, 0x00 };
|
||||
u8 PatchData[12] = { 0x2C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x02, 0x14, 0x3C, 0x60, 0x80, 0x00 };
|
||||
return PatchDOL(Address, Size, (const u8 *) &SearchPattern, sizeof(SearchPattern), (const u8 *) &PatchData, sizeof(PatchData));
|
||||
}
|
||||
|
||||
/** Thanks to WiiPower **/
|
||||
bool NSMBPatch(u8 * Address, int Size)
|
||||
{
|
||||
if (IOS_GetVersion() == 222 || IOS_GetVersion() == 223) return false; // Don't use this when using Hermes, it'll use the BCA fix instead...
|
||||
|
||||
if (memcmp("SMNE", (char *)0x80000000, 4) == 0)
|
||||
{
|
||||
u8 SearchPattern[32] = { 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
u8 PatchData[32] = { 0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
return PatchDOL(Address, Size, (const u8 *) &SearchPattern, sizeof(SearchPattern), (const u8 *) &PatchData, sizeof(PatchData));
|
||||
|
||||
}
|
||||
else if (memcmp("SMN", (char *)0x80000000, 3) == 0)
|
||||
{
|
||||
u8 SearchPattern[4] = { 0x7A, 0x6B, 0x6F, 0x6A };
|
||||
u8 PatchData[32] = { 0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD9, 0x39, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
return PatchDOL(Address, Size, (const u8 *) &SearchPattern, sizeof(SearchPattern), (const u8 *) &PatchData, sizeof(PatchData));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PoPPatch()
|
||||
{
|
||||
if (memcmp("SPX", (char *)0x80000000, 3) == 0 || memcmp("RPW", (char *)0x80000000, 3) == 0)
|
||||
{
|
||||
WIP_Code * CodeList = malloc(5*sizeof(WIP_Code));
|
||||
CodeList[0].offset = 0x007AAC6A; CodeList[0].srcaddress = 0x7A6B6F6A; CodeList[0].dstaddress = 0x6F6A7A6B;
|
||||
CodeList[1].offset = 0x007AAC75; CodeList[1].srcaddress = 0x7C7A6939; CodeList[1].dstaddress = 0x69397C7A;
|
||||
CodeList[2].offset = 0x007AAC82; CodeList[2].srcaddress = 0x7376686B; CodeList[2].dstaddress = 0x686B7376;
|
||||
CodeList[3].offset = 0x007AAC92; CodeList[3].srcaddress = 0x80717570; CodeList[3].dstaddress = 0x75708071;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Insert the individual gamepatches above with the patterns and patch data **/
|
||||
/** Following is only the VideoPatcher **/
|
||||
|
||||
#if 0 /** Isn't used right now **/
|
||||
|
||||
static GXRModeObj* vmodes[] = {
|
||||
&TVNtsc240Ds,
|
||||
&TVNtsc240DsAa,
|
||||
&TVNtsc240Int,
|
||||
&TVNtsc240IntAa,
|
||||
&TVNtsc480IntDf,
|
||||
&TVNtsc480IntAa,
|
||||
&TVNtsc480Prog,
|
||||
&TVMpal480IntDf,
|
||||
&TVPal264Ds,
|
||||
&TVPal264DsAa,
|
||||
&TVPal264Int,
|
||||
&TVPal264IntAa,
|
||||
&TVPal524IntAa,
|
||||
&TVPal528Int,
|
||||
&TVPal528IntDf,
|
||||
&TVPal574IntDfScale,
|
||||
&TVEurgb60Hz240Ds,
|
||||
&TVEurgb60Hz240DsAa,
|
||||
&TVEurgb60Hz240Int,
|
||||
&TVEurgb60Hz240IntAa,
|
||||
&TVEurgb60Hz480Int,
|
||||
&TVEurgb60Hz480IntDf,
|
||||
&TVEurgb60Hz480IntAa,
|
||||
&TVEurgb60Hz480Prog,
|
||||
&TVEurgb60Hz480ProgSoft,
|
||||
&TVEurgb60Hz480ProgAa
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static GXRModeObj* PAL2NTSC[]={
|
||||
&TVMpal480IntDf, &TVNtsc480IntDf,
|
||||
&TVPal264Ds, &TVNtsc240Ds,
|
||||
&TVPal264DsAa, &TVNtsc240DsAa,
|
||||
&TVPal264Int, &TVNtsc240Int,
|
||||
&TVPal264IntAa, &TVNtsc240IntAa,
|
||||
&TVPal524IntAa, &TVNtsc480IntAa,
|
||||
&TVPal528Int, &TVNtsc480IntAa,
|
||||
&TVPal528IntDf, &TVNtsc480IntDf,
|
||||
&TVPal574IntDfScale, &TVNtsc480IntDf,
|
||||
&TVEurgb60Hz240Ds, &TVNtsc240Ds,
|
||||
&TVEurgb60Hz240DsAa, &TVNtsc240DsAa,
|
||||
&TVEurgb60Hz240Int, &TVNtsc240Int,
|
||||
&TVEurgb60Hz240IntAa, &TVNtsc240IntAa,
|
||||
&TVEurgb60Hz480Int, &TVNtsc480IntAa,
|
||||
&TVEurgb60Hz480IntDf, &TVNtsc480IntDf,
|
||||
&TVEurgb60Hz480IntAa, &TVNtsc480IntAa,
|
||||
&TVEurgb60Hz480Prog, &TVNtsc480Prog,
|
||||
&TVEurgb60Hz480ProgSoft,&TVNtsc480Prog,
|
||||
&TVEurgb60Hz480ProgAa, &TVNtsc480Prog,
|
||||
0,0
|
||||
};
|
||||
|
||||
static GXRModeObj* NTSC2PAL[]={
|
||||
&TVNtsc240Ds, &TVPal264Ds,
|
||||
&TVNtsc240DsAa, &TVPal264DsAa,
|
||||
&TVNtsc240Int, &TVPal264Int,
|
||||
&TVNtsc240IntAa, &TVPal264IntAa,
|
||||
&TVNtsc480IntDf, &TVPal528IntDf,
|
||||
&TVNtsc480IntAa, &TVPal524IntAa,
|
||||
&TVNtsc480Prog, &TVPal528IntDf,
|
||||
0,0
|
||||
};
|
||||
|
||||
static GXRModeObj* NTSC2PAL60[]={
|
||||
&TVNtsc240Ds, &TVEurgb60Hz240Ds,
|
||||
&TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
||||
&TVNtsc240Int, &TVEurgb60Hz240Int,
|
||||
&TVNtsc240IntAa, &TVEurgb60Hz240IntAa,
|
||||
&TVNtsc480IntDf, &TVEurgb60Hz480IntDf,
|
||||
&TVNtsc480IntAa, &TVEurgb60Hz480IntAa,
|
||||
&TVNtsc480Prog, &TVEurgb60Hz480Prog,
|
||||
0,0
|
||||
};
|
||||
|
||||
static bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2)
|
||||
{
|
||||
if (mode1->viTVMode != mode2->viTVMode || mode1->fbWidth != mode2->fbWidth || mode1->efbHeight != mode2->efbHeight || mode1->xfbHeight != mode2->xfbHeight ||
|
||||
mode1->viXOrigin != mode2->viXOrigin || mode1->viYOrigin != mode2->viYOrigin || mode1->viWidth != mode2->viWidth || mode1->viHeight != mode2->viHeight ||
|
||||
mode1->xfbMode != mode2->xfbMode || mode1->field_rendering != mode2->field_rendering || mode1->aa != mode2->aa || mode1->sample_pattern[0][0] != mode2->sample_pattern[0][0] ||
|
||||
mode1->sample_pattern[1][0] != mode2->sample_pattern[1][0] || mode1->sample_pattern[2][0] != mode2->sample_pattern[2][0] ||
|
||||
mode1->sample_pattern[3][0] != mode2->sample_pattern[3][0] || mode1->sample_pattern[4][0] != mode2->sample_pattern[4][0] ||
|
||||
mode1->sample_pattern[5][0] != mode2->sample_pattern[5][0] || mode1->sample_pattern[6][0] != mode2->sample_pattern[6][0] ||
|
||||
mode1->sample_pattern[7][0] != mode2->sample_pattern[7][0] || mode1->sample_pattern[8][0] != mode2->sample_pattern[8][0] ||
|
||||
mode1->sample_pattern[9][0] != mode2->sample_pattern[9][0] || mode1->sample_pattern[10][0] != mode2->sample_pattern[10][0] ||
|
||||
mode1->sample_pattern[11][0] != mode2->sample_pattern[11][0] || mode1->sample_pattern[0][1] != mode2->sample_pattern[0][1] ||
|
||||
mode1->sample_pattern[1][1] != mode2->sample_pattern[1][1] || mode1->sample_pattern[2][1] != mode2->sample_pattern[2][1] ||
|
||||
mode1->sample_pattern[3][1] != mode2->sample_pattern[3][1] || mode1->sample_pattern[4][1] != mode2->sample_pattern[4][1] ||
|
||||
mode1->sample_pattern[5][1] != mode2->sample_pattern[5][1] || mode1->sample_pattern[6][1] != mode2->sample_pattern[6][1] ||
|
||||
mode1->sample_pattern[7][1] != mode2->sample_pattern[7][1] || mode1->sample_pattern[8][1] != mode2->sample_pattern[8][1] ||
|
||||
mode1->sample_pattern[9][1] != mode2->sample_pattern[9][1] || mode1->sample_pattern[10][1] != mode2->sample_pattern[10][1] ||
|
||||
mode1->sample_pattern[11][1] != mode2->sample_pattern[11][1] || mode1->vfilter[0] != mode2->vfilter[0] ||
|
||||
mode1->vfilter[1] != mode2->vfilter[1] || mode1->vfilter[2] != mode2->vfilter[2] || mode1->vfilter[3] != mode2->vfilter[3] || mode1->vfilter[4] != mode2->vfilter[4] ||
|
||||
mode1->vfilter[5] != mode2->vfilter[5] || mode1->vfilter[6] != mode2->vfilter[6] ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void patch_videomode(GXRModeObj* mode1, GXRModeObj* mode2)
|
||||
{
|
||||
mode1->viTVMode = mode2->viTVMode;
|
||||
mode1->fbWidth = mode2->fbWidth;
|
||||
mode1->efbHeight = mode2->efbHeight;
|
||||
mode1->xfbHeight = mode2->xfbHeight;
|
||||
mode1->viXOrigin = mode2->viXOrigin;
|
||||
mode1->viYOrigin = mode2->viYOrigin;
|
||||
mode1->viWidth = mode2->viWidth;
|
||||
mode1->viHeight = mode2->viHeight;
|
||||
mode1->xfbMode = mode2->xfbMode;
|
||||
mode1->field_rendering = mode2->field_rendering;
|
||||
mode1->aa = mode2->aa;
|
||||
mode1->sample_pattern[0][0] = mode2->sample_pattern[0][0];
|
||||
mode1->sample_pattern[1][0] = mode2->sample_pattern[1][0];
|
||||
mode1->sample_pattern[2][0] = mode2->sample_pattern[2][0];
|
||||
mode1->sample_pattern[3][0] = mode2->sample_pattern[3][0];
|
||||
mode1->sample_pattern[4][0] = mode2->sample_pattern[4][0];
|
||||
mode1->sample_pattern[5][0] = mode2->sample_pattern[5][0];
|
||||
mode1->sample_pattern[6][0] = mode2->sample_pattern[6][0];
|
||||
mode1->sample_pattern[7][0] = mode2->sample_pattern[7][0];
|
||||
mode1->sample_pattern[8][0] = mode2->sample_pattern[8][0];
|
||||
mode1->sample_pattern[9][0] = mode2->sample_pattern[9][0];
|
||||
mode1->sample_pattern[10][0] = mode2->sample_pattern[10][0];
|
||||
mode1->sample_pattern[11][0] = mode2->sample_pattern[11][0];
|
||||
mode1->sample_pattern[0][1] = mode2->sample_pattern[0][1];
|
||||
mode1->sample_pattern[1][1] = mode2->sample_pattern[1][1];
|
||||
mode1->sample_pattern[2][1] = mode2->sample_pattern[2][1];
|
||||
mode1->sample_pattern[3][1] = mode2->sample_pattern[3][1];
|
||||
mode1->sample_pattern[4][1] = mode2->sample_pattern[4][1];
|
||||
mode1->sample_pattern[5][1] = mode2->sample_pattern[5][1];
|
||||
mode1->sample_pattern[6][1] = mode2->sample_pattern[6][1];
|
||||
mode1->sample_pattern[7][1] = mode2->sample_pattern[7][1];
|
||||
mode1->sample_pattern[8][1] = mode2->sample_pattern[8][1];
|
||||
mode1->sample_pattern[9][1] = mode2->sample_pattern[9][1];
|
||||
mode1->sample_pattern[10][1] = mode2->sample_pattern[10][1];
|
||||
mode1->sample_pattern[11][1] = mode2->sample_pattern[11][1];
|
||||
mode1->vfilter[0] = mode2->vfilter[0];
|
||||
mode1->vfilter[1] = mode2->vfilter[1];
|
||||
mode1->vfilter[2] = mode2->vfilter[2];
|
||||
mode1->vfilter[3] = mode2->vfilter[3];
|
||||
mode1->vfilter[4] = mode2->vfilter[4];
|
||||
mode1->vfilter[5] = mode2->vfilter[5];
|
||||
mode1->vfilter[6] = mode2->vfilter[6];
|
||||
}
|
||||
|
||||
static bool Search_and_patch_Video_Modes(u8 * Address, u32 Size, GXRModeObj* Table[])
|
||||
{
|
||||
u8 *Addr = (u8 *)Address;
|
||||
bool found = 0;
|
||||
u32 i;
|
||||
|
||||
while (Size >= sizeof(GXRModeObj)) {
|
||||
|
||||
for (i = 0; Table[i]; i+=2) {
|
||||
|
||||
if (compare_videomodes(Table[i], (GXRModeObj*)Addr))
|
||||
|
||||
{
|
||||
found = 1;
|
||||
patch_videomode((GXRModeObj*)Addr, Table[i+1]);
|
||||
Addr += (sizeof(GXRModeObj)-4);
|
||||
Size -= (sizeof(GXRModeObj)-4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Addr += 4;
|
||||
Size -= 4;
|
||||
}
|
||||
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void VideoModePatcher(u8 * dst, int len, u8 videoSelected)
|
||||
{
|
||||
GXRModeObj** table = NULL;
|
||||
if (videoSelected == 5) // patch
|
||||
|
||||
{
|
||||
switch (CONF_GetVideo()) {
|
||||
case CONF_VIDEO_PAL:
|
||||
if (CONF_GetEuRGB60() > 0) {
|
||||
table = NTSC2PAL60;
|
||||
} else {
|
||||
table = NTSC2PAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONF_VIDEO_MPAL:
|
||||
|
||||
|
||||
|
||||
table = NTSC2PAL;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
table = PAL2NTSC;
|
||||
break;
|
||||
}
|
||||
Search_and_patch_Video_Modes(dst, len, table);
|
||||
}
|
||||
}
|
12
source/patches/gamepatches.h
Normal file
12
source/patches/gamepatches.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef GAMEPATCHES_H_
|
||||
#define GAMEPATCHES_H_
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
bool Anti_002_fix(u8 * Address, int Size);
|
||||
bool NSMBPatch(u8 * Address, int Size);
|
||||
bool PoPPatch();
|
||||
bool Search_and_patch_Video_Modes(u8 * Address, u32 Size, GXRModeObj* Table[]);
|
||||
void VideoModePatcher(u8 * dst, int len, u8 videoSelected);
|
||||
|
||||
#endif
|
@ -5,13 +5,7 @@
|
||||
#include "gecko.h"
|
||||
|
||||
#include "settings/cfg.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 offset;
|
||||
u32 srcaddress;
|
||||
u32 dstaddress;
|
||||
} WIP_Code;
|
||||
#include "wip.h"
|
||||
|
||||
static WIP_Code * CodeList = NULL;
|
||||
static u32 CodesCount = 0;
|
||||
@ -58,6 +52,22 @@ void do_wip_code(u8 * dst, u32 len)
|
||||
Counter++;
|
||||
}
|
||||
|
||||
//! 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)
|
||||
{
|
||||
if(!CodeList && size > 0)
|
||||
{
|
||||
CodeList = list;
|
||||
CodesCount = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void wip_reset_counter()
|
||||
{
|
||||
ProcessedLength = 0;
|
||||
@ -71,6 +81,7 @@ void free_wip()
|
||||
free(CodeList);
|
||||
CodeList = NULL;
|
||||
CodesCount = 0;
|
||||
Counter = 0;
|
||||
ProcessedLength = 0;
|
||||
}
|
||||
|
||||
@ -86,6 +97,13 @@ int load_wip_code(u8 *gameid)
|
||||
if (!fp)
|
||||
{
|
||||
memset(GameID, 0, sizeof(GameID));
|
||||
memcpy(GameID, gameid, 4);
|
||||
snprintf(filepath, sizeof(filepath), "%s%s.wip", Settings.WipCodepath, GameID);
|
||||
fp = fopen(filepath, "rb");
|
||||
}
|
||||
if (!fp)
|
||||
{
|
||||
memset(GameID, 0, sizeof(GameID));
|
||||
memcpy(GameID, gameid, 3);
|
||||
snprintf(filepath, sizeof(filepath), "%s%s.wip", Settings.WipCodepath, GameID);
|
||||
fp = fopen(filepath, "rb");
|
||||
@ -100,6 +118,8 @@ int load_wip_code(u8 *gameid)
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (line[0] == '#') continue;
|
||||
if (line[0] == ';') continue;
|
||||
if (line[0] == ':') continue;
|
||||
|
||||
if(strlen(line) < 26) continue;
|
||||
|
||||
@ -113,10 +133,8 @@ int load_wip_code(u8 *gameid)
|
||||
WIP_Code * tmp = realloc(CodeList, (CodesCount+1)*sizeof(WIP_Code));
|
||||
if(!tmp)
|
||||
{
|
||||
if(CodeList)
|
||||
free(CodeList);
|
||||
CodeList = NULL;
|
||||
fclose(fp);
|
||||
free_wip();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,18 @@
|
||||
#ifndef __WIP_H__
|
||||
#define __WIP_H__
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 offset;
|
||||
u32 srcaddress;
|
||||
u32 dstaddress;
|
||||
} WIP_Code;
|
||||
|
||||
int load_wip_code(u8 *gameid);
|
||||
void do_wip_code(u8 * dst, u32 len);
|
||||
bool set_wip_list(WIP_Code * list, int size);
|
||||
void wip_reset_counter();
|
||||
void free_wip();
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "settings/cfg.h"
|
||||
#include "gecko.h"
|
||||
#include "patches/wip.h"
|
||||
#include "patches/dolpatcher.h"
|
||||
#include "patches/gamepatches.h"
|
||||
|
||||
extern bool geckoinit;
|
||||
|
||||
@ -31,276 +33,12 @@ static u8 *appldr = (u8 *)0x81200000;
|
||||
|
||||
/* Variables */
|
||||
static u32 buffer[0x20] ATTRIBUTE_ALIGN(32);
|
||||
struct SSettings Settings;
|
||||
|
||||
static void __noprint(const char *fmt, ...) {
|
||||
}
|
||||
static void __noprint(const char *fmt, ...) { }
|
||||
|
||||
|
||||
|
||||
bool compare_videomodes(GXRModeObj* mode1, GXRModeObj* mode2) {
|
||||
if (mode1->viTVMode != mode2->viTVMode || mode1->fbWidth != mode2->fbWidth || mode1->efbHeight != mode2->efbHeight || mode1->xfbHeight != mode2->xfbHeight ||
|
||||
mode1->viXOrigin != mode2->viXOrigin || mode1->viYOrigin != mode2->viYOrigin || mode1->viWidth != mode2->viWidth || mode1->viHeight != mode2->viHeight ||
|
||||
mode1->xfbMode != mode2->xfbMode || mode1->field_rendering != mode2->field_rendering || mode1->aa != mode2->aa || mode1->sample_pattern[0][0] != mode2->sample_pattern[0][0] ||
|
||||
mode1->sample_pattern[1][0] != mode2->sample_pattern[1][0] || mode1->sample_pattern[2][0] != mode2->sample_pattern[2][0] ||
|
||||
mode1->sample_pattern[3][0] != mode2->sample_pattern[3][0] || mode1->sample_pattern[4][0] != mode2->sample_pattern[4][0] ||
|
||||
mode1->sample_pattern[5][0] != mode2->sample_pattern[5][0] || mode1->sample_pattern[6][0] != mode2->sample_pattern[6][0] ||
|
||||
mode1->sample_pattern[7][0] != mode2->sample_pattern[7][0] || mode1->sample_pattern[8][0] != mode2->sample_pattern[8][0] ||
|
||||
mode1->sample_pattern[9][0] != mode2->sample_pattern[9][0] || mode1->sample_pattern[10][0] != mode2->sample_pattern[10][0] ||
|
||||
mode1->sample_pattern[11][0] != mode2->sample_pattern[11][0] || mode1->sample_pattern[0][1] != mode2->sample_pattern[0][1] ||
|
||||
mode1->sample_pattern[1][1] != mode2->sample_pattern[1][1] || mode1->sample_pattern[2][1] != mode2->sample_pattern[2][1] ||
|
||||
mode1->sample_pattern[3][1] != mode2->sample_pattern[3][1] || mode1->sample_pattern[4][1] != mode2->sample_pattern[4][1] ||
|
||||
mode1->sample_pattern[5][1] != mode2->sample_pattern[5][1] || mode1->sample_pattern[6][1] != mode2->sample_pattern[6][1] ||
|
||||
mode1->sample_pattern[7][1] != mode2->sample_pattern[7][1] || mode1->sample_pattern[8][1] != mode2->sample_pattern[8][1] ||
|
||||
mode1->sample_pattern[9][1] != mode2->sample_pattern[9][1] || mode1->sample_pattern[10][1] != mode2->sample_pattern[10][1] ||
|
||||
mode1->sample_pattern[11][1] != mode2->sample_pattern[11][1] || mode1->vfilter[0] != mode2->vfilter[0] ||
|
||||
mode1->vfilter[1] != mode2->vfilter[1] || mode1->vfilter[2] != mode2->vfilter[2] || mode1->vfilter[3] != mode2->vfilter[3] || mode1->vfilter[4] != mode2->vfilter[4] ||
|
||||
mode1->vfilter[5] != mode2->vfilter[5] || mode1->vfilter[6] != mode2->vfilter[6] ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void patch_videomode(GXRModeObj* mode1, GXRModeObj* mode2) {
|
||||
mode1->viTVMode = mode2->viTVMode;
|
||||
mode1->fbWidth = mode2->fbWidth;
|
||||
mode1->efbHeight = mode2->efbHeight;
|
||||
mode1->xfbHeight = mode2->xfbHeight;
|
||||
mode1->viXOrigin = mode2->viXOrigin;
|
||||
mode1->viYOrigin = mode2->viYOrigin;
|
||||
mode1->viWidth = mode2->viWidth;
|
||||
mode1->viHeight = mode2->viHeight;
|
||||
mode1->xfbMode = mode2->xfbMode;
|
||||
mode1->field_rendering = mode2->field_rendering;
|
||||
mode1->aa = mode2->aa;
|
||||
mode1->sample_pattern[0][0] = mode2->sample_pattern[0][0];
|
||||
mode1->sample_pattern[1][0] = mode2->sample_pattern[1][0];
|
||||
mode1->sample_pattern[2][0] = mode2->sample_pattern[2][0];
|
||||
mode1->sample_pattern[3][0] = mode2->sample_pattern[3][0];
|
||||
mode1->sample_pattern[4][0] = mode2->sample_pattern[4][0];
|
||||
mode1->sample_pattern[5][0] = mode2->sample_pattern[5][0];
|
||||
mode1->sample_pattern[6][0] = mode2->sample_pattern[6][0];
|
||||
mode1->sample_pattern[7][0] = mode2->sample_pattern[7][0];
|
||||
mode1->sample_pattern[8][0] = mode2->sample_pattern[8][0];
|
||||
mode1->sample_pattern[9][0] = mode2->sample_pattern[9][0];
|
||||
mode1->sample_pattern[10][0] = mode2->sample_pattern[10][0];
|
||||
mode1->sample_pattern[11][0] = mode2->sample_pattern[11][0];
|
||||
mode1->sample_pattern[0][1] = mode2->sample_pattern[0][1];
|
||||
mode1->sample_pattern[1][1] = mode2->sample_pattern[1][1];
|
||||
mode1->sample_pattern[2][1] = mode2->sample_pattern[2][1];
|
||||
mode1->sample_pattern[3][1] = mode2->sample_pattern[3][1];
|
||||
mode1->sample_pattern[4][1] = mode2->sample_pattern[4][1];
|
||||
mode1->sample_pattern[5][1] = mode2->sample_pattern[5][1];
|
||||
mode1->sample_pattern[6][1] = mode2->sample_pattern[6][1];
|
||||
mode1->sample_pattern[7][1] = mode2->sample_pattern[7][1];
|
||||
mode1->sample_pattern[8][1] = mode2->sample_pattern[8][1];
|
||||
mode1->sample_pattern[9][1] = mode2->sample_pattern[9][1];
|
||||
mode1->sample_pattern[10][1] = mode2->sample_pattern[10][1];
|
||||
mode1->sample_pattern[11][1] = mode2->sample_pattern[11][1];
|
||||
mode1->vfilter[0] = mode2->vfilter[0];
|
||||
mode1->vfilter[1] = mode2->vfilter[1];
|
||||
mode1->vfilter[2] = mode2->vfilter[2];
|
||||
mode1->vfilter[3] = mode2->vfilter[3];
|
||||
mode1->vfilter[4] = mode2->vfilter[4];
|
||||
mode1->vfilter[5] = mode2->vfilter[5];
|
||||
mode1->vfilter[6] = mode2->vfilter[6];
|
||||
}
|
||||
|
||||
GXRModeObj* vmodes[] = {
|
||||
&TVNtsc240Ds,
|
||||
&TVNtsc240DsAa,
|
||||
&TVNtsc240Int,
|
||||
&TVNtsc240IntAa,
|
||||
&TVNtsc480IntDf,
|
||||
&TVNtsc480IntAa,
|
||||
&TVNtsc480Prog,
|
||||
&TVMpal480IntDf,
|
||||
&TVPal264Ds,
|
||||
&TVPal264DsAa,
|
||||
&TVPal264Int,
|
||||
&TVPal264IntAa,
|
||||
&TVPal524IntAa,
|
||||
&TVPal528Int,
|
||||
&TVPal528IntDf,
|
||||
&TVPal574IntDfScale,
|
||||
&TVEurgb60Hz240Ds,
|
||||
&TVEurgb60Hz240DsAa,
|
||||
&TVEurgb60Hz240Int,
|
||||
&TVEurgb60Hz240IntAa,
|
||||
&TVEurgb60Hz480Int,
|
||||
&TVEurgb60Hz480IntDf,
|
||||
&TVEurgb60Hz480IntAa,
|
||||
&TVEurgb60Hz480Prog,
|
||||
&TVEurgb60Hz480ProgSoft,
|
||||
&TVEurgb60Hz480ProgAa
|
||||
};
|
||||
|
||||
GXRModeObj* PAL2NTSC[]={
|
||||
&TVMpal480IntDf, &TVNtsc480IntDf,
|
||||
&TVPal264Ds, &TVNtsc240Ds,
|
||||
&TVPal264DsAa, &TVNtsc240DsAa,
|
||||
&TVPal264Int, &TVNtsc240Int,
|
||||
&TVPal264IntAa, &TVNtsc240IntAa,
|
||||
&TVPal524IntAa, &TVNtsc480IntAa,
|
||||
&TVPal528Int, &TVNtsc480IntAa,
|
||||
&TVPal528IntDf, &TVNtsc480IntDf,
|
||||
&TVPal574IntDfScale, &TVNtsc480IntDf,
|
||||
&TVEurgb60Hz240Ds, &TVNtsc240Ds,
|
||||
&TVEurgb60Hz240DsAa, &TVNtsc240DsAa,
|
||||
&TVEurgb60Hz240Int, &TVNtsc240Int,
|
||||
&TVEurgb60Hz240IntAa, &TVNtsc240IntAa,
|
||||
&TVEurgb60Hz480Int, &TVNtsc480IntAa,
|
||||
&TVEurgb60Hz480IntDf, &TVNtsc480IntDf,
|
||||
&TVEurgb60Hz480IntAa, &TVNtsc480IntAa,
|
||||
&TVEurgb60Hz480Prog, &TVNtsc480Prog,
|
||||
&TVEurgb60Hz480ProgSoft,&TVNtsc480Prog,
|
||||
&TVEurgb60Hz480ProgAa, &TVNtsc480Prog,
|
||||
0,0
|
||||
};
|
||||
|
||||
GXRModeObj* NTSC2PAL[]={
|
||||
&TVNtsc240Ds, &TVPal264Ds,
|
||||
&TVNtsc240DsAa, &TVPal264DsAa,
|
||||
&TVNtsc240Int, &TVPal264Int,
|
||||
&TVNtsc240IntAa, &TVPal264IntAa,
|
||||
&TVNtsc480IntDf, &TVPal528IntDf,
|
||||
&TVNtsc480IntAa, &TVPal524IntAa,
|
||||
&TVNtsc480Prog, &TVPal528IntDf,
|
||||
0,0
|
||||
};
|
||||
|
||||
GXRModeObj* NTSC2PAL60[]={
|
||||
&TVNtsc240Ds, &TVEurgb60Hz240Ds,
|
||||
&TVNtsc240DsAa, &TVEurgb60Hz240DsAa,
|
||||
&TVNtsc240Int, &TVEurgb60Hz240Int,
|
||||
&TVNtsc240IntAa, &TVEurgb60Hz240IntAa,
|
||||
&TVNtsc480IntDf, &TVEurgb60Hz480IntDf,
|
||||
&TVNtsc480IntAa, &TVEurgb60Hz480IntAa,
|
||||
&TVNtsc480Prog, &TVEurgb60Hz480Prog,
|
||||
0,0
|
||||
};
|
||||
bool Search_and_patch_Video_Modes(void *Address, u32 Size, GXRModeObj* Table[]) {
|
||||
u8 *Addr = (u8 *)Address;
|
||||
bool found = 0;
|
||||
u32 i;
|
||||
|
||||
while (Size >= sizeof(GXRModeObj)) {
|
||||
|
||||
|
||||
|
||||
for (i = 0; Table[i]; i+=2) {
|
||||
|
||||
|
||||
if (compare_videomodes(Table[i], (GXRModeObj*)Addr))
|
||||
|
||||
{
|
||||
found = 1;
|
||||
patch_videomode((GXRModeObj*)Addr, Table[i+1]);
|
||||
Addr += (sizeof(GXRModeObj)-4);
|
||||
Size -= (sizeof(GXRModeObj)-4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Addr += 4;
|
||||
Size -= 4;
|
||||
}
|
||||
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/** Anti 002 fix for IOS 249 rev > 12 thanks to WiiPower **/
|
||||
void Anti_002_fix(void *Address, int Size) {
|
||||
u8 SearchPattern[12] = { 0x2C, 0x00, 0x00, 0x00, 0x48, 0x00, 0x02, 0x14, 0x3C, 0x60, 0x80, 0x00 };
|
||||
u8 PatchData[12] = { 0x2C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x02, 0x14, 0x3C, 0x60, 0x80, 0x00 };
|
||||
|
||||
void *Addr = Address;
|
||||
void *Addr_end = Address+Size;
|
||||
|
||||
while (Addr <= Addr_end-sizeof(SearchPattern)) {
|
||||
if (memcmp(Addr, SearchPattern, sizeof(SearchPattern))==0) {
|
||||
memcpy(Addr,PatchData,sizeof(PatchData));
|
||||
}
|
||||
Addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/** Thanks to WiiPower **/
|
||||
bool NewSuperMarioBrosPatch(void *Address, int Size)
|
||||
void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat)
|
||||
{
|
||||
if (IOS_GetVersion() == 222 || IOS_GetVersion() == 223) return false; // Don't use this when using Hermes, it'll use the BCA fix instead...
|
||||
|
||||
if (memcmp("SMNE", (char *)0x80000000, 4) == 0)
|
||||
{
|
||||
u8 SearchPattern[32] = { 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
u8 PatchData[32] = { 0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
|
||||
void *Addr = Address;
|
||||
void *Addr_end = Address+Size;
|
||||
|
||||
while(Addr <= Addr_end-sizeof(SearchPattern))
|
||||
{
|
||||
if(memcmp(Addr, SearchPattern, sizeof(SearchPattern))==0)
|
||||
{
|
||||
memcpy(Addr,PatchData,sizeof(PatchData));
|
||||
return true;
|
||||
}
|
||||
Addr += 4;
|
||||
}
|
||||
}
|
||||
else if (memcmp("SMN", (char *)0x80000000, 3) == 0)
|
||||
{
|
||||
u8 SearchPattern[32] = { 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD9, 0x39, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
u8 PatchData[32] = { 0x4E, 0x80, 0x00, 0x20, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, 0x48, 0x12, 0xD9, 0x39, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78 };
|
||||
|
||||
void *Addr = Address;
|
||||
void *Addr_end = Address+Size;
|
||||
|
||||
while(Addr <= Addr_end-sizeof(SearchPattern))
|
||||
{
|
||||
if(memcmp(Addr, SearchPattern, sizeof(SearchPattern))==0)
|
||||
{
|
||||
memcpy(Addr,PatchData,sizeof(PatchData));
|
||||
return true;
|
||||
}
|
||||
Addr += 4;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u8 vipatch, u8 cheat) {
|
||||
|
||||
GXRModeObj** table = NULL;
|
||||
if (videoSelected == 5) // patch
|
||||
|
||||
{
|
||||
switch (CONF_GetVideo()) {
|
||||
case CONF_VIDEO_PAL:
|
||||
if (CONF_GetEuRGB60() > 0) {
|
||||
table = NTSC2PAL60;
|
||||
} else {
|
||||
table = NTSC2PAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONF_VIDEO_MPAL:
|
||||
|
||||
|
||||
|
||||
table = NTSC2PAL;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
table = PAL2NTSC;
|
||||
break;
|
||||
}
|
||||
Search_and_patch_Video_Modes(dst, len, table);
|
||||
}
|
||||
VideoModePatcher(dst, len, videoSelected);
|
||||
|
||||
if(cheat)
|
||||
dogamehooks(dst,len);
|
||||
@ -315,7 +53,7 @@ void gamepatches(void * dst, int len, u8 videoSelected, u8 patchcountrystring, u
|
||||
if (patchcountrystring == 1)
|
||||
PatchCountryStrings(dst, len);
|
||||
|
||||
NewSuperMarioBrosPatch(dst, len);
|
||||
NSMBPatch(dst, len);
|
||||
|
||||
do_wip_code((u8 *) dst, len);
|
||||
|
||||
@ -331,7 +69,7 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8
|
||||
|
||||
u32 appldr_len;
|
||||
s32 ret;
|
||||
gprintf("\nApploader_Run() started");
|
||||
gprintf("\nApploader_Run() started\n");
|
||||
|
||||
//u32 geckoattached = usb_isgeckoalive(EXI_CHANNEL_1);
|
||||
//if (geckoattached)usb_flush(EXI_CHANNEL_1);
|
||||
@ -359,13 +97,14 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8
|
||||
/* Initialize apploader */
|
||||
appldr_init(__noprint);
|
||||
|
||||
if (error002fix!=0) {
|
||||
if (error002fix!=0)
|
||||
{
|
||||
/* ERROR 002 fix (thanks to WiiPower for sharing this)*/
|
||||
*(u32 *)0x80003188 = *(u32 *)0x80003140;
|
||||
// *(u32 *)0x80003140 = *(u32 *)0x80003188;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
void *dst = NULL;
|
||||
int len = 0, offset = 0;
|
||||
|
||||
@ -384,17 +123,15 @@ s32 Apploader_Run(entry_point *entry, u8 cheat, u8 videoSelected, u8 vipatch, u8
|
||||
*entry = appldr_final();
|
||||
|
||||
/** Load alternate dol if set **/
|
||||
if (alternatedol == 1) {
|
||||
// gprintf("\n\talt dol from FAT");
|
||||
if (alternatedol == 1)
|
||||
{
|
||||
wip_reset_counter();
|
||||
void *dolbuffer;
|
||||
int dollen;
|
||||
void *dolbuffer = NULL;
|
||||
int dollen = 0;
|
||||
|
||||
bool dolloaded = Load_Dol(&dolbuffer, &dollen, Settings.dolpath, videoSelected, patchcountrystring, vipatch, cheat);
|
||||
if (dolloaded)
|
||||
{
|
||||
DCFlushRange(dolbuffer, dollen);
|
||||
/* Set entry point from apploader */
|
||||
*entry = (entry_point) load_dol_image(dolbuffer);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <wiiuse/wpad.h>
|
||||
|
||||
#include "patches/fst.h"
|
||||
#include "patches/gamepatches.h"
|
||||
#include "patches/wip.h"
|
||||
#include "apploader.h"
|
||||
#include "disc.h"
|
||||
@ -284,14 +285,17 @@ s32 Disc_BootPartition(u64 offset, u8 videoselected, u8 cheat, u8 vipatch, u8 pa
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Setup low memory */
|
||||
__Disc_SetLowMem();
|
||||
|
||||
char gameid[8];
|
||||
memset(gameid, 0, 8);
|
||||
memcpy(gameid, (char*)Disc_ID, 6);
|
||||
|
||||
load_wip_code((u8 *) &gameid);
|
||||
|
||||
/* Setup low memory */
|
||||
__Disc_SetLowMem();
|
||||
/* If a wip file is loaded for this game this does nothing - Dimok */
|
||||
PoPPatch();
|
||||
|
||||
/* Run apploader */
|
||||
ret = Apploader_Run(&p_entry, cheat, videoselected, vipatch, patchcountrystring, error002fix, alternatedol, alternatedoloffset);
|
||||
|
Loading…
Reference in New Issue
Block a user