+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  How to exceed the limit of 2 bytes pointer?
Pages: [1]
Author Topic: How to exceed the limit of 2 bytes pointer?  (Read 1 times)
Rappa
Guest
« on: April 11, 2010, 09:05:33 pm »

Hi everyone

I've encountered severals games that uses 2 bytes pointer. This means the pointers can only point to the range from $00 to $FFFF. It's OK with almost Japanese games, but if you translate the game into English or other language, the text block will be much longer and sometimes exceeds the above range. In this case, the pointer can not point to the remaining of text. So I would like to ask how to remedy this without reducing the translation?

For example, the original text block locates at $1E8900 and ends at $1E89FA, pointer value is 0089.
The translation of this block also starts at  $1E8900 but ends at $1F0021 so
the remaining part from $1EFFF to $1F0021 can't be displayed.

And what if I expand the Rom and want to move the above block to $31A200?
I wonder is there anywhere in the Rom that store the index address for all pointers?

Thank you in advance.
Lenophis
Guest
« Reply #1 on: April 11, 2010, 09:12:13 pm »

There's various ways to do this. Either after so many dialogue entries, increase the bank count and reset the pointer (or subtract #$10000) or convert them to 24-bit pointers. The 24-bit pointers will eat more space, but will give you complete control over how and where you stick your dialogue. The 16-bit pointers (your example) will need extra code if dialogue is in more than one bank.

Not sure if that helped, but if you need more clarification I can try and do better.
Rappa
Guest
« Reply #2 on: April 11, 2010, 09:26:46 pm »

Thank your very much, Lenophis. 24 bit pointer is what I'm looking for. The 24 bit ptr can point to everywhere in the Rom, but how to convert the 16 bit one to 24 bit?

I'm just a beginner in Asm.
Lenophis
Guest
« Reply #3 on: April 11, 2010, 09:59:53 pm »

You'd have to find the pointer loading routine, and change it to load 3 bytes instead of 2, in a nutshell.
Gideon Zhi
Guest
« Reply #4 on: April 11, 2010, 11:34:06 pm »

And once you've done that, you have to expand the pointer table to load 24-bit values, which is going to overwrite some of your original text unless you move it somewhere else, which also is going to require assembly.
Ryusui
Guest
« Reply #5 on: April 13, 2010, 04:02:14 pm »

Breath of Fire 2 (and my WIP BoF1 hack) use a hybrid method.

The 16-bit pointers are left where they are, and a separate table stored elsewhere stores the bank pointers. It still requires ASM, but it mostly solves the problem of having to move things around: provided you already have enough space to store your script, you only need an amount of space equal to the number of strings in the script.
KingMike
Guest
« Reply #6 on: April 13, 2010, 11:10:32 pm »

I don't know if you changed it in yours, but I recall BoF2 would look at the string number when checking the pointer table. It would by default set the bank value to the ROM bank of the first dialouge bank. If the string number exceeded the (hard-coded) amounts (say like knew string 100 was the first string in bank 2 and string 200 was the first string in bank 3. I forget the actual numbers, but it was that idea) then it would increment the ROM bank in the pointer.
tomaitheous
Guest
« Reply #7 on: April 13, 2010, 11:49:01 pm »

Quote from: Ryusui on April 13, 2010, 04:02:14 pm
Breath of Fire 2 (and my WIP BoF1 hack) use a hybrid method.

The 16-bit pointers are left where they are, and a separate table stored elsewhere stores the bank pointers. It still requires ASM, but it mostly solves the problem of having to move things around: provided you already have enough space to store your script, you only need an amount of space equal to the number of strings in the script.

 I did something a little bit similar. For Bubble Gum Crash, I made all string lengths fixed to a certain size of the original script. If the replacement English string was longer than the allowed limit, a special control code was inserted and the rest of the string was stored in the expanded part of the rom. I would freeze the current pointer from incrementing, and increment my own internal counter for the "far" data. Once done, I'd let the original counter increment end terminate the string. Of course, this required hook my asm routines into the original, but I didn't have to mess with replacing or changing the original pointer system.

 Oh, and my "far" data part of the string required a 24bit pointer.
Nightcrawler
Guest
« Reply #8 on: April 14, 2010, 08:14:48 am »

Yes, I've done that before. it's especially useful for games using scripting blocks that contain text intermixed with various scripting commands that may contain relative jumps and other things making it quite difficult to insert different size text without figuring all of the scripting commands out. Instead, from the game's perspective all the original pointers and strings are the exact same as they were in the original.

The drawback however is difficulty of insertion. You probably need a custom inserter to handle inserting to the original location and then adding the far pointer to continue into the new space. I don't think any available utilities do that.

And be mindful with this case. I did this one time and found a few strings that were only 2 or 3 bytes long. Oops.. The new far control and 24-bit pointer wouldn't fit and it overwrote other things. It took me awhile to figure out what happened.
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC