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

Author Topic: Modifying text in ROMS question (more length)?  (Read 2469 times)

rafaelinio

  • Jr. Member
  • **
  • Posts: 20
    • View Profile
Modifying text in ROMS question (more length)?
« on: April 27, 2016, 06:17:21 pm »
What will I need to learn to be able to add more text to games . for example I have the text "123". Am I limited to only 3 characters, or can I add more (" 1234")
Thanks

mz

  • Sr. Member
  • ****
  • Posts: 447
  • Whore
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #1 on: April 27, 2016, 06:51:31 pm »
You need to learn about pointers, see if there's something in the documents section.

Basically, there are numbers within the files that indicate the position of each line of text within the file.

Imagine you have a game with 2 lines of text. One at position 0 and another at position 10. Their pointers would say "0" and "10", but if you make line 1 longer with 2 new letters, you have to move line 2 to position 12, so you update the second pointer from "10" to "12".
There has to be a better life.

FAST6191

  • Hero Member
  • *****
  • Posts: 3014
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #2 on: April 27, 2016, 07:06:15 pm »
You can modify lengths for text in games, I will assume an actual text engine here and not a graphics based hack if the text just happens to be in graphics.

Typically three forms are seen in games, though the third is not common at all.

1) Pointers. These are values the game uses to determine either location or length, usually location. In games with file systems (DS, disc based games...) these are often file level, other games will be ROM level and most of the time it is related to the location the data would be found in memory when things are running. Normally you will end up with a bunch of pointers somewhere but we have seen things have a length value for how long the upcoming section is and then the section and then another length value. Some find them hard to get sorted in their head but they really are just a means by which the console determines the location of the text, I usually like to say think contents page in a book -- increase chapter 1 by 10 pages and everything following is out by 10 pages, remove 5 from 2, add 3 to chapter 4.....
2) Fixed maximum length. Seen mainly in menus and such like. Here the number of characters is fixed to a maximum of whatever and you have up to that to make it. It can be very hard to change this so most make do here, though there are small workarounds like putting two characters into a single tile in the font.
3) Normal parsed text file style. Your text editor will put a value (in windows this is typically the hex value 0d0a, Linux will tend to use just 0a which is why some Linux originating documents do not have proper new lines in basic notepad) to signal a new line. There may be a value like this to end a section but it will probably still be a pointer that really governs it -- your little sub 100MHz embedded CPU with barely any memory and a ROM that is supposed to be fixed is not going to benefit from parsing a text file so most devs do not.

There is an awful lot more to each of these and you might still face limits (just because your pointers say you can store gigabytes don't expect to get it all in memory or on screen or something) but learn how pointers work for the consoles you want to hack and you will be able to approach most games and do something.

rafaelinio

  • Jr. Member
  • **
  • Posts: 20
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #3 on: April 28, 2016, 04:20:51 am »
Alright so I guess I have to learn about pointers. Also, thanks for pointing out the three forms seen in games :D I think I know where to start now, thanks guys!

VicVergil

  • Hero Member
  • *****
  • Posts: 726
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #4 on: April 28, 2016, 04:24:26 am »
Check the wiki, too.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 92
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #5 on: April 28, 2016, 09:21:39 pm »

1) Pointers. These are values the game uses to determine either location or length, usually location. In games with file systems (DS, disc based games...) these are often file level, other games will be ROM level and most of the time it is related to the location the data would be found in memory when things are running. Normally you will end up with a bunch of pointers somewhere but we have seen things have a length value for how long the upcoming section is and then the section and then another length value. Some find them hard to get sorted in their head but they really are just a means by which the console determines the location of the text, I usually like to say think contents page in a book -- increase chapter 1 by 10 pages and everything following is out by 10 pages, remove 5 from 2, add 3 to chapter 4.....

I'm trying to do this now as well, so I'll add a couple things I learned in my struggle to find pointer tables.

