diff --git a/HBC/META.XML b/HBC/META.XML index 95c31036..2642c1b0 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r934 - 201005300653 + 1.0 r935 + 201005300742 Loads games from USB-devices 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. diff --git a/gui.pnproj b/gui.pnproj index 25e6a3a5..38624eee 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/memory/mem2.cpp b/source/memory/mem2.cpp index a8b942ae..01630927 100644 --- a/source/memory/mem2.cpp +++ b/source/memory/mem2.cpp @@ -1,185 +1,188 @@ - -#include "mem2.h" -#include "mem2alloc.h" - -#include -#include - -#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 +#include + +#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); +} + +} diff --git a/source/patches/dolpatcher.c b/source/patches/dolpatcher.c new file mode 100644 index 00000000..131c86db --- /dev/null +++ b/source/patches/dolpatcher.c @@ -0,0 +1,19 @@ +#include +#include + +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; +} diff --git a/source/patches/dolpatcher.h b/source/patches/dolpatcher.h new file mode 100644 index 00000000..09eb3190 --- /dev/null +++ b/source/patches/dolpatcher.h @@ -0,0 +1,8 @@ +#ifndef DOLPATCHER_C_ +#define DOLPATCHER_C_ + +#include + +bool PatchDOL(u8 * Address, int Size, const u8 * SearchPattern, int SearchSize, const u8 * PatchData, int PatchSize); + +#endif diff --git a/source/patches/gamepatches.c b/source/patches/gamepatches.c new file mode 100644 index 00000000..026562d6 --- /dev/null +++ b/source/patches/gamepatches.c @@ -0,0 +1,269 @@ +#include +#include +#include +#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); + } +} diff --git a/source/patches/gamepatches.h b/source/patches/gamepatches.h new file mode 100644 index 00000000..ef8baa54 --- /dev/null +++ b/source/patches/gamepatches.h @@ -0,0 +1,12 @@ +#ifndef GAMEPATCHES_H_ +#define GAMEPATCHES_H_ + +#include + +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 diff --git a/source/patches/wip.c b/source/patches/wip.c index 5b8702f9..a6e8af9b 100644 --- a/source/patches/wip.c +++ b/source/patches/wip.c @@ -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; } diff --git a/source/patches/wip.h b/source/patches/wip.h index 3788f25a..395244ea 100644 --- a/source/patches/wip.h +++ b/source/patches/wip.h @@ -1,8 +1,18 @@ #ifndef __WIP_H__ #define __WIP_H__ +#include + +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(); diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index 940ab990..4c8f18e4 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -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); } diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index 964e76de..d3c76b94 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -6,6 +6,7 @@ #include #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);