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

Author Topic: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)  (Read 24021 times)

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6923
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor
« Reply #20 on: February 19, 2011, 12:00:16 pm »
I believe that if you load up your emulator, and then load a save state, it will clear the SRAM and load it with whatever it had in it when that save state was originally made (thus voiding your changes). [can somebody else confirm this?]
Yes, some emulators will do that. Those will argue it is for more accurate emulation, since some games could be using the SRAM for non-saving purposes.
So I hear Furai no Shiren is an example of a game that would crash horribly.
"My watch says 30 chickens" Google, 2018

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor
« Reply #21 on: February 19, 2011, 10:38:19 pm »
I believe that if you load up your emulator, and then load a save state, it will clear the SRAM and load it with whatever it had in it when that save state was originally made (thus voiding your changes). [can somebody else confirm this?]
Yes, some emulators will do that. Those will argue it is for more accurate emulation, since some games could be using the SRAM for non-saving purposes.
So I hear Furai no Shiren is an example of a game that would crash horribly.

Ah, I see. Well that makes sense, but thank you for confirming what I only recently came to realize was the case. Many thanks, sir!

Also... Semi interesting development tonight while working on my SRAM editor and compiling some documentation... Turns out that if you fill up all 32 slots of the Hero's spell list, meaning he does not have an "END OF LIST", he will also gain all of Lufia's spells. And if you fill up her list, you will gain all of Jerin's... There is no space for spells for Aguro, so you can't "give him" magic. Though if you fill up Jerin's list, you will probably go until the first 0x00 character. I need to make a slight update to my SRAM editor to reflect this -- hopefully this will be completed tomorrow.

==UPDATE== (FEBRUARY 20, 2011)

DOWNLOAD Version 2.2: http://www.mediafire.com/?b7lrwb19s64ybod *NEW*

NEW README: https://sites.google.com/site/vegetaman/home/sramchecksum/readme

Changelog:

- added support for modifying 32 spell slots instead of 24 (run over the lists at your own risk!)
- added the readme file to the .rar package and updated the readme as well

I managed to give the Hero 9 pages of spells thanks to this 32 byte run-over method:



Also, you can give the Hero the "Elf" spell at the start of the game, but if you talk to Artea, the game will lock up when he tries to give Jerin his bow:

« Last Edit: February 20, 2011, 10:46:39 am by Vegetaman »

gadesx

  • Full Member
  • ***
  • Posts: 247
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #22 on: February 27, 2011, 07:39:54 am »
try to make a editor of lufia 2, the best! xd

Mew seeker

  • Sr. Member
  • ****
  • Posts: 449
  • What are you doing there!?
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #23 on: March 16, 2011, 10:06:31 am »
About Elegion, I believe it was used in the Japanese version in the final battle there :
http://www.youtube.com/watch?v=mjrS40mGSFs
Look at about 5:18
From what I see, they changed the final boss moveset for the U.S. version,
making it more evil and hard IMHO as it
Spoiler:
only use spell and confusion against you.
In the Japanese version,
Spoiler:
he use instead moves used by all of the Sinistrals.