For disc-based games like on PSX, the text might not be gathered in one place in a file, and what appears to be a single file when you extract it could be many files merged together. This means file-level might not be what it first appears to be. So in The Legend of Dragoon, dialogue on the first disc is in a file called DRGN21.bin. But this file is actually composed of a bunch of smaller files merged together, and these files are in turn composed of basic files like images and text files! What this means is that the text is scattered in a bunch of different files within the .bin file, and only the smallest level of file contains the text pointer table, while the .bin file and subfiles have tables of the location and size of all the smaller files nested inside them.

The upshot is, if your doing a disc-based game, you may actually have a lot of pointer tables!

On top of this, if you have to change the size of a file containing text when you expand it, you'll also be needing to adjust their size/location in the file index tables (or whatever the technical name is), and on up the hierarchy as necessary. The advice given to me is to use a file splitter/merger on files like this to break them into the smallest component files necessary, and change the script once you're working with the smallest file type possible. Then you put them all back together at the end with something that will update the index tables as needed. So that's another thing you may need to learn to do, depending on the game.

Finally, if you find something that looks like a pointer table near some text, but it doesn't seem to quite point to the right place, the game may be performing operations on them first, potentially beyond just adding an offset.
ROM wasn't hacked in a day.

aweigh

  • Jr. Member
  • **
  • Posts: 31
    • View Profile
Re: Modifying text in ROMS question (more length)?
« Reply #6 on: May 02, 2016, 12:38:22 pm »

May 02, 2016, 01:03:11 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Quote
STANDARD HEADER
By far the simplest and quickest pointers to work with.  These pointers appear somewhat frequently. Calculating them is simple (Final Fantasy 1 uses Standard Header pointers, and the procedure for calculating them is stepped through above).

 In brief, you:
1) Determine the position of the text. (SAMPLE: 12345)
2) Subtract 10 for the header. (SAMPLE: 12335)
3) Drop the Ten-thousands digit, if there is one. (SAMPLE: 2335)
4) Break the number into two pairs.  (SAMPLE: 23 35)
5) Swap the number pairs. (SAMPLE: 35 23)
Voila, you have your value.

 SetOff X000
By far the most common type of pointers on the NES, SetOff X000 pointers are pointers whose position within the ROM is modified for whatever reason.  This amount of modification is indicated by the X000 value.  Why they're modified isn't important, only how.  To calculate them, you follow the same procedure as STANDARD HEADER pointers with one additional step.  (IMPORTANT NOTE: You can only calculate X by locating the pointer table, which is described below)  If you know X000, they are calculated by:
1) Determine the position of the text.  (SAMPLE: 12345)
2) Subtract 10 for the header. (SAMPLE: 12335)
3) Add X000 to your value. (SAMPLE: if you found X000 to be 3000,
then 12335 + 3000 = 15335)
4) Drop the Ten-thousands digit, if there is one.  (SAMPLE: 5335)
5) Break the number into two pairs. (SAMPLE: 53 35)
6) Swap the number pairs. (SAMPLE: 53 35)
Voila, you have your pointer value.
If you do not know X000, you need to follow the steps outlined below in LOCATING THE
POINTER TABLES.  When you get there, read through that section below, and then come back
up here and re-read this one to gain the best understanding of SetOff X000 pointers.

 Some notes about SetOff X000:
1) Standard Header pointers are just SetOff 0000 pointers, but usually it's just easier to think of them as their own type.
2) For whatever reason, X seems to be 8 more frequently than most other values.
3) Although it is theoretically possible to have SetOff 1500 pointers, or some other value which is not a multiple of 1000, I have never encountered them.

 SEQUENTIAL TEXT
Technically, this is not even a pointer system, but I include it here because being able to recognize this when it's used can save you hours of headache and searching.  Sequential text systems don't use pointers, making their widths adjustable without any problem.  Customizing a YES/NO prompt would actually be as simple as changing:
Yes#No#texttexttexttext...
into:
Sure.#No way!#texttextt...
This way of doing things isn’t used very often, but some games do use it.
One important note: With this system, the game knows it's done when it reads enough strings. Therefore, you cannot simply remove a string you don't like without messing things up. If one string is slightly longer, the string to the right of it will have to be slightly shorter.
 FIXED-LENGTH SLOTS
