/* ips-patcher.js v20160416 - Marc Robledo 2016 - http://www.marcrobledo.com/license */ /* Implement 3-byte reader/writer in MarcBinFile */ MarcBinFile.prototype.readThreeBytes=function(offset){ return (this.readByte(offset+0) << 16)+(this.readByte(offset+1) << 8)+(this.readByte(offset+2)) } MarcBinFile.prototype.writeThreeBytes=function(offset,val){ this.writeBytes(offset, [(val & 0xff0000) >> 16, (val & 0x00ff00) >> 8, (val & 0x0000ff)]); } /* Shortcuts */ function addEvent(e,ev,f){e.addEventListener(ev,f,false)} function el(e){return document.getElementById(e)} /* IPS file format doc: http://www.smwiki.net/wiki/IPS_file_format */ var RECORD_RLE=0x0000; var RECORD_SIMPLE=1; function IPS(){ this.records=[]; this.truncate=false; } IPS.prototype.addSimpleRecord=function(o, d){ this.records.push({offset:o, type:RECORD_SIMPLE, data:d}) } IPS.prototype.addRLERecord=function(o, l, b){ this.records.push({offset:o, type:RECORD_RLE, length:l, byte:b}) } IPS.prototype.toString=function(){ nSimpleRecords=0; nRLERecords=0; for(var i=0; iromFile.fileSize){ alert('Invalid ROM file (too big?).'); return false; } }else{ if(rec.offset+rec.data.length>romFile.fileSize){ alert('Invalid ROM file (too big?).'); return false; } } } var patchedFile=new MarcBinFile(romFile.fileSize); patchedFile.fileName=romFile.fileName.replace(/\.(.*?)$/, ' (patched).$1'); var clonedFileSize=this.truncate || romFile.fileSize; for(var i=0; i16777215) alert('Too big ROM file'); }); } function openROM1(f){ romFile1=new MarcBinFile(f, function(){ if(romFile1.fileSize>16777215) alert('Too big ROM file'); }); } function openROM2(f){ romFile2=new MarcBinFile(f, function(){ if(romFile2.fileSize>16777215) alert('Too big ROM file'); }); } function openIPS(f){ tempFile=new MarcBinFile(f, readIPS); } function readIPS(){ tempFile.littleEndian=false; if(tempFile.readString(0,5)!=='PATCH'){ MarcDialogs.alert('Invalid IPS File'); return false; } ipsFile=new IPS(); var EOF=false; var seek=5; while(seekmodified.fileSize){ seekStart--; } for(var i=seekStart;i>0 && nearbyDifference;i--){ var bc1=original.readByte(seek+i); var bc2=modified.readByte(seek+i); if(bc1!=bc2){ length+=i; seek+=i; break; }else if(i==1){ nearbyDifference=false; } } } var data=modified.readBytes(originalSeek, length); /* check RLE record */ for(var i=1; i0;e++)d+=String.fromCharCode(c[e]);return d},MarcBinFile.prototype.writeByte=function(a,b){this.fileReader.dataView.setUint8(a,b,this.littleEndian)},MarcBinFile.prototype.writeByteSigned=function(a,b){this.fileReader.dataView.setInt8(a,b,this.littleEndian)},MarcBinFile.prototype.writeBytes=function(a,b){for(var c=0;c