+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Figuring out script storage format (NDS)
Pages: [1]
Author Topic: Figuring out script storage format (NDS)  (Read 2 times)
valderman
Guest
« on: August 25, 2008, 12:05:37 pm »

Hi,
I just started working on a translation of the Japanese game Mamegoma: Honobono Nikki. As I'm a complete newbie to ROM hacking and reverse engineering, I've run into a slight problem trying to figure out how the game stores its script. I've ripped the script files from the game's internal FAT and poked around a bit inside them with a hex editor. Luckily, the text storage format is very simple: NULL-terminated double byte strings with Shift-JIS encoding, with a few special sequences denoting variable values such as player name (_P,) newline (_R) and so on.

However, these strings are prefixed with a bunch of what seems to be fairly low 32-bit integers, (or 16-bit integers with every second one being a zero) and I'm having some trouble figuring out exactly what those numbers mean. There is no fixed ratio between the amount of integers and the amount of strings, instead the ratio wildly fluctuates from one script file to another. I've uploaded two script files, the game's opening dialogue and what seems to be some kind of testing/debugging script left in the ROM by the developers. There is no animation, menus or other trickery of any kind going on during the opening, just dialogue.

Does anyone recognize this format? Is there a common format for script files in NDS ROMs that I'm not aware of? If nobody has an idea, could you point me to a reasonable way of figuring this format out?
DarthNemesis
Guest
« Reply #1 on: August 25, 2008, 01:02:56 pm »

No, there's no common format, but it certainly appears to contain a pointer table. First, let's extract the dialogue and write down the address of each line. I'll reverse the bytes since that's how they'll be stored in the table as pointers.

Code:
2006 _P
2406 ママ
2A06 おじさん
3406 _P、_Rおかえりなさーい。
4E06 今日はいいニュース_Rがあるのよ。
7006 あなた、まめゴマ_Rかいたがってたわよね?
9A06 実は「まめゴマ園」の_R里親ぼしゅうに当ったのよ。
CC06 1年間スキなまめゴマをかりて_Rそだてるんですって。
0007 あなたにピッタリでしょ?
1A07 早く「まめゴマ園」に_Rいってらっしゃい!!
4607 いらっしゃい。_Rまめゴマの里親ですね?
6E07 1年間、まめゴマをがんばって_Rそだてて下さいね。
A007 じゃあ、かんたんにまめゴマの_Rかいかたをせつめいしますね。
DC07 水そうはまめゴマのおうちです。
FC07 タッチペンでまめゴマを長く_Rタッチすると、つまんで動かす_Rことができます。
4808 なでてあげることも_Rできます。
6808 まめゴマの気持ちは、_R上がめんに出ています。
9608 ここを見ながら、_Rいつでもニコニコ_Rになるように
C808 お世話してあげましょう。
E208 まめゴマに_R何かしてあげたい時は、
0609 左下のアイコンを_Rタッチしましょう。
2C09 1日に5回まで_R選ぶことができます。
5209 まめゴマといっしょに遊んだり、_Rお出かけしたりすると、
8A09 ゴマレベルが上がります。_Rお世話をちゃんとしてあげると_Rたくさん上がります。
D809 まめゴマが_Rつかれてねてしまったら、_R「ねる」をタッチしてね。
180A ゲームのきろくをしたい時は、_R「きろく」をタッチしてね。
520A 分からなくなったら「ヘルプ」を_Rタッチしてみてね。
860A もう1回せつめいしますか?
A20A じゃあ、さっそくまめゴマを_R選んでみましょう!

Okay, _P and _R definitely appear to represent the player's name and a line break (return). Now let's divide up the table data wherever one of those lines is referenced.

