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

Author Topic: Text Pointers  (Read 6686 times)

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Text Pointers
« on: February 20, 2014, 05:00:00 pm »
Can you guys help me out here, im kinda confused on how to go about extending the text so I can fit in more words. It says that for example you add to the offset but how would you do that, im looking around and can't seem to find how to do it.

Pennywise

  • Hero Member
  • *****
  • Posts: 2242
  • I'm curious
    • View Profile
    • Yojimbo's Translations
Re: Text Pointers
« Reply #1 on: February 20, 2014, 05:08:02 pm »
You need to look at one of those docs that use Final Fantasy or Zelda on the NES as an example to learn about pointers. The concepts will be the same for the GB, GG etc. I don't see the point in trying to explain something that the docs can do just as good as a job or better than someone on the forum. Hell, the Madhacker's pointer guide is still relevant and useful over a decade later.

Drakon

  • Sr. Member
  • ****
  • Posts: 277
    • View Profile
    • 16 Bit Gamer
Re: Text Pointers
« Reply #2 on: February 20, 2014, 05:24:18 pm »
You need to look at one of those docs that use Final Fantasy or Zelda on the NES as an example to learn about pointers. The concepts will be the same for the GB, GG etc. I don't see the point in trying to explain something that the docs can do just as good as a job or better than someone on the forum. Hell, the Madhacker's pointer guide is still relevant and useful over a decade later.

Not to mention that's a lot of information to cover in post replies.  I've found searching through the documents on this site answered a lot of these questions for me.

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Text Pointers
« Reply #3 on: February 21, 2014, 12:39:19 pm »
Yea I know people have explained it but for example it says here to add 4000 to the offset. How would I do that because it doesn't say how and I really want to see if I can extend the text.

http://datacrystal.romhacking.net/wiki/Pointer#Game_Boy_Pointers

Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3502
    • View Profile
    • Aeon Genesis
Re: Text Pointers
« Reply #4 on: February 21, 2014, 01:07:46 pm »
By "add 4000 to the offset" it means look at the offset number displayed in the hex editor, copy that number into your brain, then add 4000 to it in your head.

Malias

  • Sr. Member
  • ****
  • Posts: 292
    • View Profile
Re: Text Pointers
« Reply #5 on: February 21, 2014, 03:59:58 pm »
Here's a simple formula for calculating game boy pointers: pointer value = physical address %(mod)  $4000 + $4000

One thing to keep in mind is that the game boy stored its data in 16kb banks.  Unless you want to mess with bank switching, any expanded text would have to reside within the same bank.    So, for instance let's say I had a bank at $xx4000 to $xx4fff in rom.  By only adjusting the pointers, I can only address space within that range, nothing outside of it.
The great achievement is to lose one's reason for no reason, and to let my lady know that if I can do this without cause, what should I do if there were cause?
     ~Don Quixote~

Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3502
    • View Profile
    • Aeon Genesis
Re: Text Pointers
« Reply #6 on: February 21, 2014, 05:06:11 pm »
I think Bob needs to understand the conceptual relationship between a file address and pointer value before we start introducing modulus into the details. It's a good thought (and totally accurate) but probably a step or two beyond where this guy's at right now :)

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Text Pointers
« Reply #7 on: February 21, 2014, 05:11:22 pm »
I think I understand now but im still kinda confused.

Example: $1201FA is the offset you wish to point to in a game that uses little endian pointers.
Take the offset $1201FA
Take the last four digits: $01FA
Since $01FA is between 0000-3FFF, you add 4000, so you get $41FA
Because Game Boy is little endian, you take the 41FA, switch the 41 and FA around to get FA41

If you do this how does that allow you to enter more text, im probably sounding like an idiot but I just need some time to wrap my head around how to do this. Below is an image of the rom opened up in a hex editor, the text in the red box doesn't have enough room. So if you add for example if you add FA41 before the end of the text would that direct it to a blank space where I would add the rest of the text or something like that. Is that how it works?



Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3502
    • View Profile
    • Aeon Genesis
Re: Text Pointers
« Reply #8 on: February 21, 2014, 05:26:27 pm »
You're halfway there! You're calculating them correctly, at least for starters.

The idea is that the game needs to know where every string starts. Generally speaking there's going to be an array of these things somewhere, typically at the start of the text block. (This isn't always the case though!) So while knowing the pointer to the start address of a given string isn't important for changing its length, knowing the pointer to the start of the string that immediately follows it IS important to changing the string's length. If you just remove the end-of-string command, the string after will still start at the same place. If you insert data into the first string (and make it longer) you need to move every string that follows it to a new location, and you need to update their pointers accordingly.

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Text Pointers
« Reply #9 on: February 21, 2014, 05:45:23 pm »
Im getting the feeling that if I do something I'll just get an error when trying to play the game. I need to move everything forward when I enter new letters, I tried before adding a new byte but got an error when loading the game. That's probably not how you do it though, could you walk me through it as my head really hurts. I know I should be using my own initiative but I just need some help to implement a new letter onto a place where no more can go and then I should be able to do that for everything else on my own.


