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

Author Topic: Remapping pointers  (Read 5034 times)

stirwhip

  • Jr. Member
  • **
  • Posts: 6
    • View Profile
Remapping pointers
« on: March 15, 2011, 06:26:58 am »
Hello there. Quick warning : I just started delving into romhacking very recently and my English is awful. So if you're having a bad day, don't read this.  :P

I haven't found any specific tutorial on the subject though it was mentioned briefly in a couple of the guides I've read in the past few days. I'm guessing this is pretty common and simple stuff for most people here since this seems like the kind of thing that's necessary to translate a game (or do any sort of hacking) properly, but I'm gonna be as descriptive as possible and even use a concrete example in case some other newbie finds this thread and needs to be walked through this process.

It's probably obvious from the thread title, but what I'm trying to do is to simply redirect a pointer so that it points to a different location in the code. I'm gonna use Chrono Trigger as an example.

In one of the first sections of the game, the Millenial Fair, the first NPC you encounter greets you by saying "Welcome to the Millenial Fair! [Line Break] Have fun!"

This bit of text starts at $3CC3D7 in the code. The pointer that leads to this string is located at $3CBA62 in bytes D7 C3. I'd like for this pointer to be directed to $3DEEB0 (blank space located in a different bank) so that whatever the NPC says is not limited to the size of the original text at $3CC3D7.

If there's a way to do this, a utility to facilitate the process, or if it requires assembly hacking, I'd like to know about it. Also, if there's more effective way of remapping pointers than just redirecting them to empty space and expanding the rom to get more of that empty space, please share your knowledge!

Thanks in advance

Lewnatic

  • Jr. Member
  • **
  • Posts: 11
    • View Profile
Re: Remapping pointers
« Reply #1 on: March 15, 2011, 08:43:58 am »
The pointer is just the strings position in memory, so you could easily use something like Atlas to insert the text in a different place. Unless it's just the one string then I suppose you would get away with doing it manually, though I personally can never be bothered.

Ryusui

  • Hero Member
  • *****
  • Posts: 4989
  • It's the greatest day.
    • View Profile
    • Tumblr
Re: Remapping pointers
« Reply #2 on: March 15, 2011, 09:57:30 am »
Repointing to a different bank can be tricky if the game doesn't already include a bank byte in its pointers. If it's expecting to find all of its text in the same bank, the simple answer to your question is "you're screwed."

The not-so-simple answer is that it'll take some ASM hacking. If your grand plan is to move all the text in one bank to a different bank, then it's an easy hack. Just find the text loading routine and change the bank byte the game uses to calculate the pointer offset - just one byte.

Mind, it's entirely possible that all this is redundant and you're simply approaching the problem from the wrong angle. If there is free space after the text in the current bank, you can simply dump the script using a tool like romjuice or Cartographer, then reinsert with Atlas: if you format your script properly, you'll be able to take advantage of all that extra space without having to move the script to another bank. For this purpose, I recommend Cartographer, which can auto-insert the necessary formatting: it takes a little more effort than romjuice to get up and running, but it's worth it. You'll still need to insert the definitions at the start of the script file that tell it what table to use and where in the ROM to start inserting it, but it's still a lot easier than manually inserting every single pointer directive.
In the event of a firestorm, the salad bar will remain open.

stirwhip

  • Jr. Member
  • **
  • Posts: 6
    • View Profile
Re: Remapping pointers
« Reply #3 on: March 16, 2011, 05:39:32 am »
Thanks for the answer. Well first let me say I really don't have a "grand plan" here, haha. After learning about pointers, and how to modify the text in a ROM, and then putting this acquired knowledge into practice by doing half-assed translations of a few games that are low on text, I decided to try translating a RPG and see how far I could get before getting stuck.

So you're telling me that if there's not enough free space in the current bank (which seems to be the case here, the largest string of 00's I found was like 8 bytes long, I think. You can check the U rom at bank $3C if you have the time, to see if I'm wrong), and that the pointers don't reference the bank byte, the only solution is ASM hacking ? Well, that sucks. Could you give me a brief explanation of what would need to be done in case I decide to try my hand at ASM hacking in the future ? I'm guessing you'd have to add a byte to each pointer but then how would you properly reinsert the pointer table, considering the lack of space ?

Actually, is this what I'm looking for ? : http://www.romhacking.net/docs/534/

Meanwhile, I'll pick up Cartographer and Atlas to see how that helps. I had kinda left Cartographer on the shelf after a bad first experience, but it shouldn't be that hard to use if I spend more than half an hour messing around with it, heh. If you have any advice or if you feel like I'm not grasping something, please don't hesitate to correct me or lead me in the right direction. I am still very much learning the ropes here and everytime I learn something new, I'm like "Where do I go from here ?", so any orientation would be appreciated

Thanks again

Ryusui

  • Hero Member
  • *****
  • Posts: 4989
  • It's the greatest day.
    • View Profile
    • Tumblr
