News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: New to Hacking -- Script and Graphic Editing?  (Read 7988 times)

milkmanjack

  • Jr. Member
  • **
  • Posts: 10
    • View Profile
New to Hacking -- Script and Graphic Editing?
« on: February 24, 2012, 06:22:02 pm »
I've recently decided to take up a bit of rom hacking, just for fun. My main goal is to eventually have the skills necessary to translate games and such. My first attempt to do this, I decided, would be with Pokemon Red for Gameboy, for no particular reason other than I really enjoy the game, and it is quite easy to read.



The first thing I decided to do was to find out how to locate/view the scripts. I read about tables, and about some techniques to determine what bytes represent what "font entity." What I did was made two save files, made the characters names in reverse, and then did a comparison. After looking through the places with a 5 byte difference, I found where character names are stored, and the range that is used.

This is pretty much where I'm at right now. My next goal is to figure out how to A) edit the in-game font, so that I may change the language the game draws in (to English), and B) edit the script in ways that allow me to add extra text.

For A, I have tried a few graphic editor tools. Almost all of them result in the output being garbled except in a few places. After looking around, this seems to be because the graphics are compressed. Unfortunately, I have no idea how to continue at this point...  I've tried a few things, but I can't seem to find what I need.

For B, from what I have read in the past, changing script sizes can be a problem. Due to the way pointers are, changing lengths of one thing require you to move pointers of other things. One thing I was trying to do was find references to the beginnings of dialogue in hex form, but I couldn't find anything for any of the few dialogue entries I tried.

If anyone has any useful information of resources I could use for this, I'd really appreciate it. This is something I'm kind of really interested in doing, but I have very little experience with handling files like this... as in, none.

Thanks!
« Last Edit: February 24, 2012, 06:32:25 pm by milkmanjack »

tashi

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #1 on: February 24, 2012, 10:09:22 pm »
I recommend using Crystal Tile 2. It is the super best, easiest to use application.
You can find it in the utility section here on RHDN: http://www.romhacking.net/utilities/818/

If you use it and mosey over to offset $10B19 and use 1bpp mode, you will see the whole, uncompressed Japanese alphabet ()

From your screenshot, it looks like you managed to create a complete table. That was probably hard without knowing the order of the letters? But kudos to you for doing it.

To make an English font, it is as easy as just pasting in a 1bpp bitmap of your font. I literally just type out the alphabet in photoshop, copy it, and paste it directly into Crystal Tile 2, starting wherever the Japanese alphabet started (though it could be anywhere, that is just a convenient place). Be sure to save the ROM afterward.

If the katakana alphabet started with アイウエオ, then in your table, script, and WindHex you can see those letters correspond to values 30, 31, 32, 33, 34 (hypothetically). If you pasted your alphabet starting with "abcde" on top of those letters, now, those values correspond to your English letters. If you think about "7F" not referring to ま, but referring to the tile which stores some graphical data that happens to look like ま, it should be easier to understand. If you put a heart image in that same box and then you run the game, all ま letters would be turned into hearts.

Everyone else on this board is smarter than I am, and I'm sleepy, so I'll leave my explanation as it is. If no one has told you how to deal with pointers by the morning, I'll share what I know on that end.

milkmanjack

  • Jr. Member
  • **
  • Posts: 10
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #2 on: February 25, 2012, 12:11:45 am »
I recommend using Crystal Tile 2. It is the super best, easiest to use application.
You can find it in the utility section here on RHDN: http://www.romhacking.net/utilities/818/

If you use it and mosey over to offset $10B19 and use 1bpp mode, you will see the whole, uncompressed Japanese alphabet

This worked quite well. On the Japanese version, it showed the font perfectly. When I tried it on the English version just to see if it'd work, it seemed to start drawing the alphabet characters 1 pixel too low, as the top pixel of the font characters were cut off. Not a big deal, but anyway...

From your screenshot, it looks like you managed to create a complete table. That was probably hard without knowing the order of the letters? But kudos to you for doing it.

