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