In Lufia, you can push the X button IIRC to know the effects of a spell.
However, in the Japanese version, you could do it with all items
including equipment, which gave their weight value right away.
I don't know if you could be interested in it or be able to do it
but just in case I mention it.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6923
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #24 on: March 16, 2011, 03:47:12 pm »
You could, but when I tried to play the Japanese version, it seemed like the item descriptions were mostly useless (even when I tried to use a dictionary to read them).
My guess is that perhaps the item descriptions were cut for space, as it seemed like they really crunched the data to make it fit into an 8-megabit cartridge (whereas it had been announced as a 12-meg cart, perhaps it was close enough Taito felt it wasn't worth having to buy extra ROM chips).
"My watch says 30 chickens" Google, 2018

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #25 on: April 02, 2011, 11:15:11 am »
That's cool about Elegion -- and I never knew that about X for some reason. I need to go back and try that.

I'm still working on the next phase of my SRAM guide. There are a lot of things I know need to be in SRAM about the game that I am trying to track down:

1. All of the treasure chests.
2. All of the "hidden items" (in book cases, etc.).
3. All of the Scenario Items. [they're not in your regular inventory]
4. Every town you visit for the fist time (for your WARP spell).
5. Status of your level in the Old Cave.
6. Items that go to the Isle of Forfeit.
7. Various other in-game scripting (people who change what they say after you talk to them a few times, different locations for people or Doom Island and those sort of things, etc.).
8. Triggers for various in-game cutscenes (ie. The Hope Ruby).
9. The in-game clock timer.
10. The abilities of The Falcon.

Again, a lot of this will take just a lot of time to sift through, but I think there could be a lot of good information here. It wouldn't surprise me if a lot of event data was just a single bit flag... And there's probably even more stuff buried in SRAM that I haven't even thought about yet.

Anyway, on a final note, just as an exercise for myself, I tried to comment the assembler code for the checksum routine... Did I get anywhere in the ballpark? Something about this just seems off to me (I haven't messed with Assembler in about 5 years):

Code: [Select]

 A0 FC 03    LDY #$03FC            ; load Y immediate with value 0x03FC
 A6 1F       LDX $1F    [$00:001F] ; load X with value at address 0x1F
 A9 02 65    LDA #$6502            ; load Accumulator with 0x6502
 18          CLC                   ; clear the carry flag
 7D 08 00    ADC $0008,x[$70:0008] ; add with carry starting at address 0x0008
 E8          INX                   ; increment the X register
 E8          INX                   ; increment the X register (again)
 88          DEY                   ; decrement the Y register
 D0 F7       BNE $F7    [$9431]    ; repeat until Y hits 0 (branch not equal)
 AA          TAX                   ; transfer the accumulator into X
 7A          PLY                   ; pull the Y register off of the stack
 AB          PLB                   ; pulls a byte off of stack into data bank
 28          PLP                   ; pull processor status off of the stack
 60          RTS                   ; return from subroutine


Thoughts on any of this, anyone?  :cookie: :cookie: :cookie: :cookie:

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6923
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #26 on: April 05, 2011, 12:29:24 am »
Well, the game clock should be easy to figure out.
Save the game, then backup the SRAM. Reopen the emulator, reload your saved game. Stay at the save point, wait for the time to increase, save again and compare the resulting SRAM.
The "treasure collected" data is likely to be a series of bitflags. To find the area where data is saved in SRAM, leave a treasure alone that's easy to get near a save point, and again do a comparison search of before and after SRAM.
It should only contain the difference of a byte (as well as checksum and maybe clock data). Then if you know the SRAM address for a specific example, you could trace where it comes from in RAM, and then trace the routine that set the flag in RAM (using breakpoints on the SRAM address, which I think should be $70xxxx).
Also using similar methods for the other stuff.
"My watch says 30 chickens" Google, 2018

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #27 on: April 10, 2011, 01:33:05 pm »
Well, the game clock should be easy to figure out.
Save the game, then backup the SRAM. Reopen the emulator, reload your saved game. Stay at the save point, wait for the time to increase, save again and compare the resulting SRAM.
The "treasure collected" data is likely to be a series of bitflags. To find the area where data is saved in SRAM, leave a treasure alone that's easy to get near a save point, and again do a comparison search of before and after SRAM.
It should only contain the difference of a byte (as well as checksum and maybe clock data). Then if you know the SRAM address for a specific example, you could trace where it comes from in RAM, and then trace the routine that set the flag in RAM (using breakpoints on the SRAM address, which I think should be $70xxxx).
Also using similar methods for the other stuff.

Indeed, I figured a great many things in there would be bit flags. Just a lot of save game, save SRAM, do event/get chest, save game, compare SRAM. I'd be farther along at this, but after I work all day (I'm an embedded systems C programmer), I don't have a lot of leftover desire to program or fiddle with this stuff when I get home, so I mostly tend to this on my free weekends. I'd like to make a comprehensive guide of all the parts of SRAM in Lufia & The Fortress of Doom so that somebody can do a proper ROMhack of this wonderful game. I like all of your ideas there, though. The treasure chests should be easy to do, since there are plenty of them in towns in castles near save points. Also, the same goes for items hidden in bushes and cupboards and stuff. Makes me wonder how each set of 3 dragon eggs is stored... I would assume all Isle of Forfeit things are bitflags, but for quantity of more than 1 for some items, that wouldn't quite work... Need to investigate all of this further. Thanks for the support and advice as always, KingMike!  :beer: :)

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: FEB 20)
« Reply #28 on: June 06, 2011, 10:46:26 pm »
I had a request for my SRAM program that was compatible with Linux/MAC, and sadly I have not had time to make a command line version of it (yet -- though I would like to)... So, if you're so inclined, you can use the guide to change the offsets yourself and use this program to calculate what the checksum needs to be (I think it works; I've only tested it a handful of times with the [!] version of the game):