What I did was just create 2 savefiles and compare the bytes. I did this initially to find the location of the character names in the files. To start with, I named the character アイウエオ. This revealed that those bytes started at 80 and ended at 84. Then I tested characters in the K category, and saw that it started just after オ, from the bytes 85 to 59.  Then I created a generic table starting from what I knew, A-O and KA-KO, and did S, T, N, H, M, and so on relative to this data. It required a bit of time to get the rest of the characters, since they weren't as intuitively placed.

After I got the entire library of obvious characters, I opened it up and looked for the intro dialogue while running the game. From there, I just looked for patterns to determine what certain bytes did. It took me quite awhile to realize the specific functions of the "end" codes. I still am pretty sure I don't fully "get" them. I tested out the "fade out" byte, but the fade only occurred when it normally did during the intro (meaning it probably isn't a dialogue function, but the function of the game itself). I found all it did by putting it in there was end that dialogue (with a pause), and then jump to the next dialogue.

I also found out that there is a special code, represented with [50], that seems to act like a kind of reference character. For example, when it occurs in dialogue, when it gets to the byte sequence [50 14 00], it plays the Nidorino growl sound. You can play with the second byte to make it play different sounds, though certain ones make it start printing stuff beyond the dialogue box and eventually crash, or sometimes completely skip the intro dialogue, assigning specific values for your name and your rival's name. [50 01 68 CD 00] seems to be a reference to the pokemon your rival picks during the opening bit ("(Rival) received (pokemon) from Oak").

Still not entirely sure how the references work, but yeah.

To make an English font, it is as easy as just pasting in a 1bpp bitmap of your font. I literally just type out the alphabet in photoshop, copy it, and paste it directly into Crystal Tile 2, starting wherever the Japanese alphabet started (though it could be anywhere, that is just a convenient place). Be sure to save the ROM afterward.

If the katakana alphabet started with アイウエオ, then in your table, script, and WindHex you can see those letters correspond to values 30, 31, 32, 33, 34 (hypothetically). If you pasted your alphabet starting with "abcde" on top of those letters, now, those values correspond to your English letters. If you think about "7F" not referring to ま, but referring to the tile which stores some graphical data that happens to look like ま, it should be easier to understand. If you put a heart image in that same box and then you run the game, all ま letters would be turned into hearts.

Yeah, I just played with it a little and replaced some characters. Ultimately, once I replace all the font characters, I'll have to retype every line of dialogue. I will probably write a program to do this for me, so I don't have to do it all in a hex editor... I hope I'm competent enough to do so.  Probably just a simple command line program.

Everyone else on this board is smarter than I am, and I'm sleepy, so I'll leave my explanation as it is. If no one has told you how to deal with pointers by the morning, I'll share what I know on that end.

I really appreciate the help, too. With the ability to edit the font, I could theoretically begin translating right now. The only problem being I don't know how feasible it is to translate with the current string lengths. Converting ”グリーンは オーキドから ヒトカゲを もらった!” to "Green received Charmander from Oak!" would be impossible, for example. Even if I just reduce it to "Green received Charmander!", it's still too long! Not to mention the maximum name length is 5 characters! huhuhuhuuuuuu......  :-\

Ryusui

  • Hero Member
  • *****
  • Posts: 4989
  • It's the greatest day.
    • View Profile
    • Tumblr
Re: New to Hacking -- Script and Graphic Editing?
« Reply #3 on: February 25, 2012, 12:54:05 am »
Well, for string lengths, you'd dump the entire script to a text file using Cartographer, format it for reinsertion, edit it as you saw fit, and reinsert using Atlas.

String lengths are dictated by pointers, which are address values telling the game where to look for each string. A properly-edited Atlas script will have pointer tags telling the inserter where each new string starts and where in the pointer table to write the new value.

For name lengths...well, there's no easy way around that. You'd have to hack the game to use the same ten-letter method as the US versions, not to mention reposition on-screen text and add an extra page to the Pokédex entries.

Really, Pokémon is probably an awful choice for a first translation hacking project. It does have the advantage that you have an English script to compare with, but the amount of hacking you'd need to do makes such a project unfeasible. Though if you're dead set on translating one, FireRed might be a better choice. Since Pokémon can be traded between different language versions in the Gen 3 games, it's likely you won't have to do as much hacking (or any at all, really) to get ten-letter names.
In the event of a firestorm, the salad bar will remain open.

