diff --git a/index.html b/index.html
index b615605..f0f1021 100644
--- a/index.html
+++ b/index.html
@@ -3,8 +3,8 @@
Rom Patcher JS
-
-
+
+
@@ -27,7 +27,7 @@
-
+
@@ -83,7 +83,7 @@
@@ -126,6 +126,7 @@
+
@@ -151,7 +152,7 @@
- Rom Patcher JS v3.1 by Marc Robledo
+ Rom Patcher JS v3.2 by Marc Robledo
See on GitHub
Donate
diff --git a/index.js b/index.js
index c5a7535..69eace4 100644
--- a/index.js
+++ b/index.js
@@ -58,7 +58,7 @@ program
.description('creates a patch based on two ROMs')
.argument('', 'the original ROM')
.argument('','the modified ROM')
- .option('-f, --format ','patch format (allowed values: ips [default], bps, ppf, ups, aps, rup)')
+ .option('-f, --format ','patch format (allowed values: ips [default], bps, ppf, ups, aps, rup, ebp)')
.action(function(originalRomPath, modifiedRomPath, options) {
console.log(options);
try{
diff --git a/rom-patcher-js/RomPatcher.js b/rom-patcher-js/RomPatcher.js
index 3e312f1..e9e0151 100644
--- a/rom-patcher-js/RomPatcher.js
+++ b/rom-patcher-js/RomPatcher.js
@@ -254,6 +254,8 @@ const RomPatcher = (function () {
patch = APS.buildFromRoms(originalFile, modifiedFile);
} else if (format === 'rup') {
patch = RUP.buildFromRoms(originalFile, modifiedFile);
+ } else if (format === 'ebp') {
+ patch = IPS.buildFromRoms(originalFile, modifiedFile, true);
} else {
throw new Error('Invalid patch format');
}
diff --git a/rom-patcher-js/RomPatcher.webapp.js b/rom-patcher-js/RomPatcher.webapp.js
index ae05dde..0a33be2 100644
--- a/rom-patcher-js/RomPatcher.webapp.js
+++ b/rom-patcher-js/RomPatcher.webapp.js
@@ -1175,7 +1175,7 @@ const ZIPManager = (function (romPatcherWeb) {
const ZIP_MAGIC = '\x50\x4b\x03\x04';
- const FILTER_PATCHES = /\.(ips|ups|bps|aps|rup|ppf|mod|xdelta|vcdiff)$/i;
+ const FILTER_PATCHES = /\.(ips|ups|bps|aps|rup|ppf|mod|ebp|xdelta|vcdiff)$/i;
//const FILTER_ROMS=/(?romFile.fileSize){ //expand (discussed here: https://github.com/marcrobledo/RomPatcher.js/pull/46)
tempFile=new BinFile(this.truncate);
romFile.copyTo(tempFile, 0, romFile.fileSize, 0);
@@ -136,6 +173,10 @@ IPS.fromFile=function(file){
}else if((file.offset+3)===file.fileSize){
patchFile.truncate=file.readU24();
break;
+ }else if (file.readU8()==='{'.charCodeAt(0)) {
+ file.skip(-1);
+ patchFile.setEBPMetadata(JSON.parse(file.readString(file.fileSize-file.offset)));
+ break;
}
}
@@ -151,11 +192,17 @@ IPS.fromFile=function(file){
}
-IPS.buildFromRoms=function(original, modified){
+IPS.buildFromRoms=function(original, modified, asEBP=false){
var patch=new IPS();
- if(modified.fileSize=IPS_MAX_ROM_SIZE){
- throw new Error('Files are too big for IPS format');
+ throw new Error(`Files are too big for ${patch.EBPmetadata? 'EBP' : 'IPS'} format`);
return null;
}
diff --git a/test.js b/test.js
index 2250c71..0e0a101 100644
--- a/test.js
+++ b/test.js
@@ -23,9 +23,15 @@
- APS test
- Patch: http://dorando.emuverse.com/projects/eduardo_a2j/zelda-ocarina-of-time.html
- ROM: Legend of Zelda, The - Ocarina of Time (USA).z64 [CRC32=7e107c35]
+ - APS (GBA) test
+ - Patch: http://ngplus.net/InsaneDifficultyArchive/www.insanedifficulty.com/board/index9837.html?/files/file/65-final-fantasy-tactics-advance-x/
+ - ROM: Final Fantasy Tactics Advance (USA).gba [CRC32=5645e56c]
- RUP test
- Patch: https://www.romhacking.net/translations/843/
- ROM: Uchuu no Kishi - Tekkaman Blade (Japan).sfc [CRC32=cd16c529]
+ - EBP test
+ - Patch: https://forum.starmen.net/forum/Community/PKHack/NickBound/page/1#post2333521
+ - ROM: EarthBound (USA).sfc [CRC32=dc9bb451]
- xdelta test
- Patch: https://www.romhacking.net/hacks/2871/
- ROM: New Super Mario Bros. (USA, Australia).nds [CRC32=0197576a]
@@ -74,6 +80,14 @@ const TEST_PATCHES = [
patchCrc32: 0x7b70119d,
patchDownload: 'http://dorando.emuverse.com/projects/eduardo_a2j/zelda-ocarina-of-time.html',
outputCrc32: 0x7866f1ca
+ }, {
+ title: 'APS (GBA) - Final Fantasy Tactics Advance X',
+ romFile: 'Final Fantasy Tactics Advance (USA).gba',
+ romCrc32: 0x5645e56c,
+ patchFile: 'FFTA_X_1.0.3.1.aps',
+ patchCrc32: 0x77e5f2ae,
+ patchDownload: 'http://ngplus.net/InsaneDifficultyArchive/www.insanedifficulty.com/board/index9837.html?/files/file/65-final-fantasy-tactics-advance-x/',
+ outputCrc32: 0x49a5539a
}, {
title: 'Tekkaman Blade translation',
romFile: 'Uchuu no Kishi - Tekkaman Blade (Japan).sfc',
@@ -81,8 +95,17 @@ const TEST_PATCHES = [
patchFile: 'Tekkaman Blade v1.0.rup',
patchCrc32: 0x621ab323,
patchDownload: 'https://www.romhacking.net/hacks/4633/',
- outputCrc32: 0xe83e9b0a
+ //outputCrc32: 0xe83e9b0a //Headerless
+ outputCrc32: 0xda833bce //Headered
}, {
+ title: 'EBP - Mother Rebound',
+ romFile: 'EarthBound (USA).sfc',
+ romCrc32: 0xdc9bb451,
+ patchFile: 'Mother_Rebound.ebp',
+ patchCrc32: 0x271719e1,
+ patchDownload: 'https://forum.starmen.net/forum/Community/PKHack/NickBound/page/1#post2333521',
+ outputCrc32: 0x5065b02f
+ }, {
title: 'NSMB Hack Domain Infusion',
romFile: 'New Super Mario Bros. (USA, Australia).nds',
romCrc32: 0x0197576a,
@@ -128,7 +151,7 @@ _test('HashCalculator integrity', function () {
const MODIFIED_TEST_DATA = (new Uint8Array([
98, 91, 64, 8, 35, 53, 122, 167, 52, 253, 222, 156, 247, 82, 227, 213, 22, 221, 17, 247, 107, 102, 164, 254, 221, 8, 207, 63, 117, 164, 223, 10, 1, 77, 87, 123, 48, 9, 111, 64, 233, 118, 1, 36, 1, 60, 208, 245, 136, 126, 29, 231, 168, 18, 125, 172, 11, 184, 81, 20, 16, 30, 154, 16, 236, 21, 5, 74, 255, 112, 171, 198, 185, 89, 2, 98, 45, 164, 214, 55, 103, 15, 217, 95, 212, 133, 184, 21, 67, 144, 198, 163, 76, 35, 248, 229, 163, 37, 103, 33, 193, 96, 77, 255, 117, 89, 193, 61, 64, 253, 119, 82, 49, 187, 195, 165, 205, 140, 222, 134, 249, 68, 224, 248, 144, 207, 18, 126
])).buffer;
-['ips', 'bps', 'ppf', 'ups', 'aps', 'rup'].forEach(function (patchFormat) {
+['ips', 'bps', 'ppf', 'ups', 'aps', 'rup', 'ebp'].forEach(function (patchFormat) {
_test('create and apply ' + patchFormat.toUpperCase(), function () {
const originalFile = new BinFile(TEST_DATA);
const modifiedFile = new BinFile(MODIFIED_TEST_DATA);
@@ -154,7 +177,7 @@ TEST_PATCHES.forEach(function (patchInfo) {
const patchPath = TEST_PATH + 'patches/' + patchInfo.patchFile;
if (!existsSync(patchPath)) {
console.log(chalk.yellow('! skipping patch ' + patchInfo.title));
- console.log(chalk.yellow(' patch file not found: ' + patchInfo.patchFile));
+ console.log(chalk.yellow(' patch file not found: ' + TEST_PATH + 'patches/' + patchInfo.patchFile));
console.log(chalk.yellow(' download patch at ' + patchInfo.patchDownload));
return false;
}
@@ -170,7 +193,7 @@ TEST_PATCHES.forEach(function (patchInfo) {
const romPath = TEST_PATH + 'roms/' + patchInfo.romFile;
if (!existsSync(romPath)) {
console.log(chalk.yellow('! skipping patch ' + patchInfo.title));
- console.log(chalk.yellow(' ROM file not found: ' + patchInfo.romFile));
+ console.log(chalk.yellow(' ROM file not found: ' + TEST_PATH + 'roms/' + patchInfo.romFile));
return false;
}
const romFile = new BinFile(romPath);