Rarely used for text, this system is frequently used for item and spell listings.  The game knows that the text string is a certain amount of characters long, and reads them accordingly. You don't really need to do anything with these, and you can’t re-map them.

 SEQUENTIAL POINTERS
If you see these, run. I've only encountered them once, in Wily & Light no RockBoard, a Mega Man monopoly spinoff, and I'm still trying to figure out how on Earth they know everything they're supposed to.  Anyway, I'm including them here for completeness, but you're free to skip ahead.

 Sequential pointers are stored in their simplest form, two digits (as opposed to the 4 used in SetOff X000 and Standard Header pointers).  They're calculated as follows:
1) Determine the position of the text.  (SAMPLE: 12345)
2) Subtract 10 for the header. (SAMPLE: 12335)
3) Drop all digits except for your ones and tens places.  (SAMPLE: 35)
Voila, you have your pointer value.
Seems easy, doesn't it?  Well, it's not, because as you try to remap these pointers, all kinds of weird things can happen without the hundreds and thousands place.  Space constraints are worse here than anywhere else.  Trust me, you really don't want to deal with these unless you absolutely have to.

 Well, there you have your standard pointer systems.  Are there others?  Probably.  I've only encountered one other system on the NES, and I'm STILL trying to figure that one out...

 So now do we finally get to learn about how to find the pointer table?
Yes, you deserve a reward for having read this far! Let’s pull all of this together.

 FINDING POINTER TABLES and your pointer system (the easy way):
(if you need an example, refer back up to the Final Fantasy one above)
Does the ROM use a SEQUENTIAL TEXT or FIXED WIDTH systems?
1) To determine if you've got a FIXED WIDTH system, just look at your text strings.  If you've got a bunch of strings that are exactly the same length (especially if they use 00s, FFs, or some kind of <NULL> code at the end to guarantee that), odds are you've got a fixed width system at work.
2) To test and make sure, locate a string you can easily get the game to display.  Overwrite it with something longer which runs into the next string in your hex editor.  Save, then load the ROM and bring up that item.  If it cuts off after a certain length, you've got a fixed width system.
3) To test if you've got SEQUENTIAL TEXT, find some dialog in the game and locate in in your hex editor.  Now, go into the string BEFORE it and add an <END> code right in the middle of it.
Save, and load up your ROM again.  Bring up the dialog you used before.  If it's different, then you've got a SEQUENTIAL TEXT system.

 If your ROM does not use the SEQUENTIAL TEXT or FIXED WIDTH systems:
