JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<input type="file"/>
<br><br>
<select id="footer">
<option disabled selected>-- Select a footer --</option>
<option value="47020000CD10700274066A380C00000043616E31">S-2002_e BRAWL BROTHERS</option>
<option value="470200004411740670010A00000043616E31">S-2003_e Breath Of Fire</option>
<option value="4702000046117646740670010C00000043616E31">S-2004_e Demon's Crest</option>
<option value="47020000621274067002500400001E0000001200000043616E31">S-2006_e Joe & Mac 2: Lost in the Tropics</option>
<option value="4702000058107682740670020C00000043616E31">S-2007_e Kirby's Dream Course</option>
<option value="47020000A2107678740670020C00000043616E31">S-2008_e Kirby's Dream Land 3</option>
<option value="47020000C710700174060A00000043616E31">S-2013_e SUPER E.D.F. EARTH DEFENSE FORCE</option>
<option value="4702000003107628740670010C00000043616E31">S-2015_e Super Ghouls'n Ghosts</option>
<option value="47020000BD10740663016A3870020E00000043616E31">S-2016_e Super Mario Kart</option>
<option value="4702000011107691740670020C00000043616E31">S-2017_e Super Mario World</option>
<option value="470200004712700476A574060C00000043616E31">S-2020_e Super Puyo Puyo 2</option>
<option value="470200004112740670020A00000043616E31">S-2021_e Super Soccer</option>
<option value="470200006612740770020A00000043616E31">S-2022_e Super Tennis</option>
<option value="470200001D107682740670010C00000043616E31">S-2024_e The Legend of Zelda: A Link to the Past</option>
<option value="470200004A126803740670040C00000043616E31">S-2014_j Super Family Tennis</option>
<option disabled>-- Super FX --</option>
<option value="470200003B12650C74067001550200003C051200000043616E31">S-2011_e Star Fox</option>
<option value="470200003E12650C74067002550200003C051200000043616E31">S-2012_e Stunt Race FX</option>
<option value="470200003D12650C74067001550200004A061200000043616E31">S-2023_e Super Mario World 2: Yoshi's...
JavaScript
document.querySelector('select').addEventListener('change', processSelection, false);
document.querySelector('button').addEventListener('click', processDownload, false);
function processDownload() {
var file = document.querySelector('input').files[0];
var sel = document.querySelector('select');
var pid = document.getElementById('pid').value;
if (file && sel.options.selectedIndex && pid.length == 4) {
var reader = new FileReader();
reader.onload = function() {
var romBytes = new Uint8Array(reader.result);
var footerHex = sel.options[sel.selectedIndex].value;
var footerBytes = new Uint8Array(Math.ceil(footerHex.length / 2));
for (var i = 0; i < footerBytes.length; i++) {
footerBytes[i] = parseInt(footerHex.substr(i * 2, 2), 16);
}
if (pid != footerHex.substr(10, 2) + footerHex.substr(8, 2)) {
footerBytes[4] = parseInt(pid.substr(2, 2), 16);
footerBytes[5] = parseInt(pid.substr(0, 2), 16);
}
var joinedBytes = new Uint8Array(romBytes.byteLength + footerBytes.byteLength);
joinedBytes.set(romBytes);
joinedBytes.set(footerBytes, romBytes.byteLength);
var blob=new Blob([joinedBytes], {type: "application/octet-stream"});
if (window.navigator && window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, 'test.sfrom');
} else {
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="test.sfrom";
document.body.appendChild(link)
link.click();
}
}
reader.readAsArrayBuffer(file);
} else {
alert("File, footer or preset invalid");
}
}
function processSelection(evt) {
document.getElementById('pid').value = evt.target.value.substr(10, 2) + evt.target.value.substr(8, 2);
}
// https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input
// Restricts input for the given textbox to the given inputFilter.
function...