CloudMax Posted January 28, 2014 Share Posted January 28, 2014 Version 1.1 has now been released. You can use it online or download it at http://cloudmodding.com/app/rompatcher You can also download it here on The GCN at (Keep in mind that it is released roughly 1 day later on the-gcn) https://www.the-gcn.com/files/file/71-cloudmaxs-rom-patcher/ Patch format information is available here. So, as we all know, there is this thing called .ppf. It is an effective format for finding differences between two files and creating patch files that can be shared and then applied by others. However, as I was working on a project I noticed that .ppf just didn't make the cut. It was close to impossible to organize things, and no easy way of seeing what the patch actually does. So I began developing my own patcher, and based it on the Texture Packer that I've written. To apply a patch, simply drop the patch .txt file and the ROM on the tool together. Or drop two ROM files on it to generate a patch of the differences between the two. This patcher, unlike .ppf, is being developed for modders, as well as being a simple tool that can be used to generate patches which can then be re-applied by others. The patch file is in plain text, and the reason why will be very obvious soon enough. Here is an example of a patch file that was generated by the patcher. It compared a clean OoT Debug ROM with one that I had applied the MM Interface Color hack to: 0xB00322,FF82 0xB00326,3C 0xB8808B,64 0xB88097,FF 0xB880B0,2419 0xB880B3,78 0xB880B5,1906 0xB880BF,FF 0xB880DC,240E 0xB880DF,64 0xB880E1,AE 0xB88637,FF 0xB88654,240E 0xB88658,A72E As you can see, each line represent an offset that the patch writes to, which is then followed by a hex string, that can be of any length, that should be written at the specified address. Now for the thing that makes this patcher so different from ppf. The patcher supports complicated expressions, pointers, variables, conditions, alerts and comment lines among other things. To create a variable, you create a line formatted like this: var,<variable name>,<variable value> For example: var,dma,0x12F70 To use a variable, you place it's name surrounded by curly brackets in the address. So you could do something like this: var,code,[{dma}+0x10*28] Now variable code will be [0x12F70+0x10*28], which is [0x13130]. 0x13130 happens to be the location in the dmatable that points to the code.zasm file in the OoT Debug ROM. By placing square brackets around an address, it'll act as a pointer, and it reads the 32bit value inside the ROM at the specified address. So variable code would become 0x00A94000. We can now use variable code to write data relative to the code.zasm file. For example: {code}+0x6C322,FF82 it'd turn into 0x00A94000+0x6C322, which is 0xB00322. So it would write 0xFF82 to 0xB00322. By starting a line with a semicolon, the line will be treated as a comment. Now if we combine everything that we have mentioned above, we're able to write a quick patch. Here is a patch I wrote that does a few minor ASM changes and set all the Interface Button Colors to the Majora's Mask Colors: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Set up variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;0x12F70 is the address of the dmatable. var,dma,0x12F70 ;Each dmatable entry is 0x10 bytes. code.zasm is the 28th entry. var,code,[{dma}+0x10*28] ;0x8001CE60 is the offset of the code.zasm file when loaded into ;RAM, we'll use it to convert code.zasm RAM addresses to ROM. var,codeRAMtoROM,{code}-0x8001CE60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Patch ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;A Button Red (0x64) RR {codeRAMtoROM}+0x80110F3C, 240E 0064 A5AE 0AC0 ;A Button Green (0xC8) GG {codeRAMtoROM}+0x80110F08, 240F 00C8 ;A Button Blue (0xFF) BB {codeRAMtoROM}+0x80110F1C, 2419 00FF ;B Button Red (0x64) RR {codeRAMtoROM}+0x80110EE8, 240E 0064 ;B Button Green (0xFF) GG {codeRAMtoROM}+0x80110EF4, 2403 00FF ;B Button Blue (0x78) BB {codeRAMtoROM}+0x80110F10, 2419 0078 A719 06EE ;C Button Red (0xFF) RR {codeRAMtoROM}+0x801110E8, 240D 00FF ;C Button Green (0xFF) GG {codeRAMtoROM}+0x80111494, 2418 00FF ;C Button Blue (0x00) BB {codeRAMtoROM}+0x801114B4, 240E 0000 A72E 07E6 ;S Button RGB (0xFF,0x82,0x3C) RRGG BB {codeRAMtoROM}+0x80089180, 3C01 FF82 3421 3C00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; I now had the patcher convert the RAM addresses into ROM addresses for me, and it uses the dmatable to determine where the code.zasm file is. This makes the patch flexible and usable no matter which file has been extended or shortened before it. Now for some other nifty little commands. You can create alerts by formatting a line like this: alert,<alert message> An alert is a small red bar that appear at the top of the page for 5 seconds with a message, before it disappear. If there already is one on the screen, it will be replaced. You can abort the patch, ending the execution of the patch and preventing the patcher from downloading a new ROM, by simply writing "abort" on a line. You can also end execution of the patch by writing "end" on a line. Unlike the abort command, this will still download a ROM of all the changes that have already taken place. Now, both "abort" and "end" are completely useless without the conditional command. You set up a conditional command like this: con,<condition ID>,<condition> and you end the condition with a command like this: endcon,<condition ID> The way you use it is very simple. The Condition ID is used so that the patcher knows which endcon command is connected to which condition. If the condition is true, the code between the con and endcon commands will be executed, otherwise they're skipped. Here's an example: var,skip,(1==2) con,ID,{skip} alert,1 is equal to 2. end endcon,ID alert,1 is not equal to 2. If 1 is equal to 2, it will perform the alert saying that they're equal, then end the patch. Otherwise the alert saying that they are not equal will be performed and the patch will continue on. Here is a patch I wrote for the Debug ROM. It uses all commands except for "end". ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Patch written by CloudMax ;This patch is for TLoZ: Ocarina of Time Master Quest Debug ROM ; ;It will make a few minor changes to the games code to allow ;setting up all the RGB colors of the A, B, C and Start buttons ;on the Interface individually. ; ;The colors are set to the ones used in Majora's Mask. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Check if ROM ID or Version is Incorrect ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;We look up the ID and Version number of the ROM. ;If the ROM ID & Version isn't 0x4E5A4C450F or 0x435A4C450F ;an alert will appear, and the patch is aborted. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; var,romID,([0x3B]*0x100)+([0x3C]&0xFF) con,patchable,!({romID}==0x4E5A4C450F||{romID}==0x435A4C450F) alert,The provided ROM has an incorrect ID or Version. abort endCon,patchable ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Set up variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;First we set variable dma to the address of the dma table. ;Then we take that and add 0x10 multiplied by the code.zasm ;entry ID in the table, which is 28. ;We set variable code to the pointer at that address. ;We set variable codeRAMtoROM to code subtracted by the offset ;of code.zasm when it is loaded into RAM so that we can convert ;RAM addresses to ROM addresses. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; var,dma,0x12F70 var,code,[{dma}+0x10*28] var,codeRAMtoROM,{code}-0x8001CE60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Patch ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;A Button Red (0x64) RR {codeRAMtoROM}+0x80110F3C, 240E 0064 A5AE 0AC0 ;A Button Green (0xC8) GG {codeRAMtoROM}+0x80110F08, 240F 00C8 ;A Button Blue (0xFF) BB {codeRAMtoROM}+0x80110F1C, 2419 00FF ;B Button Red (0x64) RR {codeRAMtoROM}+0x80110EE8, 240E 0064 ;B Button Green (0xFF) GG {codeRAMtoROM}+0x80110EF4, 2403 00FF ;B Button Blue (0x78) BB {codeRAMtoROM}+0x80110F10, 2419 0078 A719 06EE ;C Button Red (0xFF) RR {codeRAMtoROM}+0x801110E8, 240D 00FF ;C Button Green (0xFF) GG {codeRAMtoROM}+0x80111494, 2418 00FF ;C Button Blue (0x00) BB {codeRAMtoROM}+0x801114B4, 240E 0000 A72E 07E6 ;S Button RGB (0xFF,0x82,0x3C) RRGG BB {codeRAMtoROM}+0x80089180, 3C01 FF82 3421 3C00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Everything is case-insensitive. condition IDs and Variable names may only consist of letters and underscores. the hex string may contain spaces, they are automatically omitted by the patcher. 4 Link to comment Share on other sites More sharing options...
CloudMax Posted February 17, 2014 Author Share Posted February 17, 2014 Version 1.1 is now released. The patcher should no longer cause the browser to freeze when comparing two files. You can now provide multiple patch files at once by using .zip archives. Many new commands are now available, and other improvements have been made to the parser, such as support for tabs, comments at the end of lines, etc. You can read more about the new commands that are available here: http://cloudmodding.com/applications/rompatcher/patch_format.txt Link to comment Share on other sites More sharing options...
Recommended Posts