I have written this small program (in C/C++) below to give you a better feeling for how
the checksum algorithm works for this game. I have included comments to try and
make it as straight forward as possible.

Code: [Select]
/* begin file -- main.cpp */

// File name: main.cpp
// Author: Vegetaman
// Date: February 24, 2011
// Purpose: Lufia Checksum

#include <iostream>
#include <fstream>

#define SIZE_OF_SRAM 0x2000                     // SRAM is 8K large
#define LUFIA_SRAM_FILE "C:\\Lufia.srm"         // SRAM file location
#define HALF_OF_2K 0x03FC                       // half of 2048 - 8
#define FILE00_OFFSET 0x0008                    // 8 bytes in
#define FILE01_OFFSET 0x0808                    // 2K + 8 bytes in
#define FILE02_OFFSET 0x1008                    // 4K + 8 bytes in
#define COUNTER_ROLLOVER_VALUE 0xFFFF           // max 16-bit value

using namespace std;

int main(int argc, char *argv[])
{
  FILE *filePtr;                           // file pointer
  unsigned char ArrayOfSRAM[SIZE_OF_SRAM]; // array of char or bytes
  unsigned short accumulator;              // is a 16-bit unsigned integer
  unsigned short register_x;               // will be just like the register X
  unsigned short register_y;               // will be just like the register Y
  filePtr = fopen(LUFIA_SRAM_FILE, "r");   // open file Lufia.srm -- read only

  // NOTE: I am reading the SRAM into an array so I don't have to do all of my
  //       operations from the file, which would be really slow and wasteful...

  fread(ArrayOfSRAM, sizeof(char), SIZE_OF_SRAM, filePtr); // load the array
  fclose(filePtr); // always close your file handle

  // begin the routine of calculating the first 16-bit little endian checksum
  register_x = FILE00_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0)      // while Y does not equal 0 (will run 1020 times)
  {
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // some code to throw the checksum up on the console so that it can be seen
  cout << "Checksum for FILE00: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // prepare to calculate the second little endian 16-bit checksum
  register_x = FILE01_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0)      // while Y does not equal 0 (will run 1020 times)
  {
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // some code to throw the checksum up on the console so that it can be seen
  cout << "Checksum for FILE01: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // prepare to calculate the third and final little endian 16-bit checksum
  register_x = FILE02_OFFSET; // load the first offset into register X
  register_y = HALF_OF_2K;    // load 0x03FC into register Y
  accumulator = 0x6502;       // load the accumulator with the base value 6502

  while(register_y != 0)      // while Y does not equal 0 (will run 1020 times)
  {
    accumulator += ArrayOfSRAM[register_x];      // get the first/low byte
    register_x++;                                // increment X
    accumulator += ArrayOfSRAM[register_x] << 8; // get the second/high byte
    register_x++;                                // increment X
    accumulator &= 0xFFFF;                       // discarding the carry flag
    register_y--;                                // decrement Y
  }

  // now throw the last checksum up on the console so it can also be seen
  cout << "Checksum for FILE02: " << dec << accumulator << endl;
  cout << "Little Endian HEX: " << hex << (accumulator & 0xFF) << " ";
  cout << hex << ((accumulator >> 8) & 0xFF) << endl << endl;

  // now, hold the program up until the user is done reading...
  cout << "Press ENTER to continue...";  // prompt user
  getchar();                             // wait for "ENTER" key
  return 0;                              // exit with success
}

/* end of file -- main.cpp */

Let me know if this works for you. I have been busy lately, but I DO intend to add more character offset data and stuff to this guide once I get the time to seek out the information... Your support and feedback is, as always, much appreciated!

NOTICE: You will have to change the file link in this line to point to where your Lufia SRAM file (.srm) is located on your local machine:

"#define LUFIA_SRAM_FILE "C:\\Lufia.srm"         // SRAM file location"

Hiei-

  • Sr. Member
  • ****
  • Posts: 373
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #29 on: November 10, 2011, 07:44:56 pm »
I checked a bit the rom and it's seems the rom handling the text pointers in a weird manneer or is it just me who didn't look at the right place?

The game also seems to have code hardcoded between dialogs, by the way.

So, does someone know how the text pointers of that game works? I would have also liked to do a dump of the text script (I managed to got all the MTE strings and would just need to find the way the pointers are calculated to do a proper dump, I think).

