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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Vegetaman

Pages: [1] 2 3
1
Wow it's been almost five years and I totally feel I need to go back and update this SRAM document finally. Wow, talk about real life getting in the way.

But very interesting about the message box information, badinsults. I wonder if there are other things contained there, such as pauses or movement information for cutscenes, or if it is truly just text and text persistence time? I think we could figure this out!

EDIT:

Oh geeze it's been 6 years almost. Yikes.

2
Newcomer's Board / Re: Lufia II monster stats
« on: December 07, 2012, 07:25:22 pm »
I realize Lufia II is probably not the same "core" as Lufia I, but back in 2006 over at gamefaqs we did some digging into monster data. Perhaps you may find some interesting tidbits on how to wander thru the monster data in this topic:

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

For example, the 23rd byte apparently turned out to be the "item that may drop" when they are killed, and the 24th byte is the probability of it dropping when you kill them.

3
I see only two bytes listed for EXP ("lo" and "hi" byte), but there definitely should be at least 3 bytes per character.

You're quite right -- it would need 3 bytes to be able to exceed 65535 and go up as high as 0xFFFFFF or 16777215... The same as Gold. Perhaps I should verifying and prove/disprove the information on that page and incorporate what I discover into my guide...

Also, in addition to bitflags for chests opened, there would have to be some for story scenarios and bosses beaten as well... If that SRAM code could be cracked, you may be able to pull off some neat stunts (like... a world without bosses). Of course, it may turn out like when I gave the Hero the Elf spell -- turns out that if you go there without Jerin in your party the game locks up like fort knox.

4
I am bumping this topic only because I felt like I needed to finish the SRAM guide. But in the time that has expired since I last touched this, I was notified that a RAM map has been updated on the site's wiki by Gendou and Alchemic:

http://datacrystal.romhacking.net/wiki/Lufia_%26_the_Fortress_of_Doom:RAM_map

With this being said... Is there anything that seems missing or unclear on how it works from an SRAM point of view at this point as far as character data? Because it looks fairly covered now. But it is my sincere belief that every treasure chest and secret item in this game must have an SRAM bitfield associated with them, so I was going to put that next on my list of things to track down. Anybody have any good tips on where to start looking for that?

Also I finally got around to playing with those dictionary tools from the .ZIP file. Very, very cool.

5
Personal Projects / Re: GoldenEye (N64) Spectrum Emulation Unlocked
« on: April 18, 2012, 09:57:43 pm »
I have to admit, this is all very fascinating. The level of commitment of people digging into this stuff still amazes me.

6
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.

7
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...

8
Personal Projects / Re: Mystic Quest Reborn / Mystic Quest HardType
« on: November 25, 2011, 09:38:46 pm »
I would absolutely love to get involved with the data mining of the ROM for this game, but alas I need to stick with Lufia for the time being (I have a lot of work left to do there)... But I am interested to see how treasure chests / items in treasure chests work...

9
Personal Projects / Re: Mystic Quest Reborn / Mystic Quest HardType
« on: November 19, 2011, 10:18:01 am »
So is this just a difficulty and graphics update, or are there actually new areas to explore or more enemies in the game? Either way, it looks cool, and I hope to get a chance to play it over Thanksgiving. Nice to see this game getting some attention.  :thumbsup: :beer: :cookie: ;)

10
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.

11
Newcomer's Board / Re: Help cracking encrypted text
« on: June 15, 2011, 12:24:42 am »
Here's a sentence that uses the same characters consecutively.