Re: Remapping pointers
« Reply #4 on: March 16, 2011, 03:39:56 pm »
Yeah, the doc is describing an ASM hack, and several ways to go about it.
In the event of a firestorm, the salad bar will remain open.

CaseCrash

  • Full Member
  • ***
  • Posts: 165
    • View Profile
Re: Remapping pointers
« Reply #5 on: March 16, 2011, 06:48:06 pm »
and my English is awful

Your English is better than most English speakers on the 'net :)

stirwhip

  • Jr. Member
  • **
  • Posts: 6
    • View Profile
Re: Remapping pointers
« Reply #6 on: March 16, 2011, 06:55:20 pm »
I know nothing about assembly, and learning it seems like a huge time sink and a big leap right now. I will probably end up getting into it at some point in time, but for the moment, I would just like to know if this really is the only way I can considerably increase the amount of text allocated for each pointer. Maybe I'm underestimating how much free space there is, or how to take advantage of the multiple short strings of 00's scattered in that bank.

abw

  • Hero Member
  • *****
  • Posts: 556
    • View Profile
Re: Remapping pointers
« Reply #7 on: March 17, 2011, 12:06:17 am »
If you're not feeling up to an ASM hack yet, another approach is to optimize the game's existing compression mechanism to make better use of the space available to you. I don't know anything specific about the internals of Chrono Trigger, but its text engine is probably optimized based on frequency values for the text it actually uses. If you're changing those frequency values (which is extremely likely to be the case if you're translating the game to a different language), re-optimization might allow you to fit your new script in the existing space without making coding changes.

Simple example: let's pretend Chrono Trigger uses a table like this:

// individual letters
00=a
...
19=z
1A=
// 1A is a single space, just to be clear

// DTE
80=ha
81=ve
82= f
83=un

The game could then represent the text "have fun" in 4 bytes: 80 81 82 83. If you wanted to change "have fun" to "home run", you would have to use 7 bytes: 07 0E 0C 04 1A 11 83, because you can only make use of 1 entry in the game's DTE table; the other 3 entries are completely useless for your text. But if you found the game's DTE table and changed it to something like this:

80=ho
81=me
82= r
83=un

then you too could use 4 bytes instead of 7 bytes. A utility like http://www.romhacking.net/utils/405/ can analyze your entire script (instead of my little 8 character example) and tell you what kind of gains better compression could give you.

stirwhip

  • Jr. Member
  • **
  • Posts: 6
    • View Profile
Re: Remapping pointers
« Reply #8 on: March 18, 2011, 08:01:49 am »
Heh, I thought I had gathered a pretty good library of utilities used for text hacking,  but I somehow completely skipped over this one. Thanks for the explanation.

Tell me if I'm missing something though. If I want to change what each hex value displays in the ROM according to the results and the table provided by ScriptCrunch,  wouldn`t I need to edit the tiles, which would involve ASM hacking since they're mostly compressed with Multi Tile Encoding ?

Auryn

  • Hero Member
  • *****
  • Posts: 650
    • View Profile
Re: Remapping pointers
« Reply #9 on: March 18, 2011, 10:21:23 am »
No, u don't need to change the tiles because DTE/MTE will use the same tiles as the rest of the font.
U just need to find where they are defined in the rom.

abw

  • Hero Member
  • *****
  • Posts: 556
    • View Profile
Re: Remapping pointers
« Reply #10 on: March 18, 2011, 06:33:25 pm »
Every game is potentially different, but I would expect a text-heavy game like Chrono Trigger to have a fairly robust text engine. If you find and tweak the game's DTE (or MTE or whatever) table, probably the game itself will quite happily take care of all the heavy lifting for you. With luck, finding the game's table will be the hardest part of the process :p

When looking for the game's table, it's often fastest to just try a couple of searches and hope for the best. If CT uses something longer than DTE (like MTE), try searching the ROM for some of the longer strings and looking for a section with a bunch of other strings used for compression. That ought to be your table. Failing that, I'd probably try (in order of increasing desperation):
- searching for the DTE parts in table order (e.g. "ha" followed by "ve" followed by " f");
- searching for the DTE parts in sorted order (e.g. "ha" followed by "un" followed by "ve");
- asking Google;
- opening up a debugger and tracing through code (which is the guaranteed way to find what you're looking for, but can take considerable amounts of time, depending on the complexity of the code and your own skill level).

stirwhip

  • Jr. Member
  • **
  • Posts: 6
    • View Profile
Re: Remapping pointers
« Reply #11 on: March 19, 2011, 04:42:41 pm »
Awesome. After reading Auryn's post, I thought this would  require at least SOME trial and error, but for Chrono Trigger, it was indeed as simple as doing a text search for the longest substring I could think of in the MTE table (in this case , 'of the'), and the first result I got was obviously what I was looking for. I'll see how much I can accomplish with this technique,  but from what I've tested so far, it looks really, really useful. Thanks a lot for the help guys.

I'll keep an eye on the forums, so if any of the more experienced people here have good advice concerning what else I should experiment with before I decide to tackle the task of learning ASM hacking, I'll be glad to hear it  :)