-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Editing fonts without the aid of a Graphics Editor! A rather useless document written by Neil_! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ---FAQ--- o What will this document teach you to do? - This document will teach you to find and change standard bitplane format fonts using nothing but a hex editor. o Why do I need to know this when there are tools that practicly do it for me? - Knowledge of how fonts are stored will not only give you a more comprehensive idea of how thing in a ROM are stored and arranged, but allow you to copy and paste fonts from one ROM to another! o What do I need to have before reading this lovely piece of writing? - It is expected that you have at least a small interest in ROM Hacking, a firm knowledge of hex math (or a calculator that can perform hex math), a hex editor (HexWorkshop will do nicely), and naga (to test out your work). o Will this document teach me to edit compressed fonts like those in the DragonQuest series? - No. This document will only teach you how to edit non compressed fonts. ---Begin--- ROM files are binary files. That is, they contain executable data run by the system they are meant for. Also included is various types of data used by the games. Today we'll look at bitplane graphics. And more specificly, "fonts". Consoles don't look at them as fonts however, but as simply graphics like pictures. They have no special significance to the ROM, and are only used as pictures, put on the screen in the order that the program reads from the script. This might seem rather pointless to mention, or it might seem like a grand new concept. Either way, there it is. ;) How do consoles like the Gameboy, NES, and SNES store fonts? Most games for these consoles store at least one font in 8 pixel by 8 pixel boxes in what we call bit plane encoding. Picture, if you will, something that looks like this: _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| A perfectly empty 8x8 grid, ne? Well, lets say we wanted to draw a letter in there.. The letter 'A': _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_| |_|_|x|x|x|x|_|_| |_|x|_|_|_|_|x|_| |_|x|_|_|_|_|x|_| |_|x|x|x|x|x|x|_| |_|x|_|_|_|_|x|_| |_|x|_|_|_|_|x|_| |_|x|_|_|_|_|x|_| See the letter in there? =) If you know how base 2 (binary) works, you probably have a decent idea of what comes next. A binary number is traditionally written in 8 bits, that is 00000000. If you notice, our grid up there is exactly 8 bits long! We could easily turn that into a nice binary string by making the empty boxes 0s and the boxes with the letter x in them 1s. 00000000 00111100 01000010 01000010 01111110 01000010 01000010 01000010 Ok. So now what? We've got 8 binary numbers. Well, most ROM hackers seem to like hex, so how about we convert those lovely binary numbers to hex? 00000000=00h 00111100=3Ch 01000010=42h 01000010=42h 01111110=7Eh 01000010=42h 01000010=42h 01000010=42h So, we've got 003C 4242 7E42 4242. Well, fire up hex workshop, create a new file, and hit -insert. In the box that pops up, type in 8 and select 'hex'. Type in 003C 4242 7e42 4242, and save the file as 'font.fnt'. Open it up in naga. In the upper left corner of the display window, you should see our lovely letter A. What's all that other junk? Just random stuff in memory. Ignore it all. You've now been let on to the key to understanding bitplane graphics. All of the types of fonts you're going to encounter in SNES, GB, or NES games are going to be built off of this basic concept. It's really not of much use to know this stuff for most people because these days with tools like Naga and tile layer, it's just as easy to use them to perform basic operations. One area where they lack currently however is copying fonts from one game to another. Tile Layer has support for having two files open at once, but copying 60 or so tiles from one game to another is a very slow and tedious process. This is the main area where this knowledge will come in handy. If you can open the ROM up in Tile Layer and do a quick conversion to binary, you can use hex workshop to find where the font is located and simply copy and paste the font. Tada! A job that would have taken 30 minutes now takes 5. Knowing this will also help you rip fonts and store them for later use and again, easy insertion. There are two other font types that you'll need to know about, 2 bit plane and 4 bit plane fonts. As I said earlier, they're basicly the same as 1 bit plane fonts, just with a little twist. For 2 bit plane fonts, picture 2 boxes: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| Well, 2bp (bit plane) is just like 1 bp but with one other plane. The numbers in the other plane influence the color of the completed font tile. There are 4 possible colors. For simplicity sake, we'll call them 1,2,3 and 4. Lets say we have the following: Plane 1 Plane 2 00000000 00000000 00111100 00000000 01000010 00000000 01000010 00000000 01111110 00000000 01000010 00000000 01000010 00000000 01000010 00000000 So plane 1 is just like it was before in our 1bp experiment, and plane 2 is empty. In the rom, 2bp is stored like this: Line 1 from plane 1, line 1 from plane 2, line 2 from plane 2, and so on. So for our example it would be stored like this: 00000000 00000000 00111100 00000000 01000010 00000000 01000010 00000000 01111110 00000000 01000010 00000000 01000010 00000000 01000010 00000000 So, convert those binary to hex! 00 00 3C 00 42 00 42 00 7E 00 42 00 42 00 42 00 Yes, this time all we did was insert a 00 after each of the hex bytes we had last time. Open up hexworkshop and create a new file. Insert 16 bytes. Type in the above hex string, and open it up in naga. Switch to 2bp mode. Looks just like the 1bp font, right? Hmm. How do we use those other colors? Lets try this: Plane 1 Plane 2 00000000 00000000 00000000 00111100 00000000 01000010 00000000 01000010 00000000 01111110 00000000 01000010 00000000 01000010 00000000 01000010 So this time it would be stored like this: 00000000 00000000 00000000 00111100 00000000 01000010 00000000 01000010 00000000 01111110 00000000 01000010 00000000 01000010 00000000 01000010 So, convert those binary to hex! 00 00 00 3C 00 42 00 42 00 7E 00 42 00 42 00 42 Well lookie there! Color 3(color 1 is black, and color 2 is the one we had with 1bp)!! If you haven't guessed by now, color 4: Plane 1 Plane 2 00000000 00000000 00111100 00111100 01000010 01000010 01000010 01000010 01111110 01111110 01000010 01000010 01000010 01000010 01000010 01000010 Split it up again: 00000000 00000000 00111100 00111100 01000010 01000010 01000010 01000010 01111110 01111110 01000010 01000010 01000010 01000010 01000010 01000010 Convert those binary to hex again: 00 00 3C 3C 42 42 42 42 7E 7E 42 42 42 42 42 42 Yup, indeed. After checking it out in Naga, it's none other but the elusive color 4! Well, I'm not bored enough to tackle 4bp here, but after running through the motions with 2bp, you should have a basic clue of what's going to happen. We've got a total of 16 lovely color combinations, and a grid that would look something like this: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| If after doing 2bp fonts you can't figure this one out on your own, bitch in my general direction and I'll go through the entire thing in this doc. Otherwise, I'd rather not waste an hour of my time. :P Those are the three major font types that you're likely to encounter in your ROM hacking career, although knowing some of these weird coders, you'll probably find some interesting hybrid format somewhere or other that'll piss you off to no end. Just remember that it's gotta be bitplane, and thus by disecting it and playing with it for a while, the answer will stare you in the face. As for SNES 16x16 size fonts, those can wait for v2.0 of this doc. When will that be finished? The next time I get bored. -Neil_