Thanks a lot!

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #30 on: November 18, 2011, 09:49:02 pm »
I checked a bit the rom and it's seems the rom handling the text pointers in a weird manneer or is it just me who didn't look at the right place?

The game also seems to have code hardcoded between dialogs, by the way.

So, does someone know how the text pointers of that game works? I would have also liked to do a dump of the text script (I managed to got all the MTE strings and would just need to find the way the pointers are calculated to do a proper dump, I think).

Thanks a lot!

I haven't played around with this game in about five months, but early on (maybe two years ago?) I tried to figure out how the text was stored. I have learned a lot more about how this stuff works than before this data was compiled, but some of what I was able to figure out is written down here:

Dictionary Decoded:

https://sites.google.com/site/vegetaman/home/dictionary/masterkey

Notes:

https://sites.google.com/site/vegetaman/home/dictionary

The whole thing with hard coded stuff occurring within dialogs confuses the crap out of me, too. I have to assume it has to do with location information (such as for a character to walk or the camera to pan).

I took the data I did know and made a C# program to decode the text, but the hard coded information made the resulting dump fairly worthless. I was at least able to get large chunks of relevant dictionary information like this, though:

Code: [Select]
Important Codes:
----------------
04 text box close (?)
05 line return
07 character name call
0b place name call
0c lower case dictionary
0d upper case dictionary
20 blank space (" ")
2e period (.)
2b double period (..)
20 - 7f reserved character symbols
00 - 0f reserved flag calls and specials
80 - a9 new textbox (?) [tie to character/position?]
?? time to wait between boxes (?)

(many of the above are just guesses, whereas the below are taken from the ROM more directly)

...snip...

LC|UC|link#|dictionary
--|--|-----|----------
80 c0 42 cb the
81 c1 45 cb you
82 c2 48 cb to
83 c3 4a cb it
84 c4 4c cb of
85 c5 4e cb that
86 c6 52 cb is

Note that the LC is the hex value for lower case and that UC is the hex value for upper case (as in "the" versus "The", IIRC). I spent quite a bit of time on it back in 2010 or so, but finally gave up the ghost to work on the SRAM project, which I still need to get back to...

Trial Text Dump:

https://sites.google.com/site/vegetaman/home/dictionary/textdump

Let me know if you have any more information I don't -- or if you'd like me to explain some of this information I have better.

Code: [Select]
Some examples of the "hard coded" stuff mucking up the text translation
as my program currently stands with some well known dialog from Alekia
Castle towards the start of the game:

usedSinistralRcanWhat? The rumor about
monsters in Sheran?
I can't send anyone
until you've checked it.

canNo matter how many times
you ask, I can't send the
knights until you've checked
to see if the rumor's true.

canSo, the monsters really
attacked Sheran. I wonder
if our kingdom is safe?

whatYour Majesty. Please
organize the detail. This
matter is too serious
to ignore!

canI leave all foreign affairs
in your hands. My first
duty is to protect the
kingdom.

canEstea's been meddling in
military affairs? Well, the
military needs shaking up,
anyway.

canIt is most fortunate that
the Kingdom of Sheran
survived unscathed. You
did well, Hero.
« Last Edit: November 18, 2011, 09:57:28 pm by Vegetaman »

Hiei-

  • Sr. Member
  • ****
  • Posts: 373
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #31 on: November 21, 2011, 06:58:34 pm »
I managed to found the dictionnary easily, it is stored directly in a part of the rom (0x054e19-0x0553CC for the biggest part of it).

You have more or less the same problem as me for the dump, because of the hardcoded values.

Code: [Select]
[CODE_040C32000C]
Hey. You shouldn't let[JUMP]
such a pretty lady run[JUMP]
away like that![END_000C]


Monsters in town?[JUMP]
We have ourselves a[JUMP]
heavy situation here.[END_000C]


Roman's cinnamon tea is[JUMP]
the best. I wish I could[JUMP]
make it, but Roman only[JUMP]
taught [Character_Name_Lufia]. [END_0005]


[CODE_0345000C]
The latest dress designs[JUMP]
are at the biggest shop in[JUMP]
Lorbenia_2. Why don't you go_2[JUMP]
there with [Character_Name_Lufia]?[END_000C]


Hey, [Character_Name_Lufia]. Whatever[JUMP]
happened to [Character_name_written_on_the_entry_name_screen]?[END_000C]