milkmanjack

  • Jr. Member
  • **
  • Posts: 10
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #4 on: February 25, 2012, 01:59:37 am »
Well, for string lengths, you'd dump the entire script to a text file using Cartographer, format it for reinsertion, edit it as you saw fit, and reinsert using Atlas.

String lengths are dictated by pointers, which are address values telling the game where to look for each string. A properly-edited Atlas script will have pointer tags telling the inserter where each new string starts and where in the pointer table to write the new value.

I think the only problem with this is that I have no idea how pointers or pointer tables work. I was reading that there are blocks of data that are dedicated to storing pointers to other locations in memory, 2 bytes for data in the same block, or 3 bytes for data in other blocks (where the first byte refers to which block to look in). I really have no idea what to look for, though, or where to even begin looking.

Grabbing the raw script was easy enough though.

For name lengths...well, there's no easy way around that. You'd have to hack the game to use the same ten-letter method as the US versions, not to mention reposition on-screen text and add an extra page to the Pokédex entries.

Really, Pokémon is probably an awful choice for a first translation hacking project. It does have the advantage that you have an English script to compare with, but the amount of hacking you'd need to do makes such a project unfeasible. Though if you're dead set on translating one, FireRed might be a better choice. Since Pokémon can be traded between different language versions in the Gen 3 games, it's likely you won't have to do as much hacking (or any at all, really) to get ten-letter names.

I was afraid of that. To be honest I didn't even consider the problem of the name limits until I was writing that post...
Though if that is the case, it isn't really a huge problem for me. The main goal here is to find out all of the things necessary to edit graphics, find scripts, and edit said scripts. Once I understand the principles behind these things, I'll move onto different stuff.

Ryusui

  • Hero Member
  • *****
  • Posts: 4989
  • It's the greatest day.
    • View Profile
    • Tumblr
Re: New to Hacking -- Script and Graphic Editing?
« Reply #5 on: February 25, 2012, 02:10:37 am »
Well said. Just keep in mind that you probably won't be able to do everything Nintendo did to the game at this point. ;)

Anyways. This topic might give you a better grasp of pointers and script dumping; appropriately enough, it talks about FireRed. ^_^;

Pointers for GB/C games are different from those for GBA games, but the same principles apply. Just find the start of a string and search for the 16-bit address pointer. You can calculate the GB pointer by taking the address mod 0x4000 (that is, the remainder after dividing by 4000 hex) and adding 0x4000 if it's not in the first 0x4000 bytes of the ROM. So if the string starts at 0xFACED, the GB address will be 0x6CED (FACED % 4000 = 2CED; 2CED + 4000 = 6CED). Sometimes, the pointers will include bank bytes indicating which 0x4000-byte chunk of ROM to look in; just divide by 0x4000 to get that (e.g. FACED is in bank 3E).

One last wrinkle. The pointers will be stored in little-endian format, which means you have to reverse the byte order. Since every two digits of a hex number represent one byte, it's easy. 0xFACED (or 0x0FACED) in little-endian format is 0xEDAC0F; 0x6CED is 0xED6C. So if a string started at 0xFACED, the hex value you'd search for would be 0xED6C - if you find it among a bunch of other (usually consecutive!) values pointing to other strings, congratulations, that's the (or a) pointer table.

Also, you can leave out the "0x" when searching for hex; I'm just using the designation to make it clear I'm talking about hex and not dec.
In the event of a firestorm, the salad bar will remain open.

Vehek

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #6 on: February 25, 2012, 03:20:40 am »
You might want to check your table against these topics:
http://hax.iimarck.us/topic/274/
http://hax.iimarck.us/topic/160/

Also, did you know that for the string you have selected in that image, the string actually starts on the byte before (on the 00), not on that byte?
Unfortunately, not all strings in the Gen 1 game are in pointer tables. Many are loaded by ASM scripts. In fact, the pointer tables for locations contain both pointers to straight-up strings and pointers to event scripts.