Pennywise

  • Hero Member
  • *****
  • Posts: 2242
  • I'm curious
    • View Profile
    • Yojimbo's Translations
Re: Text Pointers
« Reply #10 on: February 21, 2014, 06:42:19 pm »
Bob, this is an example of a block of text as viewed in a hex editor.



And this is an example of the script as viewed in a text file.

Quote
//POINTER #0 @ $18000 - STRING #0 @ $18350

#WRITE(Block1, $18000)
A master attack[LINE]taken![END]
//せんせい 攻撃を 受けた[END]
//POINTER #1 @ $18002 - STRING #1 @ $18361

#WRITE(Block1, $18002)
Enemy escaped.[END]
//てきは にげた[END]

So pointers are usually stored in an array which we call a pointer block and we take these pointers and use them to extract the script from a game. We then use a program to insert the script back into the ROM and update the pointers. This allows us to reassemble a game's script without worrying string length etc.

Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3502
    • View Profile
    • Aeon Genesis
Re: Text Pointers
« Reply #11 on: February 21, 2014, 06:44:15 pm »
This is why we use script extractors and inserters. You can't just insert a new byte into the ROM; that moves everything after it, and suddenly shit starts breaking all over the place. You're limited by the available space, and in gameboy games that happens to be in chunks of 0x4000 bytes apiece. So everything in 28000-2BFFF needs to stay in that range. (At least, for now. There are ways to expand but that's beyond the scope of this message.) If you expand a string at 28A94 to be an extra byte long, all the strings that come after it start at their original addresses + 1, and you have one fewer byte left in the data bank as a whole. But unless you modify the pointers, the game's still looking at the strings in their original addresses.

Let me see if I can illustrate this somehow....
Code: [Select]
0000: 1000 2000 3000 0000 0000 0000 0000 0000
0010:This's a string<END>
0020:Another string!<END>
0030:String No.Three<END>

The values at address 0000 are 16-bit (2-byte) pointers represented as hex data. The first pointer is pointing at address 0010, the second pointer is pointing at address 0020, and the third is pointing at 0030. The values at addresses 10, 20, and 30 are strings. If we assume that everything in each of these strings takes up a single byte (including the <END> marker) then each of these is 16 bytes long.

Note that the string at 0010 is lacking a period. If we add one in, then things start to look like this...

Code: [Select]
0000: 1000 2000 3000 0000 0000 0000 0000 0000
0010:This's a string.<END>
0021:Another string!<END>
0031:String No.Three<END>

The first pointer is pointing at address 0010, the second pointer is still pointing at address 0020, and the third is still pointing at 0030. However, since we added a period to the end of the first string, each of the strings after it have been offset by one byte - the second string now starts at 0021, and the third at 0031. Address 0020 is now occupied by the first string's <END> byte, while address 0030 is now occupied by the second string's <END> byte. If the game tried to display these strings, they'd start loading at address 0020 or 0030, they'd get the <END> byte, and they'd just stop loading outright.

Now, obviously, remapping all of these things by hand is an impractically huge chore. What if you mistype? You'll have to go through and change everything by hand AGAIN. This is where script inserters come into play. In the case of Atlas (which was designed to my specification and I use almost exclusively), I insert directives in the script saying "This string is pointed to by pointer 0/1/2/etc" and when the inserter puts the text into the game the inserter knows which pointer to remap and takes care of it for me. This allows me to have strings exactly as long as they need to be, and to maximize the frequently-limited available space in a given data bank. That said, while script extractors and inserters are a critical part of the project workflow, I don't expect you to understand exactly how they work just yet - I only want you to understand why they're useful.

Does that help elucidate things any?

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Text Pointers
« Reply #12 on: February 22, 2014, 10:26:58 am »
Umm I thought you did something when opened up im a hex editor and not a script extractor,

"So pointers are usually stored in an array which we call a pointer block and we take these pointers and use them to extract the script from a game. We then use a program to insert the script back into the ROM and update the pointers. This allows us to reassemble a game's script without worrying string length etc."

I understand a bit better now, I want to test this out but could you guys link me the programs/script extractors that you used as that would help alot. Also how would you modify the pointers, do you do that with the script extractor or something else.

I noticed this program and I guess I could use that to get the pointers, thanks alot for your help as I'll fully understand all of this eventually.
http://www.romhacking.net/utilities/978/

justin3009

  • Hero Member
  • *****
  • Posts: 1611
  • Welp
    • View Profile
Re: Text Pointers
« Reply #13 on: February 22, 2014, 11:49:05 am »
Cartographer and Atlas seem to be the big key script extractor and inserters that I've seen.

If I remember right (Somehow I get these two mixed up)

Cartographer is the script dumper
Atlas is the script inserter
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'

Gideon Zhi

  • IRC Staff
  • Hero Member
  • *****
  • Posts: 3502
    • View Profile
    • Aeon Genesis
Re: Text Pointers
« Reply #14 on: February 22, 2014, 12:48:25 pm »
Justin's correct about the dumper and inserter (though I usually use a customized version of romjuice for dumping.) And yes, you CAN use a hex editor to remap pointers. You probably even should, as a step in your learning process. But I wouldn't go that route for remapping hundreds of the things, and if you're working on an RPG, chances are you're going to have to remap hundreds of the things.

Scio

  • Full Member
  • ***
  • Posts: 155
    • View Profile
Re: Text Pointers
« Reply #15 on: February 22, 2014, 04:01:52 pm »
The way I learned pointers was like this. I'll give an example using Magic Knight Rayearth:

* is a pointer.

*                                                                          *                                                                             *
Hikaru looked at the mirror, and called Umi.<FF>Hikaru: Are you seeing the same thing I am?<FF> Umi: What should I be seeing here?

You'll see this onscreen:
Hikaru looked at the mirror, and called Umi.
Hikaru: Are you seeing the same thing I am?
Umi: What should I be seeing here?

The pointer is where the game will look at to start the phrase. If you change the length of the phrase without changing the pointer as well, this happens:

*                                                                          *                                                                             *
Hikaru looked at the mirror, and then called her friend Umi.<FF>Hikaru: Are you seeing the same thing I am seeing?<FF> Umi: What should I be seeing here?

By just extending the length, and not the pointers, the game will keep looking at the same place for the start of the phrase. The third phrase won't even be called at all. You'll see this on the screen:
Hikaru looked at the mirror, and then called her friend Umi.
friend Umi.
hing I am seeing?

See? Very different.

About adding a byte, you don't really add a byte in the middle of the ROM to allocate more text. That's a big no-no. At least for now, you should use the space you have. You _can_ expand a ROM to fit more text, but it's not so easy like that.

Bob Liu

  • Sr. Member
  • ****
  • Posts: 253
    • View Profile
Re: Text Pointers
« Reply #16 on: February 22, 2014, 04:27:58 pm »
Ok I'll try this out for the Cfiro part, 0x000094C0 is the start of the text and 0x000094C4 is the end. Using that pointer calculator it says you enter 6 digits but there are more than that for the hex locations, do I just add the last six or something like that.

I just noticed that Cartographer and Atlas uses command prompt, ugh Im no good at those but you guys should be able to help me out on that. Also what is the process of pointers

1. Get the offsets for start and finish of the block of text
2. Get the pointers for both
3. ?
4. ?
5. ?


Drakon

  • Sr. Member
  • ****
  • Posts: 277
    • View Profile
    • 16 Bit Gamer
Re: Text Pointers
« Reply #17 on: February 22, 2014, 08:14:26 pm »
Some games are weird.  The main menu for fire 'n ice had the text stored in ascii that represents text so no table file needed to be made.  It was done pointer style with 3 hex values in between menu options to signify where the next line begins and the last one ends.  For some reason expanding the middle option beyond 4 text characters and moving over the next line code caused the game to crash.  Instead of figuring it out I just kept the text limited to 4 characters.  I guess for games that aren't very text heavy there isn't as much flexibility with the software.

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
Re: Text Pointers
« Reply #18 on: February 22, 2014, 08:28:59 pm »
You need a tool that can understand the pointer fully.

There is a lot of things that can change the stored value for a pointer:
  • The base value. All pointers are relative to something. It can be the start of the cpu address space, the start of the data region containing the script or even the value of another pointer.
  • The data type. Pointers aren't always stored with the same number of bits. The native word size is the most popular size, but it is not a requirement.
  • The unit for the pointer value. Games like to bitshift values for no real reason.
  • Address map quirks. Things like memory areas being mirrored at adjacent addresses, pointer truncation, bank switching and what not make for an exciting time.

As for the process, the original developers wrote a tool that simultaneously places the pointed to data and notes where the placed data is located in a pointer table. To work with the result of that you have two options:
  • Read all data and repeat the original placement process
  • Move individual pieces of data and update only the corresponding pointers

In summation, it isn't just about pointing to the new location of data, it is also ensuring that the new location isn't used by something else. Variable sized data makes the later problematic to change afterwards, since there is usually little to no room left between chunks of data.

And to complicate things further, there can be several layers of placed data and pointers. The game can have major chunks (code, music, level maps, math tables, dialog text) and each can have sub sections (individual functions, music tracks, individual levels, different math functions, different dialog lines). The real fun begins when you have pointers between different major chunks (the code needs to know where the level data is and so on).

Also note that none of this is dialog specific. Data is data and pointers work for all data.

Scio

  • Full Member
  • ***
  • Posts: 155
    • View Profile
Re: Text Pointers
« Reply #19 on: February 22, 2014, 08:29:43 pm »
Some games are weird.  The main menu for fire 'n ice had the text stored in ascii that represents text so no table file needed to be made.  It was done pointer style with 3 hex values in between menu options to signify where the next line begins and the last one ends.  For some reason expanding the middle option beyond 4 text characters and moving over the next line code caused the game to crash.  Instead of figuring it out I just kept the text limited to 4 characters.  I guess for games that aren't very text heavy there isn't as much flexibility with the software.
Could be hardcoded pointers, and the three bytes are actually control codes (for text positioning/scrolling text).