''Goodbye, Takuya.''
Code: [Select]
00000170                               54 4E 28 4E 1C 07 11            TN(N...
00000180   10 14 59 43 27 13 10 07  0F 12 51 50 50            ..YC'.....QPP

As you can see, it uses ['] twice at the beginning, and twice and the end. And surprisingly, they have the same hex value $50,  I tried changing the last two bytes to $51 and it caused the game to show [&] instead of [']


As I understand it, it breaks up like this, then?

Code: [Select]
STRING:    '  '  G  o  o  d  b  y  e  ,     T  a  k  u  y  a  .  '  '
GAME HEX:  54 4E 28 4E 1C 07 11 10 14 59 43 27 13 10 07 0F 12 51 50 50

STRING:    '  '  G  o  o  d  b  y  e  ,     T  a  k  u  y  a  .  '  '
ASCII HEX: 27 27 47 6F 6F 64 62 79 65 2C 20 54 61 6B 75 79 61 2E 27 27

What is telling is that you have a 0x4E meaning a " ' " in one spot, and a 0x4E meaning an " o " in another, in the same string... As well as having 0x54, 0x4E, and 0x50 all meaning " ' " at different points, apparently... At least, IMO...

The ASCII hex assumes what the string would be if the game would have been using an ASCII character table (which depending on how the XOR encoding is done, may or may not be a truism). That part was added to see if any patterns emerge... Which, for me, is going to have to wait until tomorrow...

12
Newcomer's Board / Re: Help cracking encrypted text
« on: June 14, 2011, 07:54:41 pm »
If it is just a standard XOR encryption, and the cipher key is trivial (meaning they weren't really trying to lock it up like Fort Knox), then doing a frequency analysis on the hex data that contains all of the text strings from the game may well allow the key to be discovered -- but the assembler method is probably the fastest.

13
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"

14
Personal Projects / Re: Super Mario 64 - Star Road
« on: June 04, 2011, 10:50:44 am »
Looks outstanding!

The screenshot reminds me of Rusty Bucket Bay from Banjo-Kazooie.  Do you have other Banjo-Kazooie-inspired areas in there too?

Indeed, I was going to say it reminded me of Banjo-Kazooie or Donkey Kong 64. Very sweet; keep up the good work!

15
Newcomer's Board / Re: Hunting for glitches/bugs
« on: June 02, 2011, 07:37:21 pm »
I was going to suggest Lufia II: Rise of the Sinistrals. It is rife with all sorts of little bugs and glitches. Things like improper names, the item pricing glitch, killing the Egg Dragon (heal it to make it's 65535 health pass over 0 and then hit it once to slay it)... Etc.

http://www.gamefaqs.com/boards/588451-lufia-ii-rise-of-the-sinistrals

16
Personal Projects / Re: The Legend of Zelda: Shadow of Night
« on: May 21, 2011, 02:15:21 pm »
Grinding Tip:

This is what I do when I need to grind some EXP or refill my health/magic bars...

1. Find a place in a palace where the ceiling drips acid and occasionally those blue jelly guys.

2. Cast life magic on yourself until you are fully healed.

3. Position yourself right at the edge of where they bounce to when they come out.

4. Set your turbo stab key, crouch Link down, and press it.

5. Now, turn on frame skip x10.

Now, make sure you made a save state before this, because sometimes they get lucky and whoop your ass.

Alternatively, you can use one of those overworld places like in the swamp that spawns those annoying ass birds that fly around continually. Just stand at a screen edge and turbo stab away!

I made many a level up this way. Also, they drop a magic container or P bag every 10 kills, so your magic bar should fill back up fast.

ALSO! I see somebody has started a video guide on youtube: http://www.youtube.com/watch?v=K_HxuvqCNaM  :cookie: :woot!:

17
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: :)

18
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:

19
Personal Projects / Re: The Legend of Zelda: Shadow of Night
« on: March 30, 2011, 10:04:55 pm »
Now that I think about it, I remember that there actually is an in game clue about the location of the last spell. It's a good clue that should make things pretty clear. The problem might be that some players will miss this clue. There is a message in the original game that is found in a similar way, but very easy to miss.

This isn't a huge secret, but that was a nice touch with the old lady who walks into the wall in Saria town. I originally thought she was supposed to be a "ghost" that you couldn't reach -- but DASH proved to be quite useful here.

20
Personal Projects / Re: The Legend of Zelda: Shadow of Night
« on: March 30, 2011, 07:19:08 pm »
As far as I can tell, you can never "beat" a palace, i.e., turning it to stone. 

As for the key for the lady locked out, that took ages for me to find.

Spoiler:
It's hidden similarly to the cat, but nowhere near the lady.  I found it near the western town exit.

I found a lady who wouldn't talk to me unless I had 7 magic containers, but after getting the cross from one of the palaces, she let me in, even though I only have five.  So, I'm able to progress to the great palace, but assuming it is like the original game, I'll need Thunder magic there, which I've not found, so I hesitate to explore inside.  And I still only have 5 6 magic containers and 6 7 heart containers...  Not really sure where the others are hiding, and I'm not sure I'm up for another check every square of the world map search, as I've pretty much done that already when looking for other things...  There's always checking every tree and rock wall with the hammer, but...

Let me see... There's one magic container near the first town, two heart containers from the first town to the second palace... And I think there's supposed to be more "magic" in one of the swamps, as well as death mountain. At least from in-game hints so far, and I'm only to palace 3.

Did find the key for the locked out lady, though.

Pages: [1] 2 3