1) Open the ROM in your hex editor.
2) Locate a string of dialog which you can bring up in the game easily or quickly. (Don't use menu options/other types of text, as these tend to be stored differently than main text)
3) Write down your offset.
4) Subtract 10 for the header.
5) Note down the last two digits of your value.  (If your adjusted position was 12345, the 45)
6) In your hex editor, Hex Search UP for this value. (the 45)
7) Usually, you'll find one close to where you started your search.  Regardless, write down the two digit number to the right of the one you just found (Let's say, searching for 45, your search returned the 45 in the following line:  AB 45 FE. Write down the FE)
8) Check the second digit in the number you just wrote down (In FE it'd be the E).  Compare that value with the hundreds place in your adjusted position (In 12345 it'd be the 3).  If they match, you may have found the
beginning of your pointer table.  In they don't, continue searching UP.
9) Since the values didn't match, we continue searching upwards until they do.  (Finally, we find it a line that includes 82 45 83)
10) Now that we've found a potential pointer, we need to test it.  Change the pointer so that the text will display differently (my favorite is to just set the ones place ahead by 1, so that the first letter doesn't display.  When that happens, you know it worked.)  Then you'll need to remap the pointer to another string of text, and see if it changed like you expected it to (What we did in the Final Fantasy example above.)
11) If the text changed as you expected it to, CONGRATULATIONS, YOU'VE JUST
LOCATED THE POINTER TABLE.
12) To figure out which pointer system you're dealing with, you only need to look at the pointer you've found and compare it to the position of the text you're using.  Take the first digit of the right number in your pointer (45 83 -> Take the 8) and compare this to the thousands digit of your position (12345 -> The 2).  If they're the same, you're dealing with STANDARD HEADER pointers, otherwise you've got SetOff X000 pointers (where X is the number you just examined from the pointer -8- less the number you just took from the position -2-, or 6 => Therefore, you're dealing with SetOff 6000 pointers)

 That's it.  This system will work for most of the games that many of you will want to hack out there.  Now that you know the pointer system, you can calculate the pointer for the first item in your text block.  Find that, and you've found the beginning of your pointer table.


 FINDING THE POINTER TABLES (a harder way):
If the above system didn't work for you, make sure you don't have any control codes (described below).  If you're sure that there aren't any in there, try this system:
1) Test for SEQUENTIAL TEXT and FIXED WIDTH systems, as outlined above.
2) Locate a string you can bring up easily in the game.
3) Using its position, calculate the pointer using the STANDARD HEADER system.
4) Search the hex for this value. Change every occurrence slightly (remember, change the second digit of the first number pair for minor changes).
5) Save, and load the ROM.  If the change you wanted occurred, then you know it's a STANDARD HEADER system.  Change matches one by one until you find the right one.
6) If that doesn't work, then calculate the pointer using the SetOff 8000 system.  Search for this value in the ROM, changing every occurrence slightly.
7) Save, and load the ROM.  If the changes you wanted occurred, then you know it's a SetOff 8000 system.  Change matches one by one until you find the right one.

 If these don't work, then I'm afraid you'll have to resort to:

 BRUTE FORCE POINTER LOCATION (the tedious way):
The system of last resort.  This will work 99.9% of the time if you know that you're not dealing with a FIXED WIDTH or SEQUENTIAL TEXT system, and that there are no control codes throwing you off (and in that 0.1% of the time, you don't want to deal with it anyway).
1) Locate a dialog string you can bring up easily in the game.
2) Locate that string in the hex editor.
3) Calculate the pointer for it using the SEQUENTIAL POINTER system (no, don't worry. Using this method does not automatically mean you've got sequential pointers).
4) From the beginning of the ROM, Hex Search through for that value.  One by one, change that value slightly.  Saving and testing to see each time if you've found the right one.
5) EVENTUALLY you'll come across it (hey, if you're lucky, the Hex Search will only turn up 500 or so occurrences).  FROM there you can figure out the pointer system as described under the easy way above.

 ...or you could go on datacrystal.romhacking.net and see if somebody else has found it and written it up.

 So, is that it?  Do I now know everything I need to about pointers?
Almost. There are only two more minor things for me to address.

 Empty Space in the ROM:
Fitting all of the text you need to into the ROM can be quite troublesome.  Fortunately, there is a solution...sometimes.  On some occasions there will be blank space within the ROM which you can use to fit some extra text in.  You can recognize this space because it's usually just a large block of 00s or FFs.  Look at the end of your ROM and you'll probably see a good example of it.
Now, because NES pointers are limited to four digits, so too are your pointers.  Therefore, your range will be limited to whatever bank the existing text is in.

 Control codes:
These are codes that programmers put in with the text which tell the NES how to display it.  Much like the font tables themselves, these vary from game to game.  End of Line, End of Page, and Pause are two common examples.
I bring these up because if the text string you're using has one (or more) of these at its beginning, the pointer will point to THAT instead of the first actual letter of the message.

 COULD IT BE?  YOU ARE FINISH!!

SOURCE: chrome-extension://gbkeegbaiigmenfmjfclcdgdpimamgkj/views/app.html
« Last Edit: May 02, 2016, 01:03:32 pm by aweigh »