It involves editing pointers. Basically, pointers are integers that store the address of data, like the first letter in a string. Typically, there is a table of pointers either before or after the data; in DKC's case, it's before. Perhaps it will make more sense if I do an example.
The string "Stop & Go Station" starts at 0x38A6F1 in the ROM. Now, to calculate the pointer in an SNES game like DKC (I assume this is the case for all SNES games, although I haven't done much SNES hacking at all), you must cut off all but the last four nibbles (a nibble in hexadecimal is like a digit in decimal). So for here, 38A6F1 becomes A6F1.
But you're not done yet... Nintendo systems are, in general, little-endian, so you must
reverse the bytes. Each byte is two nibbles long; so in this case, you switch A6 with F1 to get F1A6. There's your pointer.
Now how do you find it? Search for the hex string F1 A6 in a hex editor. In XVI32, you can search upwards; search once (in this case) and you'll find the pointer table; the pointer F1 A6 is at 0x38A320. How do you know it's a pointer table? You can see a little pattern here:
... C7
A6 D8
A6 E7
A6 F1 A6 02
A7 0E
A7 1F
A7 ...
The red is the pointer that you are searching for. The bold is meant to indicate a pattern. They are all similar to each other (they start out as A6 (at least from what I pasted here) and become A7, and so on), and the bytes just before the bold increase a little each time. Whenever you see something like this, chances are pretty good you found a pointer table.
Now, something important. If you want to change the text from "&" to "and", you'll have to expand this string. And by doing this, you are going to
shift all the strings afterwards (in this case, two bytes). Therefore, to make the game search in the right spots, you'll have to adjust the pointers for any text that comes after "Stop & Go Station". So anything that comes after F1 A6, you'll have to increase the values of these pointers (in this case, by 2). Remember that pointers are little endian, so don't be confused! It's tedious, but it's certainly possible to do.
------------------
Now this part is a bit extra, but here's how to calculate pointers for GB/GBC and GBA games in case anybody's curious:
GBA: Unlike the SNES, pointers are four bytes instead of two (so basically it's ww xx yy zz instead of yy zz). However, you must add 0x8000000 to the address to make it a pointer. So an address of 0x123456 would become 0x08123456. And like before, GBA is little endian, so you must switch the bytes! So 0x08123456 becomes 56 34 12 08. (Although, I've heard of exceptions to this latter rule, but I haven't seen any.)
GB/GBC: There are 2-byte and 3-byte pointers. 2-byte pointers are limited in the area that you can address (only a range of 0x4000 bytes), but they're more common since they take up less space. 3-byte pointers can point to anything in the ROM. I'll go over 2-byte pointers first.
- 2-byte pointers: Obviously, these are two bytes long. Like the SNES, you must only have the last two bytes (123456 becomes 3456, for example). However, there's something tricky here! If this new address is outside the range of 0x4000-0x7FFF, you must add or subtract by a multiple of 0x4000 to make it fit in this range! So basically, the formula is:
pointer = (address mod 0x4000) + 0x4000
Another way to think of it is:
- If the two-byte address is from 0x0000-0x3FFF, add 0x4000.
- If the two-byte address is from 0x4000-0x7FFF, do nothing.
- If the two-byte address is from 0x8000-0xBFFF, subtract 0x4000.
- If the two-byte address is from 0xC000-0xFFFF, subtract 0x8000.
So for example, if the two-byte address is 0x3456, you add 0x4000 to make it 0x7456.
And of course... like other Nintendo systems, Game Boy and Game Boy Color are little endian. So switch the bytes! For example, 0x7456 becomes 56 74.
However, there are exceptions, such as Donkey Kong Land 2 and Donkey Kong Land III. These are rare, and I don't know of any others.
- 3-byte pointers: This is similar, except there's another byte you have to have before the normal two bytes. And no, it's not as simple as truncating the address to three bytes. You must find the ROM bank of the address. It's simple, just divide by 0x4000 and discard the remainder. So for example, if you have an address of 0x123456, the ROM bank is (0x123456/0x4000)=0x48. That's your first byte.
The last two bytes are calculated the same way as before, so it would be 74 56. The full three-byte pointer would be 48 74 56.
------------------
If that was all confusing, then this may help instead:
http://datacrystal.romhacking.net/wiki/Pointer