From b052fdda13eb6cee28daeccd003f32360e891608 Mon Sep 17 00:00:00 2001 From: Supremekirb <99102603+Supremekirb@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:43:07 +0930 Subject: [PATCH 1/4] EBP support --- index.html | 9 ++-- index.js | 2 +- rom-patcher-js/RomPatcher.js | 4 +- rom-patcher-js/RomPatcher.webapp.js | 2 +- .../modules/RomPatcher.format.ips.js | 41 +++++++++++++++---- test.js | 11 +++++ 6 files changed, 53 insertions(+), 16 deletions(-) diff --git a/index.html b/index.html index b615605..3338326 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 @@ +
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..f70ec66 100644 --- a/rom-patcher-js/RomPatcher.js +++ b/rom-patcher-js/RomPatcher.js @@ -242,8 +242,8 @@ const RomPatcher = (function () { format = 'ips'; var patch; - if (format === 'ips') { - patch = IPS.buildFromRoms(originalFile, modifiedFile); + if (format === 'ips' || format === 'ebp') { + patch = IPS.buildFromRoms(originalFile, modifiedFile, format === 'ebp'); } else if (format === 'bps') { patch = BPS.buildFromRoms(originalFile, modifiedFile, (originalFile.fileSize <= 4194304)); } else if (format === 'ppf') { diff --git a/rom-patcher-js/RomPatcher.webapp.js b/rom-patcher-js/RomPatcher.webapp.js index ae05dde..26b5c40 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|ebp|ups|bps|aps|rup|ppf|mod|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 +157,8 @@ IPS.fromFile=function(file){ }else if((file.offset+3)===file.fileSize){ patchFile.truncate=file.readU24(); break; + }else if (file.readU8()===EBP_MAGIC_META_OPENER) { + break; } } @@ -151,10 +174,12 @@ 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 ${'EBP' ? patch.isEBP : 'IPS'} format`); return null; } diff --git a/test.js b/test.js index 2250c71..e002b4c 100644 --- a/test.js +++ b/test.js @@ -14,6 +14,9 @@ - IPS test - Patch: https://www.romhacking.net/hacks/3784/ - ROM: Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb [CRC32=d5ec24e4] + - EBP test + - Patch: https://forum.starmen.net/forum/Community/PKHack/NickBound/page/1#post2333521 + - ROM: EarthBound (USA).sfc [CRC32=dc9bb451] - BPS test - Patch: https://www.romhacking.net/translations/6297/ - ROM: Samurai Kid (Japan).gbc [CRC32=44a9ddfb] @@ -50,6 +53,14 @@ const TEST_PATCHES = [ patchCrc32: 0x0b742316, patchDownload: 'https://www.romhacking.net/hacks/3784/', outputCrc32: 0xf0799017 + }, { + 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: 'BPS - Samurai Kid translation', romFile: 'Samurai Kid (Japan).gbc', From 198c046424ceee639ffe4a510d08c81f2b754dbd Mon Sep 17 00:00:00 2001 From: Supremekirb <99102603+Supremekirb@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:52:30 +0930 Subject: [PATCH 2/4] Fix to default EBP metadata --- rom-patcher-js/modules/RomPatcher.format.ips.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rom-patcher-js/modules/RomPatcher.format.ips.js b/rom-patcher-js/modules/RomPatcher.format.ips.js index 38ec68f..d4aa21c 100644 --- a/rom-patcher-js/modules/RomPatcher.format.ips.js +++ b/rom-patcher-js/modules/RomPatcher.format.ips.js @@ -13,7 +13,9 @@ const IPS_RECORD_SIMPLE=0x01; /* When creating patches, insert this data after everything else. */ /* Finally, EBP doesn't seem to support truncation metadata. */ const EBP_MAGIC_META_OPENER = 0x7B //UTF-8 '{' -const EBP_META_DEFAULT={"author": "Unknown", "title": "Untitled", "description": "No description"} +/* EBPatcher (linked above) expects the "patcher" field to be EBPatcher to read the metadata. Can't imagine why... */ +/* CoilSnake (EB modding tool) inserts this manually too. */ +const EBP_META_DEFAULT={"patcher": "EBPatcher", "author": "Unknown", "title": "Untitled", "description": "No description"} if(typeof module !== "undefined" && module.exports){ module.exports = IPS; @@ -34,7 +36,7 @@ IPS.prototype.addRLERecord=function(o, l, b){ } IPS.prototype.addEBPMetadata=function(author, title, description){ /* currently not used - no frontend support */ - this.EBPmetadata=JSON.stringify({"author": author, "title": title, "description": description}) + this.EBPmetadata=JSON.stringify({"patcher": "EBPatcher", "author": author, "title": title, "description": description}) } IPS.prototype.toString=function(){ nSimpleRecords=0; From 844cfcb5a6412e7e11675066495ca2ce5b158164 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Wed, 30 Apr 2025 01:11:55 +0200 Subject: [PATCH 3/4] refactor and added EBP description showing in frontend --- index.html | 8 +- rom-patcher-js/RomPatcher.js | 6 +- rom-patcher-js/RomPatcher.webapp.js | 2 +- .../modules/RomPatcher.format.ips.js | 85 ++++++++++++------- test.js | 42 +++++---- 5 files changed, 88 insertions(+), 55 deletions(-) diff --git a/index.html b/index.html index 3338326..f0f1021 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,8 @@ Rom Patcher JS - - + + @@ -27,7 +27,7 @@ - + @@ -152,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/rom-patcher-js/RomPatcher.js b/rom-patcher-js/RomPatcher.js index f70ec66..e9e0151 100644 --- a/rom-patcher-js/RomPatcher.js +++ b/rom-patcher-js/RomPatcher.js @@ -242,8 +242,8 @@ const RomPatcher = (function () { format = 'ips'; var patch; - if (format === 'ips' || format === 'ebp') { - patch = IPS.buildFromRoms(originalFile, modifiedFile, format === 'ebp'); + if (format === 'ips') { + patch = IPS.buildFromRoms(originalFile, modifiedFile); } else if (format === 'bps') { patch = BPS.buildFromRoms(originalFile, modifiedFile, (originalFile.fileSize <= 4194304)); } else if (format === 'ppf') { @@ -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 26b5c40..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|ebp|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); @@ -159,7 +172,9 @@ IPS.fromFile=function(file){ }else if((file.offset+3)===file.fileSize){ patchFile.truncate=file.readU24(); break; - }else if (file.readU8()===EBP_MAGIC_META_OPENER) { + }else if (file.readU8()==='{'.charCodeAt(0)) { + file.skip(-1); + patchFile.setEBPMetadata(JSON.parse(file.readString(file.fileSize-file.offset))); break; } } @@ -179,10 +194,14 @@ IPS.fromFile=function(file){ IPS.buildFromRoms=function(original, modified, asEBP=false){ var patch=new IPS(); - patch.isEBP=asEBP - - if(modified.fileSize=IPS_MAX_ROM_SIZE){ - throw new Error(`Files are too big for ${'EBP' ? patch.isEBP : '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 e002b4c..0e0a101 100644 --- a/test.js +++ b/test.js @@ -14,9 +14,6 @@ - IPS test - Patch: https://www.romhacking.net/hacks/3784/ - ROM: Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb [CRC32=d5ec24e4] - - EBP test - - Patch: https://forum.starmen.net/forum/Community/PKHack/NickBound/page/1#post2333521 - - ROM: EarthBound (USA).sfc [CRC32=dc9bb451] - BPS test - Patch: https://www.romhacking.net/translations/6297/ - ROM: Samurai Kid (Japan).gbc [CRC32=44a9ddfb] @@ -26,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] @@ -53,14 +56,6 @@ const TEST_PATCHES = [ patchCrc32: 0x0b742316, patchDownload: 'https://www.romhacking.net/hacks/3784/', outputCrc32: 0xf0799017 - }, { - 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: 'BPS - Samurai Kid translation', romFile: 'Samurai Kid (Japan).gbc', @@ -85,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', @@ -92,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, @@ -139,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); @@ -165,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; } @@ -181,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); From 3b139947374735495186b90cb17a6533eed6ab72 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Wed, 30 Apr 2025 01:15:28 +0200 Subject: [PATCH 4/4] small refactor --- rom-patcher-js/modules/RomPatcher.format.ips.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rom-patcher-js/modules/RomPatcher.format.ips.js b/rom-patcher-js/modules/RomPatcher.format.ips.js index c7957b5..1206131 100644 --- a/rom-patcher-js/modules/RomPatcher.format.ips.js +++ b/rom-patcher-js/modules/RomPatcher.format.ips.js @@ -43,10 +43,11 @@ IPS.prototype.getDescription=function(){ if(this.EBPmetadata){ var description=''; for(var key in this.EBPmetadata){ - if(key!=='patcher'){ - const keyPretty=key.charAt(0).toUpperCase() + key.slice(1); - description+=keyPretty+': '+this.EBPmetadata[key]+'\n'; - } + if(key==='patcher') + continue; + + const keyPretty=key.charAt(0).toUpperCase() + key.slice(1); + description+=keyPretty+': '+this.EBPmetadata[key]+'\n'; } return description.trim(); }