Code:
EC0300000200000001000000030000000000000000000000EC03000000000000010000000200000008000000...
24060000
34060000F203000001000000F103000000000000
4E060000F203000001000000F103000000000000
70060000F203000001000000F103000000000000
9A060000F203000001000000F103000000000000
CC060000F203000001000000F103000000000000
00070000F203000001000000F103000000000000
1A070000F203000001000000EE0300000A04000001000000EB03000001000000160400000A0000007E000000...
2A060000
46070000F203000001000000F103000000000000
6E070000F203000001000000F103000000000000
A0070000F203000001000000EE0300000A04000001000000EB030000010000000A0000007E00000020000000...
DC070000F203000001000000EC030000F900000001000000030000000000000000000000F103000000000000
FC070000F203000001000000EC030000FA00000001000000030000000000000000000000F103000000000000
48080000F203000001000000EC030000FB00000001000000030000000000000000000000F103000000000000
68080000F203000001000000F103000000000000
96080000F203000001000000F103000000000000
C8080000F203000001000000EC030000FC00000001000000030000000000000000000000F103000000000000
E2080000F203000001000000F103000000000000
06090000F203000001000000EC030000FD00000001000000030000000000000000000000F103000000000000
2C090000F203000001000000EC030000FE00000001000000030000000000000000000000F103000000000000
52090000F203000001000000EC0300000401000001000000030000000000000000000000F103000000000000
8A090000F203000001000000EC0300000101000001000000030000000000000000000000F103000000000000
D8090000F203000001000000EC0300000201000001000000030000000000000000000000F103000000000000
180A0000F203000001000000EC0300000301000001000000030000000000000000000000F103000000000000
520A0000F203000001000000EE0300000A04000001000000EC03000013000000000000000300000000000000...
860A0000FE030000460000007300000000000000520000007C050000EB030000010000000A0000007E000000...
A20A0000F203000001000000EE0300000A04000001000000EB03000001000000160400000A0000007E000000...

Wow, what a mess! Well, there do appear to be some blocks that are the same length. Watching the opening, it seems that those short blocks reference lines that are spoken in a row without any interruption, while the long blocks reference lines where there are transitions or movement in the scene. That can only mean one thing - this file contains the event script for the cutscene interspersed with the pointers to the script lines.

If you wanted to, you could probably take the time to map out exactly which bytes represent which actions in the game, but all you really need to do to translate it is to update those pointers to the starting address of each line when you re-insert the dialogue. I'll go ahead and analyze the format a little, though.

There are two blocks that are only a single int, and both reference a name that shows up at the top of the dialogue box. This leads me to believe that a table entry actually contains two pointers, one to the caption and one to the line itself. That would mean that each entry should actually start 4 bytes earlier:

Code:
EC0300000200000001000000030000000000000000000000EC0300000000000001000000...
[color=blue]2406000034060000F203000001000000F1030000
000000004E060000F203000001000000F1030000
0000000070060000F203000001000000F1030000
000000009A060000F203000001000000F1030000
00000000CC060000F203000001000000F1030000
0000000000070000F203000001000000F1030000
000000001A070000F203000001000000EE030000[/color]
0A04000001000000EB03000001000000160400000A0000007E0000002000000064000000...
[color=blue]2A06000046070000F203000001000000F1030000
000000006E070000F203000001000000F1030000
00000000A0070000F203000001000000EE030000[/color]
0A04000001000000EB030000010000000A0000007E00000020000000640000007E000000...
[color=blue]00000000DC070000F203000001000000EC030000[/color]
F900000001000000030000000000000000000000F1030000
[color=blue]00000000FC070000F203000001000000EC030000[/color]
FA00000001000000030000000000000000000000F1030000
[color=blue]0000000048080000F203000001000000EC030000[/color]
FB00000001000000030000000000000000000000F1030000
[color=blue]0000000068080000F203000001000000F1030000
0000000096080000F203000001000000F1030000
00000000C8080000F203000001000000EC030000[/color]
FC00000001000000030000000000000000000000F1030000
[color=blue]00000000E2080000F203000001000000F1030000
0000000006090000F203000001000000EC030000[/color]
FD00000001000000030000000000000000000000F1030000
[color=blue]000000002C090000F203000001000000EC030000[/color]
FE00000001000000030000000000000000000000F1030000
[color=blue]0000000052090000F203000001000000EC030000[/color]
0401000001000000030000000000000000000000F1030000
[color=blue]000000008A090000F203000001000000EC030000[/color]
0101000001000000030000000000000000000000F1030000
[color=blue]00000000D8090000F203000001000000EC030000[/color]
0201000001000000030000000000000000000000F1030000
[color=blue]00000000180A0000F203000001000000EC030000[/color]
0301000001000000030000000000000000000000F1030000
[color=blue]00000000520A0000F203000001000000EE030000[/color]
0A04000001000000EC0300001300000000000000030000000000000000000000F8030000...
[color=red]FD030000860A0000FE0300004600000073000000[/color]
00000000520000007C050000EB030000010000000A0000007E0000002000000064000000...
[color=blue]00000000A20A0000F203000001000000EE030000[/color]
0A04000001000000EB03000001000000160400000A0000007E0000002000000064000000...