This is a merchant's shop.[END_1C03000C]


This is a weapons shop.[END_1C01000C]


This is an armorer's shop.[END_1C0200065000075000]


[CODE_045006001E000C]
You did well to find this[JUMP]
underground road. It's a[JUMP]
good way to keep out of[JUMP]
the rain.[END_1E00050C0800011C00000C]


Yes. It's really peaceful.[END_000C]


Monsters attacked the[JUMP]
Kingdom of Sheran?[JUMP]
Why is this happening now?[JUMP]
It's been 100 years.[END_000C]


You can't change your[JUMP]
weapon once you're in[JUMP]
battle, so be careful.[END]


[CODE_040C6600040D25000C]
Halt, [Character_name_written_on_the_entry_name_screen]! What is your[JUMP]
business in the castle?[END]


[WAIT]

[CODE_66000CC93F20]
The commander?[JUMP]
Same want_2 always. He's[JUMP]
sleeping in the tower_2room[JUMP]
on the far left side.[END_000C]


What? Monsters attacked[JUMP]
Sheran? Is the kingdom[JUMP]
safe?[END_000C]


When you want to use magic,[JUMP]
select the staff icon with[JUMP]
the cross key and press the[JUMP]
"A" button.[WAIT]

During battle, use the[JUMP]
cross key to choose a spell.[JUMP]
Press the "A" button to[JUMP]
cast it.[END_000C]


Press the "A" button when[JUMP]
in front of the dresser.[JUMP]
Maybe you'll find something.[WAIT]

When you walk around,[JUMP]
touch objects in towns and[JUMP]
villages to find hidden[JUMP]
items.[WAIT]

For example, you could[JUMP]
look around outside[JUMP]
this room.[END_0005]


[CODE_0C0800012E00000C]
Maybe you should ask[JUMP]
the commander first.[JUMP]
He's in the castle.[END_060D000C]


The commander said he[JUMP]
didn't know anything?[JUMP]
Well, if he doesn't,[JUMP]
we sure don't.[END_0005]


[CODE_0C0800013100000C]
Monsters in the Kingdom[JUMP]
of Sheran? The commander[JUMP]
didn't say a word about[JUMP]
that![END_000C]


Fight the monsters?[JUMP]
If I'd known that, I[JUMP]
would have trained more.[END]


[CODE_0410560002010B004300000C]
[Character_Name_Lufia] was crying.[JUMP]
Whoever made her cry must[JUMP]
be cruel and unfeeling.[END_000C]


Did you make up with[JUMP]
[Character_Name_Lufia]?[END_0005]

But a lot of parts are still "not perfect" :

Code: [Select]
I wonder how long this[JUMP]
peace will last.[JUMP]
Life used to be so hard[JUMP]
100 years ago.[END_84]


