As I've been learning new concepts in ROM Hacking, I've also been developing my own custom tools in Java.
Since they are Java, they should all be cross-platform.
I have finished several tools and I thought I might as well share them.
These are all command-line tools, and they can all be found here;
The first tool I've written is a Relative Search tool. It lets you search binary files for relative sequences, such as strings of text, and also accepts wildcards.
java RelativeSearch zelda.nes 8 false 1 3 -1
That will return something like this:
0001AC19: D8 D9 DC DB
As you can see, the hex value "D8" increases by 1, then by 3, then down by 1.
The "8" is either 8 or 16 depending on whether the ROM uses 8 bits per character or 16 bits per character.
The "false" is either "true" or "false" depending on if you want the relative calculations to be done using signed or unsigned bytes. I believe this probably should almost always be false, but I left the option in there in case there is an exception somewhere.
A character sequence would look something like this:
java RelativeSearch zelda.nes 8 false take?this
This will return something like this:
0000407D: 1D 0A 14 0E 24 1D 11 12 1C
Essentially, a character relative sequence calculates the relative change in values between each character using ASCII values, and searches for that. I used a "?" for the space because it's unlikely an actual space will be the same distance from "e" and "t" as it is in ASCII. The "?" is a wildcard that means any byte.
In fact, that "0000407D" is the location of where the guy in the cave tells link "It's dangerous to go alone. Take this.".
The only wildcard in character sequences is the ?. But in numeric sequences, you can also use "+", "-", and "x".
"+" means the value increases. It can be any value, it just must be larger.
"-" means the value decreases. It can be any value, it just must be less.
"x" means the value changes. It can be any value, it just must be different.
"0" can be used if you want to check if the value doesn't change.
java RelativeSearch zo.nes 8 false 20 + + - - -
000081CF: 1B 2F 6F CF CA 6A 39
1B first changes to 20, then it increases to 6F, then increases to CF, then decreases three times to 39.
java RelativeSearch zo.nes 8 false 0 0 0 x 0 0 x 0 0 0 x
000054F8: 00 00 00 00 F7 F7 F7 FF FF FF FF DC
As you can see, the first value, 00, doesn't change three times, then changes to F7. Then, it changes to FF, then doesn't change three times. Then finally it changes to DC.
The next one I've written is a tile editor for NES games.
For example, if I were to type:
java TileEditor mario.nes -e 2104
I'd get this as an output:
That is the front of Mario's head.
The "-e" means "export", and the "2104" is the tile ID (memory address divided by 16).
If I want, I can dump all the tiles in the entire ROM into a single file using "-d".
The number after "-d" says how many tiles you want per column.
If I were to type:
java TileEditor mario.nes -d 5 > dump.txt
That would produce a pretty large text file, which I'll post here.
You can start finding the graphics around #2100.
We exported a single tile just a little while ago, but we can also import custom tiles.
If we export our Mario head to a file like so:
java TileEditor mario.nes -e 2104 > head.txt
We can then edit the text file. Let's say we change it to Mario without a mouth:
We just save that as a text file, then we can import that into the ROM like so:
java TileEditor mario.nes -i 2104 < head.txt
The third program is very simple, but rather useful. It allows you to create a map file which you can then use to easily convert strings into their hex values and back again.
Here's an example of a map file:
48 = A
49 = B
5A = C
10 = a
11 = b
12 = c
01 = wa
02 = ta
03 = shi
You can then use something like:
HexMapper custom.map AbC
That will output:
48 11 5A
Or another way to use it is:
HexMapper custom.map 1 2 48 3
That will return:
Note that the hex values must be on the left side on the equals sign and the spaces around the equal sign are required.
(I required it so you can use "=" as an actual character.)
It actually supports any base (you can use decimal instead of hex).
I just mainly use hex.
All this can be found a the Github page I linked to at the top.
I will probably update this with more tools once I develop them.
Again, I'm new to this so I'm still learning, so as I learn new stuff I'll probably make more tools.