milkmanjack

  • Jr. Member
  • **
  • Posts: 10
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #7 on: February 25, 2012, 07:39:31 am »
Just to verify I'm understanding the concepts...
(since there seems to be more information on it, I'm using the English version of Pokemon Red for this test)

Locate the location in memory of the text. In this case, we'll use a string located at 0x8A425.
To get the 2 byte pointer used to refer to this string, address mod 0x4000, giving us 0x2425.
Since the address of the memory is 0x8A425, it is located beyond the first bank. Add 0x4000 to get 0x6425.
To get the bank byte that refers to the bank 0x8A425 is stored in, divide by 0x4000, giving us 22.
This means that the 3 byte pointer to this string will be 0x226425.

Finally, convert to little endian.

2 byte pointer: 0x2564
3 byte pointer: 0x256422

Test: found the 3 byte pointer in memory at 0x6254. got the location of another string in memory using this method, and replaced 3 byte pointer with the reference to that string (0x0D6422).

Result: Totally worked.

High five. Now I guess I just need to find out where the table begins and ends? Is there a way to do this? And will all of the pointers in this block be 3 byte pointers?


You might want to check your table against these topics:
http://hax.iimarck.us/topic/274/
http://hax.iimarck.us/topic/160/

Thanks! This should help to get the more obscure characters, and the descriptions for the ending bytes seem to be a bit more accurate. Updated mine accordingly.

Also, did you know that for the string you have selected in that image, the string actually starts on the byte before (on the 00), not on that byte?

I assumed this was the case. That's why all the string start with x in my Cartographer generated script. That's my null character.

February 25, 2012, 01:04:00 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I seem to be having some problems with the Japanese version of Pokemon. I did the same process as with the English version, and the results are pretty different.

The intro dialogue starts at 0x603C. This should mean a pointer to this data should be stored as 3C60[01], according to this method. I managed to find it at 0x5F4A, though instead of the bank byte [01], I found [CD]. To ensure this was in fact a pointer to my dialogue, I found some other dialogue in the same area in memory and changed the pointer to refer to it. This worked. However, when I tried to change it to dialogue stored in further parts of memory, it simply didn't work. And I assume this is because of that third byte. Either the CD is a reference to that bank in particular, or just a reference to "this block."

It seems all of the pointers in the English version are in the exact format as discussed earlier in this thread. I was even able to define a string out in unused memory space and it worked fine.

I'll have to do some more tests.
« Last Edit: February 25, 2012, 01:04:00 pm by milkmanjack »

Vehek

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #8 on: February 25, 2012, 07:00:57 pm »
As far as I know, only the localizations use 24-bit (3-byte) pointers for text. And those 24-bit pointers are part of a script command, which is pointed to by a regular 16-bit (2-byte) pointer.
I told you, some strings are loaded by ASM. That 0xCD you found after the pointer is part of an ASM command, "call".

See here:
Code: [Select]
ROM1:5F49 21 3C 60         ld   hl,603C
ROM1:5F4C CD 67 3C         call 3C67

tashi

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: New to Hacking -- Script and Graphic Editing?
« Reply #9 on: February 25, 2012, 08:05:00 pm »
This worked quite well. On the Japanese version, it showed the font perfectly. When I tried it on the English version just to see if it'd work, it seemed to start drawing the alphabet characters 1 pixel too low, as the top pixel of the font characters were cut off. Not a big deal, but anyway...

Use ctrl+left and ctrl+right to change your offset by increments of 1. This will help you line up the tiles just right. Also, alt+left/right/up/down adjust your tile size, which is necessary sometimes since not all font tiles are 8x8.

What I did was just create 2 savefiles and compare the bytes. I did this initially to find the location of the character names in the files. To start with, I named the character アイウエオ. This revealed that those bytes started at 80 and ended at 84. Then I tested characters in the K category, and saw that it started just after オ, from the bytes 85 to 59.  Then I created a generic table starting from what I knew, A-O and KA-KO, and did S, T, N, H, M, and so on relative to this data. It required a bit of time to get the rest of the characters, since they weren't as intuitively placed.

The easier way to make the table is to use relative searching. For that, Monkey Moore is the way to go. http://www.romhacking.net/utilities/513/

Find the font tiles with Crystal Tile 2 to confirm the hiragana sequence, type it out into monkey's "define character set" and search for a string in game. It will fill out your whole table for you! And give you the offset for that string in the ROM!