(ReynaofokAre you thinking about[JUMP]
the past again?[END_89]


What would we do if the[JUMP]
Sinistrals returned?[JUMP]
[Character_Name_Maxim] is dead. Who would[JUMP]
defend us?[END_84]


I'llingReynait.ReynaofokYou're a knight of Alexia,[JUMP]
aren't you? Doesn't [Character_Name_Maxim]'s[JUMP]
blood run in your veins?[JUMP]
Won't that be enough?[END_84]


what........[END_84]


okWe should be getting home[JUMP]
soon. I'll make you some[JUMP]
cinnamon tea. I haven't[JUMP]
made it for a while.[END_89]


Cinnamon tea.[JUMP]
One of your recipes that[JUMP]
actually tastes good.[END_AD]


Oh, you! I'll have you[JUMP]
know that it's very popular[JUMP]
with our guests.[END_28]





*ReynaofokWhat?[END_84]

The problem is, actually, this dump is done without the pointers because I didn't find how they work for this game. Knowing how they work would maybe able to get a good text dump, if the pointers starts at the beginning of the sentences (so, if they ignore the hardcoded values, which give false results because some of the values are the same than ones the dictionnary use).

This dialog is a good example :

Quote
ReynaofI'llI'mReyna(ReynaitjustwhatHmm. That's odd.[JUMP]
Aren't you using......[END_84]

"ReynaofI'llI'mReyna(Reynaitjustwhat" is, in fact, some hardcoded values and the real dialog is just :

Quote
Hmm. That's odd.[JUMP]
Aren't you using......[END_84]

The solution is to edit manually each dialog and/or put something like that in the .tbl file :

Quote
0318842C1884281884142618842818842A=[CODE_0318842C1884281884142618842818842A]\n
071A14080190=[CODE_071A14080190]\n
0345000C=[CODE_0345000C]\n
040005=[END_0005]\n\n\n
04000C=[END_000C]\n\n\n
040C32000C=[CODE_040C32000C]\n
040C6600040D25000C=[CODE_040C6600040D25000C]\n
04103D000C=[END_103D000C]\n\n\n

But it's a very very long and rather boring method :/
« Last Edit: November 21, 2011, 07:21:14 pm by Hiei- »

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #32 on: January 01, 2012, 02:12:47 pm »
Interestingly enough, back in 2006 we tried to work out some of this stuff on the gamefaqs Lufia board, with no luck there either. Is there a similar sort of text compression in Lufia II? I know that it was more popular, so if somebody cracked it, then surely it can be backwards related to Lufia I -- a shot in the dark, at least.

The topic in question: http://www.gamefaqs.com/boards/588452-lufia-and-the-fortress-of-doom/30424903

We had a lot of interesting discussions in that topic about monster data from the ROM itself; it is still a pretty good resource IMO.

My New Years Resolution is to work on my SRAM stuff some more this year. I need to get motivated and find some free time.

I just can't figure out the "garbled stuff". It has to be related to character movements or text boxes or something; but why is it hard coded in there? It makes no sense at this point. Perhaps somebody who knew assembler or could watch the text get loaded in the actual game itself would be able to make more sense of it...

justin3009

  • Hero Member
  • *****
  • Posts: 1615
  • Welp
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #33 on: January 01, 2012, 02:20:07 pm »
Best thing to do for noting that stuff is just do a bunch of random stuff that doesn't actually load any VWF dialogue up.

1. Use Geiger's SNES9X Debugger.
2. Click CPU.  Do whatever you need to do before loading any sort of dialogue, even press random buttons just so the code gets ran through once and you won't see it again.
3. Unclick CPU and move around just a tad.
4. Click CPU and move up to an NPC or something and talk to them to load up the dialogue.
5. Once the dialogue's loaded even a little, unmark CPU.
6. Check the log file and go through that and you'll figure out the dialogue stuff a bit more.

I may be assuming wrong if that was unknown but if it was, this can greatly help figuring out certain things.  Maybe not specifically for SRAM but it'll help with the text boxes and character movement, etc..
'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.'

Jigglysaint

  • Sr. Member
  • ****
  • Posts: 316
  • Corruptomancer
    • View Profile
    • Stuff Jigglysaint has done(like discover the Crocomire in MZM)
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #34 on: January 01, 2012, 11:04:59 pm »
Interestingly enough, back in 2006 we tried to work out some of this stuff on the gamefaqs Lufia board, with no luck there either. Is there a similar sort of text compression in Lufia II? I know that it was more popular, so if somebody cracked it, then surely it can be backwards related to Lufia I -- a shot in the dark, at least.

The topic in question: http://www.gamefaqs.com/boards/588452-lufia-and-the-fortress-of-doom/30424903

We had a lot of interesting discussions in that topic about monster data from the ROM itself; it is still a pretty good resource IMO.

My New Years Resolution is to work on my SRAM stuff some more this year. I need to get motivated and find some free time.

I just can't figure out the "garbled stuff". It has to be related to character movements or text boxes or something; but why is it hard coded in there? It makes no sense at this point. Perhaps somebody who knew assembler or could watch the text get loaded in the actual game itself would be able to make more sense of it...

Yeah, Lufia 2 uses a dictionary compress too, but the data itself is actually stored in the event code, and the event code is defined for each map.  I think Lufia 1's data works the same as well, which maybe why nobody can find pointers.  If there are pointers, they might be relative pointers(both games use relative pointers for things).  If that's the case then you need to find the start of the data and add the value of the pointer to that address.

xander

  • Jr. Member
  • **
  • Posts: 24
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #35 on: January 02, 2012, 01:08:16 pm »
FloBo has released his tools for lufia 1 which he used to translate to german.There is also source and documentation to go along with this which may be of great help.

http://digisalt.de/main.php?ccat=1188&site=1325360294&part=0&lang=GB

« Last Edit: January 03, 2012, 01:12:48 pm by xander »
xander

Vegetaman

  • Jr. Member
  • **
  • Posts: 79
  • Child of Doom
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #36 on: January 03, 2012, 07:28:44 pm »
FloBo has released his tools for lufia 1 which he used to translate to german.There is also source and documentation to go along with this which may be of great help.

http://digisalt.de/main.php?ccat=1188&site=1325360294&part=0&lang=GB

Interestingly enough, I read through some of his documentation and he hit the same snag we hit (I think...?). He makes mention of hex code 0x04 being the "end of text box", and it looks like he just marks everything else as "unused characters".

So I'll have to dig deeper into how he's doing it, but it looks like he must be specifically skipping over "junk" data or using some event data to kick him to the text menus... Hmmm... No explanation on what the junk after the "end of text box" code is, though.

Yeah, Lufia 2 uses a dictionary compress too, but the data itself is actually stored in the event code, and the event code is defined for each map.  I think Lufia 1's data works the same as well, which maybe why nobody can find pointers.  If there are pointers, they might be relative pointers(both games use relative pointers for things).  If that's the case then you need to find the start of the data and add the value of the pointer to that address.

Interesting... So the event code for each map is in different databanks, then? Relative pointers are always fun to suss out, since they require THAT much more legwork to uncover.

Best thing to do for noting that stuff is just do a bunch of random stuff that doesn't actually load any VWF dialogue up.

1. Use Geiger's SNES9X Debugger.

I have never tried Geiger's debugger, but it is quite widely hailed around here. I need to give it a whirl.

Hiei-

  • Sr. Member
  • ****
  • Posts: 373
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #37 on: January 05, 2012, 09:20:14 am »
I should have a good dump pretty soon, though gamefaqs already have one.

My friend is working on some tools to hack the game and make a french translation, but his tools use the pointers of the game (to move the texts anywhere in the rom).

He's actually analysing the game to find each value of each bytecode.

The dump will look like that :

Code: [Select]
<Event adr='0001BD58'>
</Event>

<Event adr='0001BD65'>
<Code id='04' value='95'>
<Code id='1C' value='00'>
<Perso 2>[Character_Name_Maxim]! We can't escape!</Text>
<Code id='15' value='0101'>
<Code id='3C' value=''>
<Code id='16' value='00'>
</Event>

<Event adr='0001BD82'>
<Code id='50' value='08'>
<Code id='5F' value='01'>
<Code id='5F' value='02'>
<Code id='5F' value='03'>
<Code id='5F' value='04'>
<Code id='5E' value='01'>
<Code id='3D' value='0026'>
<Code id='3D' value='0025'>
<Code id='3D' value='0024'>
<Code id='3D' value='0023'>
<Code id='3D' value='0027'>
<Code id='3D' value='0028'>
<Code id='3D' value='0029'>
<Code id='3D' value='002B'>
<Code id='3D' value='002C'>
<Code id='3D' value='001F'>
<Code id='3D' value='0103'>
<Code id='3D' value='0102'>
<Code id='3D' value='0106'>
<Code id='3D' value='010F'>
<Code id='3D' value='010E'>
<Code id='3D' value='0111'>
<Code id='3D' value='0119'>
<Code id='3D' value='0120'>
<Code id='3D' value='0309'>
<Code id='3D' value='030C'>
<Code id='3D' value='0315'>
<Code id='3D' value='0320'>
<Code id='3D' value='0317'>
<Code id='3D' value='031A'>
<Code id='3D' value='0326'>
<Code id='3D' value='0324'>
<Code id='3D' value='032A'>
<Code id='3D' value='031D'>
<Code id='3D' value='032C'>
<Code id='3D' value='032D'>
<Code id='3E' value='B957'>
<Code id='3E' value='963E'>
<Code id='3E' value='981C'>
<Code id='3E' value='BA32'>
<Code id='3E' value='9C5C'>
<Code id='3E' value='9D58'>
<Code id='3E' value='9E5F'>
<Code id='3E' value='9F5B'>
<Code id='3E' value='B024'>
<Code id='3E' value='B81D'>
<Code id='57' value='01'>
<Code id='3C' value=''>
<Code id='16' value='00'>
<Code id='69' value='04'>
<Text2>It's so dark.</Text>
<Text2>I feel the energy.</Text>
<Text2>A very dark energy.[NewLine]
Beware! It's powerful.</Text>
<Text2>[Character_Name_Selan]. Light Magic.</Text>
<Text2>As you wish.</Text>
<Code id='54' value='16'>
<Code id='09' value='0E002200'>
<Code id='27' value='010E22'>
<Code id='27' value='020D23'>
<Code id='27' value='030F23'>
<Code id='27' value='040E24'>
<Code id='18' value='02'>
<Code id='5A' value=''>
<Perso 1>Is this the Fortress[NewLine]
of Doom?</Text>
<Perso 2>So cold! It freezes[NewLine]
straight to the heart.</Text>
<Code id='6D' value='02'>
<Code id='3A' value='04'>
<Code id='6B' value='2004'>
<Text1>Welcome, [Character_Name_Maxim].</Text>
<Perso 1>[Character_Name_Daos]? It's you, isn't it?[NewLine]
Show yourself!</Text>
<Code id='83' value=''>
<Code id='B5' value=''>
<Code id='83' value=''>
<Code id='B2' value=''>
<Code id='83' value=''>
<Code id='2D' value='04'>
<Code id='83' value=''>
<Code id='6D' value='02'>
<Code id='3A' value='04'>
<Code id='6B' value='2004'>
<Text1>Approach. My chamber is[NewLine]
above. I await you.</Text>
<Code id='6A' value='3C'>
<Code id='16' value='00'>
</Event>

<Event adr='0001BF1E'>
<Text1>Move the pointer to the[NewLine]
spell. Press the "X" button[NewLine]
to see what the spell can[NewLine]
do.</Text>
</Event>

<Event adr='0001BF5E'>
<Text1>Move the pointer to the[NewLine]
spell. Press the "X" button[NewLine]
to see what the spell can[NewLine]
do.</Text>
</Event>

German tools, as explained in the readme, don't care about the pointers (5 bytes one), so basically they managed to put the translation in the same room where the english text was by recompressing the dictionnary with new values.

By the way, you can easily modify the rom to use a whole new dictionnary instead of the "CAPS-mod" dictionnary.

I can post the modifications that have to be done here if someone is interested.

Original game use a dictionnary, and the values start with "0C". It use another dictionnary which values start with "0D". "0D" are the same than "0C" instead the first letter is in caps.

With a few modifications, you can use a true new dictionnary for "0D", instead of the "CAPS-mod".

Same for the dictionnary "C0-FF" which is a miror of dictionnary "80-BF" and which is working the same way.

With those modifications, you can even extend the length of the dictionnary values, as you expand the rom. So you can have like 14 letters for each value for example, it's not a problem.
« Last Edit: January 05, 2012, 09:26:10 am by Hiei- »

Jigglysaint

  • Sr. Member
  • ****
  • Posts: 316
  • Corruptomancer
    • View Profile
    • Stuff Jigglysaint has done(like discover the Crocomire in MZM)
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #38 on: January 05, 2012, 08:25:09 pm »
For Lufia 2, I've got some values.  It's for an unheadered rom but it should be useful for finding data.  At 3E434 I have it listed in my bookmarks as part of the Lizardman boss script.  It's been years since I've played with the game so I don't know what's what, but somewhere should be a code that calls the boss, and the text should be there as well.  3E2BD I have as start of map 06 script, so that might be where the script starts.  I have 76A00 as the start of dictionary pointers, which are relative pointers(which the starting address can easily be found by forming a pointer to the pointer table, searching, and then glancing at the code to see what is loaded after it).  Item pointers are at B4FC3, and are relative.  It should be possible to relocate the code that comes after item data, or relocate item data itself in order to use the extra slots that otherwise glitch and harm the game.  That or just get rid of the Ran-Ran step which basically performs all the animations in the game in an never ending loop(and it calls them all by listing them all).  1380BD has map pointers, not sure if it's the start but a search should reveal that fact easily.  They are relative, and other pointers seem to be there as well, such as the tileset pointers and whatnot.  At 27FCBC I have sprite location pointers for each map.  Each map has it's own scripts defined, and this is the pointer list to where each event is positioned on the map.

That's pretty much it.  I also have some info on partimitars that are used in creating the Ancient Cave.  I think I fiddled with it and made it only give out blue chests in a treasure room setting on each floor.

xander

  • Jr. Member
  • **
  • Posts: 24
    • View Profile
Re: Lufia & The Fortress of Doom Text Dump & SRAM Editor (UPDATE: JUN 6)
« Reply #39 on: January 06, 2012, 02:03:59 am »
A lot of interesting notes on lufia 2.
« Last Edit: January 06, 2012, 07:39:07 pm by xander »
xander