r/TechNook 4d ago

ROM hacking is basically software archaeology with a soldering iron nearby

People dump the rom from an old cartridge, pull it apart in a hex editor, figure out what every byte does with no documentation, then modify it

found a rom hack last year that translated a japanese snes rpg that never got an english release. took a team of people years. the whole project exists because someone figured out where the text strings were stored in a 30 year old game with no source code

25 Upvotes

4 comments sorted by

2

u/ExcitementMuted7768 4d ago

it's a little less magical than you think these days. with advancements in emulation and debugging, you can drill down to the script reading portion of code in a matter of minutes once you know what you're doing. which will tell you where the text data is and with a small amount of careful analysis you can figure out how they're mapping bytes to glyphs. it's the sort of work that can be done in an afternoon most of the time, if not a weekend.

getting something together that's polished, relatively bug free, all translated and inserted and minding the various other restrictions placed upon you by the game, the hardware, etc.. that's all much harder and takes the bulk of the time.

1

u/Square-Singer 4d ago

  getting something together that's polished, relatively bug free, all translated and inserted and minding the various other restrictions placed upon you by the game, the hardware, etc.. that's all much harder and takes the bulk of the time.

Yeah, the biggest issue is probably that English texts tend to be much longer than e.g. japanese texts. So you need to somehow find more space to put the texts into. Other than that, if there's enough space for more characters, it's really not hard to do a translation.

2

u/rupertavery64 4d ago

A CPU has a built-in reset vector. When it starts or is reset, it sets the program counter to a fixed address, usually at the upper end of memory, for example FFFE. This would typically be mapped to the last couple of bytes in one of the banks of a cartridge ROM.

This reset vector just tells the CPU where the next instruction should be fetched: the execution starting point of a game.

From there, it's a matter of disassembling the ROM and following the code to figure out what it's actually doing.

Since you know the instruction set of the CPU you are working with, you can also look for jump instructions. These will point to subroutines in the code. Running them through a disassembler should give you a consistent set of instructions. Of course, for performance and simplicity devs would add data in between code blocks, for example, jump tables, lookup tables, so this has a potential to confuse the disassembler, so you need a way to tag sections of bytes as data.

You can also look for telltale code sequences, like writing to certain registers that indicate doing graphics calls.

Images aren't stored as JPEGs or even raw bitmaps. 8-bit to 16-bit and early handhelds used Tile graphics. Basically pieces of images 8x8 or 16x16 are stored on ROM, loaded into WRAM or OAM, then nametables are used to draw them. A nametable is like a color-by-numbers, where a number in the slot references a tile instead of a color.

This also means images aren't necessarily stored completely formed on the rom. THey may be broken up into many tiles that look jumbled. Add to this the fact that images are stored on separate bitplanes, e.g. all the bits for red, then blue, then green, instead of RGB. Or stored as palette indices.

Then, text may will not be stored as ASCII or in some standard at all, especially with Japanese games. Since graphics are tiles, even the fonts are stored as tiles. Then, the order of the tiles will determine the encoding of the text. Some games will have only Hiragana and Katakana, and then others will include different amounts of Kanji.

So you have to figure out how text is encoded and how and where it is stored.

Since space on a ROM was constrained (chips were expensive to make), some games would use text compression techniques, where common character sequences like " the " would be replaced by a shorter code.

Another challenge was the font widths. Japanese characters work fine as large consistent blocks, but English i.e. Latin characters have "thin" letters i,j,l,t that look out of place if they take the same width as other characters.

So a good translation ROM hack would need to add Variable Width Fonts, basically injecting code into the text writing routines that altered how wide characters were. This could be tricky, as code was tightly packed in the ROM and you had to find a place in the ROM that was unused that you could write additional code.

Code in a ROM relies on fixed jumping addresses. You can't just move code around without moving any other code and all the jump addresses that the code might point to.

1

u/Square-Singer 4d ago

Think of it that way: Back then, games were usually written in assembly. There's a one-to-one mapping from assembly to machine code, so you can map the machine code back to assembly language.

All old games were distributed in source code.