2010-05-29 17:43:19 +02:00
|
|
|
#include <gccore.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "gecko.h"
|
|
|
|
|
|
|
|
#include "settings/cfg.h"
|
2010-05-30 16:18:25 +02:00
|
|
|
#include "wip.h"
|
2010-05-29 17:43:19 +02:00
|
|
|
|
|
|
|
static WIP_Code * CodeList = NULL;
|
|
|
|
static u32 CodesCount = 0;
|
|
|
|
static u32 ProcessedLength = 0;
|
|
|
|
static u32 Counter = 0;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
void do_wip_code( u8 * dst, u32 len )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( !CodeList )
|
2010-05-29 17:43:19 +02:00
|
|
|
return;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( Counter < 3 )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
|
|
|
Counter++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
int n = 0;
|
|
|
|
int offset = 0;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
for ( i = 0; i < CodesCount; i++ )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
for ( n = 0; n < 4; n++ )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
offset = CodeList[i].offset + n - ProcessedLength;
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( offset < 0 || offset >= len )
|
2010-05-29 17:43:19 +02:00
|
|
|
continue;
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( dst[offset] == ( ( u8 * )&CodeList[i].srcaddress )[n] )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
dst[offset] = ( ( u8 * ) & CodeList[i].dstaddress )[n];
|
|
|
|
gprintf( "WIP: %08X Address Patched.\n", CodeList[i].offset + n );
|
2010-05-29 17:43:19 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
gprintf( "WIP: %08X Address does not match with WIP entrie.\n", CodeList[i].offset + n );
|
|
|
|
gprintf( "Destination: %02X | Should be: %02X.\n", dst[offset], ( ( u8 * )&CodeList[i].srcaddress )[n] );
|
2010-05-29 17:43:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ProcessedLength += len;
|
|
|
|
Counter++;
|
|
|
|
}
|
|
|
|
|
2010-05-30 16:18:25 +02:00
|
|
|
//! 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
|
2010-09-19 01:16:05 +02:00
|
|
|
bool set_wip_list( WIP_Code * list, int size )
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( !CodeList && size > 0 )
|
2010-05-30 16:18:25 +02:00
|
|
|
{
|
|
|
|
CodeList = list;
|
|
|
|
CodesCount = size;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-29 17:43:19 +02:00
|
|
|
void wip_reset_counter()
|
|
|
|
{
|
|
|
|
ProcessedLength = 0;
|
|
|
|
//alternative dols don't need a skip. only main.dol.
|
|
|
|
Counter = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_wip()
|
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( CodeList )
|
|
|
|
free( CodeList );
|
2010-05-29 17:43:19 +02:00
|
|
|
CodeList = NULL;
|
|
|
|
CodesCount = 0;
|
2010-05-30 16:18:25 +02:00
|
|
|
Counter = 0;
|
2010-05-29 17:43:19 +02:00
|
|
|
ProcessedLength = 0;
|
|
|
|
}
|
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
int load_wip_code( u8 *gameid )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
char filepath[150];
|
|
|
|
char GameID[8];
|
|
|
|
memset( GameID, 0, sizeof( GameID ) );
|
|
|
|
memcpy( GameID, gameid, 6 );
|
|
|
|
snprintf( filepath, sizeof( filepath ), "%s%s.wip", Settings.WipCodepath, GameID );
|
|
|
|
|
|
|
|
FILE * fp = fopen( filepath, "rb" );
|
|
|
|
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" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !fp )
|
2010-05-29 17:43:19 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
char line[255];
|
2010-09-19 01:16:05 +02:00
|
|
|
gprintf( "\nLoading WIP code from %s.\n", filepath );
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
while ( fgets( line, sizeof( line ), fp ) )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( line[0] == '#' ) continue;
|
|
|
|
if ( line[0] == ';' ) continue;
|
|
|
|
if ( line[0] == ':' ) continue;
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( strlen( line ) < 26 ) continue;
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
u32 offset = ( u32 ) strtoul( line, NULL, 16 );
|
|
|
|
u32 srcaddress = ( u32 ) strtoul( line + 9, NULL, 16 );
|
|
|
|
u32 dstaddress = ( u32 ) strtoul( line + 18, NULL, 16 );
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
if ( !CodeList )
|
|
|
|
CodeList = malloc( sizeof( WIP_Code ) );
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
WIP_Code * tmp = realloc( CodeList, ( CodesCount + 1 ) * sizeof( WIP_Code ) );
|
|
|
|
if ( !tmp )
|
2010-05-29 17:43:19 +02:00
|
|
|
{
|
2010-09-19 01:16:05 +02:00
|
|
|
fclose( fp );
|
2010-05-30 16:18:25 +02:00
|
|
|
free_wip();
|
2010-05-29 17:43:19 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CodeList = tmp;
|
|
|
|
|
|
|
|
CodeList[CodesCount].offset = offset;
|
|
|
|
CodeList[CodesCount].srcaddress = srcaddress;
|
|
|
|
CodeList[CodesCount].dstaddress = dstaddress;
|
|
|
|
CodesCount++;
|
|
|
|
}
|
2010-09-19 01:16:05 +02:00
|
|
|
fclose( fp );
|
|
|
|
gprintf( "\n" );
|
2010-05-29 17:43:19 +02:00
|
|
|
|
2010-09-19 01:16:05 +02:00
|
|
|
return 0;
|
2010-05-29 17:43:19 +02:00
|
|
|
}
|