-
Notifications
You must be signed in to change notification settings - Fork 1
/
IpsPatch.cpp
53 lines (46 loc) · 1.66 KB
/
IpsPatch.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "ROMCheck.h"
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <fstream>
#include <cstring>
#define IPS_EOF 0x454F46
using namespace std;
bool applyPatch (const std::string &OutFile, const unsigned char PatchBuffer[]) {
std::ifstream ReadROM(OutFile, std::ios::binary);
ReadROM.seekg(0, std::ios::end);
long ROMFileSize = ReadROM.tellg();
unsigned char *ROMBuffer = new unsigned char[ROMFileSize];
ReadROM.seekg(0, std::ios::beg);
ReadROM.read((char *)ROMBuffer, ROMFileSize);
ReadROM.close();
ReadROM.clear();
int patchPos = 5; // After the header
unsigned int offset, size;
unsigned char b;
offset = PatchBuffer[patchPos] << 16 | (PatchBuffer[patchPos + 1] << 8 | PatchBuffer[patchPos + 2]);
patchPos += 3;
while (offset != IPS_EOF) {
size = PatchBuffer[patchPos] << 8 | PatchBuffer[patchPos + 1];
patchPos += 2;
if (size == 0) {
// RLE hunk - one byte repeated
size = PatchBuffer[patchPos] << 8 | PatchBuffer[patchPos + 1];
patchPos += 2;
b = PatchBuffer[patchPos++];
memset(ROMBuffer + offset, b, size);
} else {
// Regular hunk - copy slice of patch into ROM
memcpy(ROMBuffer + offset, PatchBuffer + patchPos, size);
patchPos += size;
}
offset = PatchBuffer[patchPos] << 16 | (PatchBuffer[patchPos + 1] << 8 | PatchBuffer[patchPos + 2]);
patchPos += 3;
}
std::ofstream WriteROM(OutFile, std::ios::binary);
WriteROM.write((char *)ROMBuffer, ROMFileSize);
WriteROM.close();
WriteROM.clear();
delete[] ROMBuffer;
return true;
}