Alright, now we're getting somewhere. A block that continues into the next dialogue box ends with F1030000, while a block with an action afterward ends with... actually, there doesn't seem to be a consistent value. Looks like all the event blocks before a line end with F1030000 as well, so we probably need to shift the table entries over again.

Code:
EC0300000200000001000000030000000000000000000000
EC0300000000000001000000020000000800000000000000
EC0300001300000000000000030000000000000000000000
EC03000014000000000000000200000000000000050000001504000002000000
EB030000000000000A0000007E00000020000000640000007E0000000904000001000000
ED03000001000000
EF030000
F0030000
[color=blue]F10300002406000034060000F203000001000000
F1030000000000004E060000F203000001000000
F10300000000000070060000F203000001000000
F1030000000000009A060000F203000001000000
F103000000000000CC060000F203000001000000
F10300000000000000070000F203000001000000
F1030000000000001A070000F203000001000000[/color]
EE0300000A04000001000000
EB03000001000000160400000A0000007E00000020000000640000007E000000
F80300000000000003000000
F80300000000000002000000
F80300000100000003000000
F80300000100000002000000
EC030000AC00000000000000030000000000000000000000
EC030000AD00000000000000020000000000000000000000
EC03000013000000010000000300000000000000000000001504000008000000
EB030000000000000A0000007E00000020000000640000007E0000000904000001000000
ED03000001000000
EF030000
F0030000
[color=blue]F10300002A06000046070000F203000001000000
F1030000000000006E070000F203000001000000
F103000000000000A0070000F203000001000000[/color]
EE0300000A04000001000000
EB030000010000000A0000007E00000020000000640000007E000000
F80300000100000003000000
F80300000100000002000000
EC030000F800000001000000030000000000000000000000
EB030000000000000A0000007E00000020000000640000007E0000000904000001000000
ED03000001000000
EF030000
F0030000
[color=blue]F103000000000000DC070000F203000001000000[/color]
EC030000F900000001000000030000000000000000000000
[color=blue]F103000000000000FC070000F203000001000000[/color]
EC030000FA00000001000000030000000000000000000000
[color=blue]F10300000000000048080000F203000001000000[/color]
EC030000FB00000001000000030000000000000000000000
[color=blue]F10300000000000068080000F203000001000000
F10300000000000096080000F203000001000000
F103000000000000C8080000F203000001000000[/color]
EC030000FC00000001000000030000000000000000000000
[color=blue]F103000000000000E2080000F203000001000000
F10300000000000006090000F203000001000000[/color]
EC030000FD00000001000000030000000000000000000000
[color=blue]F1030000000000002C090000F203000001000000[/color]
EC030000FE00000001000000030000000000000000000000
[color=blue]F10300000000000052090000F203000001000000[/color]
EC0300000401000001000000030000000000000000000000
[color=blue]F1030000000000008A090000F203000001000000[/color]
EC0300000101000001000000030000000000000000000000
[color=blue]F103000000000000D8090000F203000001000000[/color]
EC0300000201000001000000030000000000000000000000
[color=blue]F103000000000000180A0000F203000001000000[/color]
EC0300000301000001000000030000000000000000000000
[color=blue]F103000000000000520A0000F203000001000000[/color]
EE0300000A04000001000000
EC0300001300000000000000030000000000000000000000
F80300000000000002000000
[color=red]FD030000860A0000
FE030000460000007300000000000000520000007C050000[/color]
EB030000010000000A0000007E00000020000000640000007E000000
EC030000AC00000000000000030000000000000000000000
EC030000AD00000000000000020000000000000000000000500000006C020000
EC030000AC00000000000000030000000000000000000000
EC030000AD00000000000000020000000000000000000000
EC03000013000000010000000300000000000000000000000904000001000000
ED03000001000000
EF030000
F0030000
[color=blue]F103000000000000A20A0000F203000001000000[/color]
EE0300000A04000001000000
EB03000001000000160400000A0000007E00000020000000640000007E000000
FFFFFFFF

Hey, now there's a consistent pattern! F103 represents a line of dialogue and FD03 represents a decision box, and there are a bunch of other control codes for you to figure out. If you decide to do so, I recommend incrementing or decrementing one of the values and then watching the cutscene to see what changes.
« Last Edit: August 25, 2008, 09:34:55 pm by DarthNemesis »
Pages: [1]  


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