Hacking Brandish: The Dark Revenant translation

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
Yeah, I saw that, but the 8 uncompressed files in txt can't be all of the game's text can they? You were saying before that you were trying to get the compressed files in the *.act archives uncompressed. So did you find that they contain no text at all? Or is the txt folder really all of it?

EDIT: Ok for the script files, I've figured out how the pointers work, but I'm still so unsure on so much of the file I'm not sure how useful this will be to you.

The pointers are all based off of the start of the text table, and 04000000 is the text opcode. If you search the file for "040000000000000064" you'll get a lot of the hits that reference the strings. But there are entries that have the first variable at beyond 0, and there are also ones where that 64 isn't set either. You can't just search for 04000000 though because you'll get a hell of a lot of stuff (obviously). So it's going to require a lot of manual insertion work.

The location for the string pointer is 0x14 bytes after that 04, and it's set from the beginning of the text table.

Also, the length of the text table is stored as a word in the header at 0x2a, so you'll need to update that too. No idea what the other values are.

Here's an example of it working:
M4ZT2nZ.jpg


And the very next line following it (to show you that the next line works properly):

hJvi3Ny.jpg
Here's the actual strings I used:

Let's make this an uber long string to test things,comma here should bring this into a new line,and again. neoxephon neoxephon neoxephon,I heard that if you say it three times into a mirror, he'll appear and not be able to find string pointers. :),Adding a whole FF more bytes,surely we're off the screen by now123.Here is string 2,right the way down here, This is jsut blah blah ble is string 2,right the way down here, This is jsut blah blah ble is string 2,right the way down here, This is jsut blah blah ble is string 2,right the way down here, This is jsut blah blah blsut blah blah bl.

As they are in the file, the second string is just after the "now123." I made both of them FF bytes longer than their originals.

A nice thing I found out, after adding in manual commas for newlines after reading you said they were used, is that the game has automatic newlining. \o/ That's always a pain, nice that the game handles it itself. I also thought the text would go off the screen and not automatically scroll for you, but nop, that's handled too, nice.
 

neoxephon

Well-Known Member
Member
Joined
Jul 13, 2009
Messages
437
Trophies
0
Age
35
Location
USA
XP
547
Country
United States
Yeah, I saw that, but the 8 uncompressed files in txt can't be all of the game's text can they? You were saying before that you were trying to get the compressed files in the *.act archives uncompressed. So did you find that they contain no text at all? Or is the txt folder really all of it?

As far as I am aware, that is it. The script is the biggest amount of text. The game doesn't have a lot of items and whatnot. Some of the game text is graphics.

The assets for the Dela scenario that they added to the PSP game (wasn't in the original SNES game) are located in the \ext folder. Some of the items and enemies are the same, while some are different. So, for example, item.tb in the \ext\txt folder is not identical to the item.tb located \txt\ folder.

Great job on figuring out the pointers!

mp1_14.scp (which contains all of the script for the Tutorial) seems to handle the pointers just slightly different.

With all of the other script files, I can get the pointers every time by searching for:
04 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00 00 00 00 00

But with mp1_14.scp it is instead:
04 00 00 00 01 00 00 00 64 00 00 00 00 00 00 00 00 00 00 00

And the control codes for showing the Tutorial images (tuto00 and so on) get counted in with the text strings connected to it (they don't have their own pointers like I originally thought).

Say we start at the 00 before tuto00 (beginning of text block) the pointer is the number of bytes from that 00 until the 00 after the text string (not the 00 after tuto00). CC seems to tell it that the text string should begin. This seems to be the case for all text strings that have a special control code before the actual text (tuto00, a_name8, br1_a5, etc.)

So basically, if we have a control code before the text string, the pointer includes the control code and the following text string.

A little bit later today, I'm going to go through all of the script files and make sure the pattern for finding the pointers is the same for all of them. Then, I'll start working on programming a tool.
 

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
Yeah, I said it'll be different, and that's why it requires a bunch of manual effort. There are some which don't have that 64 in either. They're just variables for the 04 opcode, so they're not handled differently, it's just called with different values.

Also, you have that backwards, it starts at the first character, not at the 00. The pointers all point to the first character of the string, and the 00 (a null) is what marks the end of strings. The CC does something else which isn't in very many strings at all, not even the ones that call the next part of the script, like tuto12, tuto4 etc etc, but it is on just some of them like tuto14, and also some just normal strings. Either way though, that CC isn't loaded, the pointer goes past it. Something else may interact with it though.

EDIT:

Ok so the first variable controls the type of text box. 00 is for a text box that goes by itself, needs no interaction. 01 is a standard dialogue-type box that requires you to press O. 02 is the same as 00. 03 is one of those wall panels:

hrkYh9d.jpg

But the text is ghosting a bit. So other variables at play there. EDIT: Ok, it's because the text is shadowed. When you want to use a wall panel type text, use #6C at the start of the string, that sets the text colour to black and it looks normal.

04 is the same as 03.

05 is a bit interesting, it plays the string automatically, then fades it out, but keeps the text box open. I then have a blank text box, sooo that's for showing multiple strings per text box, without actually closing-reopening it.

Not sure what 06 is. 07 gives us a yes/no box, and so does 08 (except 08 shows more text after choosing an option, 07 doesn't):

d2Xyxyz.jpg

And etc etc, so that's the first variable. From what I can see though, the 04 opcode takes differing amounts of variables, based on whatever the first value is, or maybe it's all under the umbrella of a larger opcode which remains the same. I'm not going to go through every variable, as I'm sure most of it will be difficult to see what it does.

So there isn't so much of a "pattern" to it, as the variables just change based on what sort of text they want.

Some opcodes (all variables are dwords I think, and all values are in hex):
01 - 20 bytes - return?
02 - 20 bytes
03 - ? bytes - This one is a tricky trickster. It has the absolute block count for the block after it, at 0xC from its opcode. Then where it ends is at at 0x10. So if you had a 03 opcode like: 03000000 65000000 01000000 a0000000 a2000000 - Then that 03 has an extra block (beyond its standard 20 bytes) at base+(a0*20), which means that our 03 code itself is at base+(9f*20). And the next opcode will start at base+(a2*20). So essentially, our 03 is at base+13E0, and the next opcode after 03 will be at base+1440.
04 - 20 bytes - set string
17 - 20 bytes - move camera?
1a - 20 bytes - move camera?
1e - 20 bytes
1f - 20 bytes - wait?
20 - 20 bytes
23 - 20 bytes
43 - 20 bytes
44 - 20 bytes
45 - 20 bytes
46 - 20 bytes

There's tonnes more. Anyway, most of them are 20 bytes, the whole thing works based on 20 byte blocks. It saves the start of that script (well, sort of mini function if you will), and then saves how many 20 byte blocks it's jumped, and then pulls the opcode from that base address+(blocks*20).

I'm going to assume that 03 isn't the only one that can change its length based off a value.

To investigate yourself, just breakpoint at 08845404, that's where it reads the opcode, you can find everything from there. v0 has the opcode we're reading, v1 has our base address, and +C bytes to v1 is where our block count is.

Go through and get all their lengths, figure out any annoying ones like 03, and then you can write a decompiler which can dump all the opcodes and all their variables into a file, and you'll then be able to edit things, and recompile them without breaking anything.

Another thing is that the length of the script table is saved in the script file header at 0x28 as a word, and it's the length / 20. Sooooo, but process of deduction, all those words before that are going to the sizes of other sections in the file as well..... I think.

EDIT: So I made a dumper, no reinsertion yet, but here's how looks so far. This is dumped from mp1_01.scp:

0x61 { 19 3c 37 0 17000c 0 0 }
0x3 { 100 0 2 8c 0 0 0 }
0x8 { 100 0 0 0 0 0 0 }
0x14 { 1 1 5 a 0 0 0 }
0x14 { 2 3 1 5 0 0 0 }
0x14 { e 1 3d 28 0 0 0 }
0x14 { e 17 3d 28 0 0 0 }
0x14 { 10 1 1 a 0 0 0 }
0x14 { 10 1e f 12c 0 0 0 }
0x14 { 12 1 f 12c 0 0 0 }
0x14 { 12 17 9 1 0 0 0 }
0x14 { 14 1 f 64 0 0 0 }
0x14 { 14 14 f 64 0 0 0 }
0x14 { 16 14 f 12c 0 0 0 }
0x14 { 1e 1 e 5 0 0 0 }
0x14 { 16 1c 8 a 0 0 0 }
0x14 { 12 1b 3d 32 0 0 0 }
0x14 { e 1d 47 1 0 0 0 }
0x1c { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1f { 5dc 0 0 0 0 0 0 }
0x16 { 0 0 0 0 0 0 0 }
0x5b { 0 0 ff 0 0 0 0 }
play-video { 0 0 0 0 "br1_tra" 8 0 }
0x56 { 2 0 0 0 0 0 0 }
0x79 { 0 0 0 0 0 0 0 }
0x16 { a 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
play-video { 0 0 0 0 "br1_op" 7 0 }
0x56 { 8 0 0 0 0 0 0 }
0x79 { 0 0 0 0 0 0 0 }
0x16 { a 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x58 { 64 0 0 0 0 0 0 }
0x2a { 10 1c 0 0 0 0 0 }
0x44 { 10e 0 0 0 0 0 0 }
0x46 { 50 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x43 { 4b a 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
0x56 { a 0 0 0 0 0 0 }
0x1f { 5dc 0 0 0 0 0 0 }
0x13 { ffffffff 10 1b 0 0 0 0 }
0x1a { ffffffff 2b7 2b7 0 1 0 0 }
0x2a { 10 1b 1 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x43 { 96 32c8 0 0 0 0 0 }
0x46 { 3c 32c8 0 0 0 0 0 }
0x2a { 10 1b 0 32c8 0 0 0 }
0x5c { 64 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x1f { 4b0 0 0 0 0 0 0 }
TEXT { 0 5a 0 0 "どれほどの時間が経っただろうか。" 20 0 }
0x23 { 0 0 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
TEXT { 0 78 0 0 "……幸いな事に、,命を落さずに済んだようだ。" 2b 0 }
0x23 { 0 0 0 0 0 0 0 }
0x1a { ffffffff 2b7 2b7 0 1 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
0x1a { ffffffff 2b7 2b7 0 1 0 0 }
0x1f { 1f4 0 0 0 0 0 0 }
0x1a { ffffffff 2b7 2c6 0 3c 0 0 }
0x20 { ffffffff 0 0 0 0 0 0 }
0x1e { 32 0 0 0 0 0 0 }
0x2a { 10 1b 1 0 0 0 0 }
0x45 { 0 0 2 0 0 0 0 }
0x44 { 0 0 2 0 0 0 0 }
0x43 { 0 0 2 0 0 0 0 }
0x46 { 0 0 2 0 0 0 0 }
0x46 { 23 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x1a { ffffffff 2c6 2ed 0 3c 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x20 { ffffffff 0 0 0 0 0 0 }
0x1f { 1f4 0 0 0 0 0 0 }
0x44 { 3c 2710 1 0 0 0 0 }
0x43 { 4b 2710 0 0 0 0 0 }
0x46 { 0 2710 2 0 0 0 0 }
0x62 { bb8 0 0 0 1e000c 0 0 }
0x1a { ffffffff 25d 262 5 14 0 0 }
0x20 { ffffffff 0 0 0 0 0 0 }
0x1f { 12c 0 0 0 0 0 0 }
0x1a { ffffffff 262 26c 5 19 0 0 }
0x20 { ffffffff 0 0 0 0 0 0 }
0x1f { 12c 0 0 0 0 0 0 }
0x1a { ffffffff 26c 271 5 19 0 0 }
0x20 { ffffffff 0 0 0 0 0 0 }
0x1f { 320 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "どうやら、ここは,かなり古い廃墟のようだ。" 29 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "空気は湿り気を含んでおり、,ひんやりと肌に冷たい。" 31 0 }
0x23 { 0 0 0 0 0 0 0 }
0x1f { c8 0 0 0 0 0 0 }
0x7 { 10 1b fa0 0 0 0 0 }
0x1e { c8 0 0 0 0 0 0 }
0x43 { 0 0 2 0 0 0 0 }
0x44 { 0 0 2 0 0 0 0 }
0x2a { f 17 2 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x44 { a 0 1 0 0 0 0 }
0x2b { 1 0 0 0 0 0 0 }
0x46 { 0 0 0 0 0 0 0 }
0x2b { 4 0 0 0 0 0 0 }
0x46 { fffffff6 1f40 0 0 0 0 0 }
0x2a { f 17 3 1f40 0 0 0 }
0x61 { 19 3c 37 0 17000c 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x1f { 44c 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "はるか遠方に,塔のような構造物が見える。" 27 0 }
0x23 { 0 0 0 0 0 0 0 }
0x1f { 50 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "地上に出るには、,あの塔を目指すしかなさそうだ。" 2f 0 }
0x23 { 0 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x1f { 3e8 0 0 0 0 0 0 }
0x15 { c8 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x19 { ffffffff 0 0 0 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x45 { 0 0 2 0 0 0 0 }
0x44 { 0 0 2 0 0 0 0 }
0x43 { 0 0 2 0 0 0 0 }
0x46 { 0 0 2 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1f { 1f4 0 0 0 0 0 0 }
0x16 { 64 0 0 0 0 0 0 }
0x1f { 3e8 0 0 0 0 0 0 }
0x3e { ffffffff 10e 0 0 0 0 0 }
0x21 { 0 70 7b 1e "a_name1" 8 0 }
0x38 { 0 0 100 20 0 0 0 }
0x37 { 0 0 0 0 0 0 0 }
0x1f { b54 0 0 0 0 0 0 }
0x36 { ff ff 0 64 0 ff0000 0 }
0x37 { 0 0 0 0 0 0 0 }
0x68 { 0 0 0 0 0 0 0 }
0x68 { 1 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x2 { 94 0 0 0 0 0 0 }
0x3 { 1f3 1 8d 8e 0 0 0 }
0x19 { 1 2 1 0 0 0 0 }
0x2 { 8f 0 0 0 0 0 0 }
0x3 { 1f5 1 90 91 0 0 0 }
0x29 { 0 0 0 0 0 0 0 }
0x2 { 92 0 0 0 0 0 0 }
0x18 { 0 0 0 0 0 0 0 }
0x2 { 94 0 0 0 0 0 0 }
0x3 { 146 0 95 97 0 0 0 }
0x5 { 1c 3 5 0 0 0 0 }
0x2 { 99 0 0 0 0 0 0 }
0x5 { 1c 3 0 0 0 0 0 }
0x2 { 99 0 0 0 0 0 0 }
0x11 { 4 b 65 1 0 0 0 }
0x3 { 65 1 9b 9d 0 0 0 }
0x6 { 4 b 5 0 0 0 0 }
0x31 { 4 b 0 0 0 0 0 }
0x2 { 9e 0 0 0 0 0 0 }
0x11 { 6 b 65 1 0 0 0 }
0x3 { 65 1 a0 a2 0 0 0 }
0x6 { 6 b 5 0 0 0 0 }
0x31 { 6 b 0 0 0 0 0 }
0x2 { a3 0 0 0 0 0 0 }
0x34 { 0 0 0 3e8 0 1b0010 0 }
0x1 { 0 0 0 0 0 0 0 }
0x11 { a 1b 65 0 0 0 0 }
0x11 { 16 1b 66 0 0 0 0 }
0x3 { 65 1 a8 af 0 0 0 }
0xd { 4 0 0 0 0 0 0 }
0x1f { 32 0 0 0 0 0 0 }
0x28 { 219 0 64 0 0 0 0 }
0x10 { 4 0 0 0 0 0 0 }
0x12 { 1 d 4 0 0 0 0 }
0x13 { ffffffff 9 1b 2 0 0 0 }
0x2 { c6 0 0 0 0 0 0 }
0x3 { 66 1 b0 bc 0 0 0 }
0xd { 4 0 0 0 0 0 0 }
0x1f { 32 0 0 0 0 0 0 }
0x28 { 219 0 64 0 0 0 0 }
0x10 { 4 0 0 0 0 0 0 }
0x12 { 1 d 4 0 0 0 0 }
0x55 { 67 3 0 0 0 0 0 }
0x3 { 67 1 b7 b9 0 0 0 }
0x13 { ffffffff 17 1b 3 0 0 0 }
0x2 { bb 0 0 0 0 0 0 }
0x13 { ffffffff 15 1b 3 0 0 0 }
0x2 { bb 0 0 0 0 0 0 }
0x2 { c6 0 0 0 0 0 0 }
0xd { 3 0 0 0 0 0 0 }
0x1f { 32 0 0 0 0 0 0 }
0x28 { 219 0 64 0 0 0 0 }
0x10 { 3 0 0 0 0 0 0 }
0x1f { 32 0 0 0 0 0 0 }
0xe { ffffffff 3 1 0 0 0 0 }
0x28 { 209 0 64 0 0 0 0 }
0x1f { c8 0 0 0 0 0 0 }
0x2f { a a c8 a 0 0 0 }
0x2 { c6 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x11 { c 1b 65 0 0 0 0 }
0x11 { 14 1b 66 0 0 0 0 }
0x11 { 1d 0 67 0 0 0 0 }
0x3 { 65 1 cb ce 0 0 0 }
0x12 { 1 d 2 0 0 0 0 }
0x13 { ffffffff b 1b 2 0 0 0 }
0x2 { f5 0 0 0 0 0 0 }
0x3 { 66 1 cf d2 0 0 0 }
0x12 { 1 d 2 0 0 0 0 }
0x13 { ffffffff 13 1b 3 0 0 0 }
0x2 { f5 0 0 0 0 0 0 }
0x3 { 67 1 d3 f4 0 0 0 }
0x3 { 1f5 0 d4 f1 0 0 0 }
0x8 { 1f5 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1e { 64 0 0 0 0 0 0 }
0x13 { ffffffff 1d 1 0 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x5 { 1e 2 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x24 { ffffffff 1d 0 1 0 0 0 }
0x28 { 1ff 0 64 0 0 0 0 }
0x32 { ffffffff 0 f 0 0 0 0 }
0x1f { 3e8 0 0 0 0 0 0 }
0x66 { 1d 5 0 0 0 0 0 }
0x2a { 1d 5 0 5dc 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x13 { 0 1d 8 0 0 0 0 }
0x24 { 0 1d 6 1 0 0 0 }
0x25 { 0 0 0 0 0 0 0 }
0x19 { 0 0 1 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
0x2a { 1d 1 0 fa0 0 0 0 }
0x15 { c8 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x5 { 1e 2 1 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x32 { ffffffff ff 1 0 0 0 0 }
0x12 { 1 2 5 0 0 0 0 }
0x13 { ffffffff 1d 1e 0 0 0 0 }
0x66 { ffffffff ffffffff 0 0 0 0 0 }
0x2 { f4 0 0 0 0 0 0 }
0x12 { 1 2 3 0 0 0 0 }
0x13 { ffffffff 1d 1e 0 0 0 0 }
0x2 { f4 0 0 0 0 0 0 }
0x2 { f5 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 f7 f9 0 0 0 }
TEXT { 0 64 0 0 "壁が崩れかかっている。" 16 0 }
0x2 { fb 0 0 0 0 0 0 }
TEXT { 0 64 0 0 "壁が壊れている。" 10 0 }
0x2 { fb 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff8 0 fd 106 0 0 0 }
0x3 { fffffff9 8 fe 105 0 0 0 }
0x8 { fffffff8 0 0 0 0 0 0 }
0x5a { 0 0 0 0 0 0 0 }
0x2c { 1 0 0 0 0 0 0 }
TEXT { 0 64 0 0 "鍵が開いた!" c 0 }
0x28 { 202 0 64 0 0 0 0 }
0x3e { ffffffff 24 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x2 { 106 0 0 0 0 0 0 }
0x2 { 107 0 0 0 0 0 0 }
0x53 { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 10a 112 0 0 0 }
0x6 { 1 16 5 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0xb { 3 14 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 3 14 0 0 0 0 }
0x8 { 107 0 0 0 0 0 0 }
0x2 { 113 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 115 11d 0 0 0 }
0x6 { 2 8 5 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0xb { 1 f 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 1 f 0 0 0 0 }
0x8 { 102 0 0 0 0 0 0 }
0x2 { 11e 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x9 { 65 0 0 0 0 0 0 }
0x11 { 4 b 65 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x3 { 65 1 123 125 0 0 0 }
0x6 { 4 b 5 0 0 0 0 }
0x2 { 127 0 0 0 0 0 0 }
0x6 { 6 b 5 0 0 0 0 }
0x2 { 127 0 0 0 0 0 0 }
0x3 { 108 1 128 12a 0 0 0 }
0xc { 5 b 0 0 0 0 0 }
0x2 { 12c 0 0 0 0 0 0 }
0xb { 5 b 0 0 0 0 0 }
0x2 { 12c 0 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 5 b 0 0 0 0 }
0x3 { 65 1 130 13b 0 0 0 }
0x3 { 11e 1 131 133 0 0 0 }
0x7 { 4 d 0 0 0 0 0 }
0x9 { 11e 0 0 0 0 0 0 }
0x2 { 134 0 0 0 0 0 0 }
0x3 { 105 0 135 138 0 0 0 }
0xb { 3 e 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x41 { 96 3 e 0 0 0 0 }
0x2 { 139 0 0 0 0 0 0 }
0x31 { 4 b 0 0 0 0 0 }
0x2 { 13d 0 0 0 0 0 0 }
0x31 { 6 b 0 0 0 0 0 }
0x2 { 13d 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 13f 142 0 0 0 }
0x6 { 4 d 5 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0x2 { 143 0 0 0 0 0 0 }
0x3 { 105 1 144 148 0 0 0 }
0xc { 3 e 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 3 e 0 0 0 0 }
0x2 { 149 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 14b 156 0 0 0 }
0x6 { 10 f 5 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0xb { d f 0 0 0 0 0 }
0xb { 13 f 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 d f 0 0 0 0 }
0x41 { 96 13 f 0 0 0 0 }
0x8 { 10c 0 0 0 0 0 0 }
0x8 { 110 0 0 0 0 0 0 }
0x2 { 157 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 159 160 0 0 0 }
0x6 { 10 17 5 0 0 0 0 }
0x28 { 1f9 0 64 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0xb { 10 16 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 10 16 0 0 0 0 }
0x2 { 161 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x28 { 1f8 0 64 0 0 0 0 }
0x3 { fffffff7 1 164 167 0 0 0 }
0x7 { 12 15 0 0 0 0 0 }
0x9 { fffffff7 0 0 0 0 0 0 }
0x2 { 16a 0 0 0 0 0 0 }
0x7 { 12 15 e 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0x2 { 16a 0 0 0 0 0 0 }
0x3 { 10d 1 16b 171 0 0 0 }
0x1f { 2bc 0 0 0 0 0 0 }
0xc { 10 11 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 10 11 0 0 0 0 }
0x2 { 177 0 0 0 0 0 0 }
0x1f { 2bc 0 0 0 0 0 0 }
0xb { 10 11 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 10 11 0 0 0 0 }
0x2 { 177 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x28 { 1f8 0 64 0 0 0 0 }
0x3 { fffffff7 1 17a 17d 0 0 0 }
0x7 { 14 2 0 0 0 0 0 }
0x9 { fffffff7 0 0 0 0 0 0 }
0x2 { 180 0 0 0 0 0 0 }
0x7 { 14 2 e 0 0 0 0 }
0x8 { fffffff7 0 0 0 0 0 0 }
0x2 { 180 0 0 0 0 0 0 }
0x3 { 118 1 181 187 0 0 0 }
0x1f { 2bc 0 0 0 0 0 0 }
0xc { 1d 2 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 1d 2 0 0 0 0 }
0x2 { 18d 0 0 0 0 0 0 }
0x1f { 2bc 0 0 0 0 0 0 }
0xb { 1d 2 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x28 { d 0 64 0 0 0 0 }
0x41 { 96 1d 2 0 0 0 0 }
0x2 { 18d 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x28 { 203 0 64 0 0 0 0 }
TEXT { 4 64 0 0 "#6C    忘却の都    ,  世を悲しみ神に背き  , 自らその身を地中に沈め ,   永遠の時を眠る" 61 0 }
0x23 { 1 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x28 { 203 0 64 0 0 0 0 }
TEXT { 4 64 0 0 "#6C 死を恐れぬ者のために ,  この地は存在する  ,    さもなくば    , ここより進まぬが賢明" 64 0 }
0x23 { 1 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x28 { 203 0 64 0 0 0 0 }
TEXT { 3 64 0 0 "#6C   碑石に宿る宝は   , 一帯を踏破せし者にのみ ,    与えられる" 46 0 }
0x23 { 1 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 147 0 1a2 1a5 0 0 0 }
0x8 { 147 0 0 0 0 0 0 }
0x42 { 5 1 0 0 0 0 0 }
0x2 { 1af 0 0 0 0 0 0 }
0x71 { 68 5 0 0 0 0 0 }
0x3 { 68 1 1a7 1a8 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x2 { 1a9 0 0 0 0 0 0 }
0x71 { 69 5 6 0 0 0 0 }
0x3 { 69 1 1ab 1ac 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x2 { 1ad 0 0 0 0 0 0 }
0x42 { 5 1 0 0 0 0 0 }
0x2 { 1af 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0xb { 6 1a 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x15 { 4b 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x9 { 95 0 0 0 0 0 0 }
0x39 { 0 0 0 0 0 0 0 }
0x3b { 15 1 0 0 0 0 0 }
0x3b { 16 1 0 0 0 0 0 }
0x3b { 17 1 0 0 0 0 0 }
0x3b { 1b 1 0 0 0 0 0 }
0x3b { 1c 1 0 0 0 0 0 }
0x3b { 1f 14 0 0 0 0 0 }
0x3b { 20 14 0 0 0 0 0 }
0x3b { 21 14 0 0 0 0 0 }
0x3b { 1 14 0 0 0 0 0 }
0x3b { 3 14 0 0 0 0 0 }
0x3c { ffffffff 0 0 0 "sp_1_01b" 8 0 }
0x3c { 0 0 0 0 " 魔法屋" 8 0 }
0x3c { 1 0 0 0 "いらっしゃい。,ゆっくり見てってね。" 23 0 }
0x3c { 2 0 0 0 "また来てちょうだいね。" 16 0 }
0x3c { 3 0 0 0 "%d GOLDだけど買う?" 13 0 }
0x3c { 4 0 0 0 "どうも、ありがとね。" 14 0 }
0x3c { 5 0 0 0 "お金が足りないようね。" 16 0 }
0x3c { 6 0 0 0 "これ以上持てないんじゃない?" 1c 0 }
0x3c { 7 0 0 0 "%d GOLDでどう?" f 0 }
0x3c { 8 0 0 0 "どうも、ありがとね。" 14 0 }
0x3c { 9 0 0 0 "悪いけど、それは買い取れないね。" 20 0 }
0x3c { a 13 0 0 "br1_tra" 0 0 }
0x56 { 28 64 0 0 0 0 0 }
0x3a { 0 0 0 0 0 0 0 }
0x3d { 0 0 0 0 0 0 0 }
0x56 { a 64 0 0 0 0 0 }
0xc { 6 1a 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x16 { 32 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0xa { 6 1a 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 95 0 1d7 1db 0 0 0 }
0x8 { 95 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "また新しいのが来たね。,今度は兄さんか。#K#Dあんたも気が付いたら,ここにいたってクチだろ?,ま、大抵みんなそんなもんさ。#K#Dそういえばさっき,裸みたいな格好した姉さんが、,男を捜してるって言ってたっけ。#K#D察するにあんたのことだろ?,ふふ、色男はつらいね。#K#Dでもね、気を付けた方がいいよ。#K#Dあのお姉さん、ここで,けっこうゴッツイ攻撃魔法用の,杖を買っていったからね。#K#Dどんな事情かは知らないけど、,今度会ったらすぐにでも,謝った方がいいよ。#K#D焼かれて、炭になった後じゃ,遅いからね。#K#Dあっ、そうそう。,近くにある泉には行ってみたかい。#K#Dあの水のおかげで,あたし達は生きていられるのさ。#K#D聞いた話だと、,この世界はとてつもない,エネルギーの塊らしいからね。#K#D何が起こっても不思議は無いのさ。,まあ、せいぜい,気を付けて行くんだね。#K" 2d9 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 1de 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "あのお姉さんの様子からするに、,どうやらあんた相当な,うらみを買ってるみたいだね。#K#Dどんな事情かは知らないけど、,今度会ったらすぐにでも,謝った方がいいよ。#K#D焼かれて、炭になった後じゃ,遅いからね。#K" c7 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 1de 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0xb { b 18 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x15 { 4b 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x9 { 95 0 0 0 0 0 0 }
0x39 { 0 0 0 0 0 0 0 }
0x3b { 3d a 0 0 0 0 0 }
0x3b { 3d 14 0 0 0 0 0 }
0x3b { 3e 1e 0 0 0 0 0 }
0x3b { 41 32 0 0 0 0 0 }
0x3b { 51 1 0 0 0 0 0 }
0x3b { 47 1 0 0 0 0 0 }
0x3b { 5 a 0 0 0 0 0 }
0x3b { 6 14 0 0 0 0 0 }
0x3c { ffffffff 0 0 0 "sp_1_01c" 8 0 }
0x3c { 0 0 0 0 " 武器屋" 8 0 }
0x3c { 1 0 0 0 "いらっしゃい。" e 0 }
0x3c { 2 0 0 0 "またな。" 8 0 }
0x3c { 3 0 0 0 "%d GOLDだが、買うか?" 15 0 }
0x3c { 4 0 0 0 "すまんね。" a 0 }
0x3c { 5 0 0 0 "金が足らないようだな。" 16 0 }
0x3c { 6 0 0 0 "荷物が一杯のようだな。" 16 0 }
0x3c { 7 0 0 0 "%d GOLDでどうだ?" 11 0 }
0x3c { 8 0 0 0 "すまんね。" a 0 }
0x3c { 9 0 0 0 "そいつは引き取れないな。" 18 0 }
0x3c { a 15 0 0 "br1_tra" 0 0 }
0x56 { 28 64 0 0 0 0 0 }
0x3a { 0 0 0 0 0 0 0 }
0x3d { 0 0 0 0 0 0 0 }
0x56 { a 64 0 0 0 0 0 }
0xc { b 18 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x16 { 32 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0xa { b 18 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 95 0 204 208 0 0 0 }
0x8 { 95 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "あんた新顔のようだが、,この世界で生きのびたいのなら,何もしない方がいいぜ。#K#Dもしくは、俺のように暇潰しに,武器でも集めて商売することだ。#K#Dこれでけっこう人が来るんだよ。,あんたみたいのがね。#K#D俺は仲間と一緒に落っこちて来たが,今はもう俺しかいない。#K#Dあとのやつらは皆死んだよ。,ここから出ようとしたからだ。#K#D悪いことは言わねえから、,あんたも俺の様に,じっとしているこった。#K#Dこんな所でもな、,住んじまえば都ってもんさ。#K" 1ab 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 20b 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "悪いことは言わねえから、,あんたも俺の様に,じっとしているこった。#K#Dこんな所でもな、,住んじまえば都ってもんさ。#K" 71 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 20b 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0xb { e 12 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x15 { 4b 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x9 { 95 0 0 0 0 0 0 }
0x39 { 0 0 0 0 0 0 0 }
0x3b { 5 3 0 0 0 0 0 }
0x3b { 6 5 0 0 0 0 0 }
0x3b { 1 8 0 0 0 0 0 }
0x3b { 3 5 0 0 0 0 0 }
0x3b { 3d 6 0 0 0 0 0 }
0x3b { 46 1 0 0 0 0 0 }
0x3b { 47 1 0 0 0 0 0 }
0x3c { ffffffff 0 0 0 "sp_1_01a" 8 0 }
0x3c { 0 0 0 0 " 道具屋" 8 0 }
0x3c { 1 0 0 0 "いらっしゃい。" e 0 }
0x3c { 2 0 0 0 "またお越し下され。" 12 0 }
0x3c { 3 0 0 0 "%d GOLDだが買うかね?" 15 0 }
0x3c { 4 0 0 0 "どうもすまないね。" 12 0 }
0x3c { 5 0 0 0 "お金が足りないね。" 12 0 }
0x3c { 6 0 0 0 "荷物が一杯のようだね。" 16 0 }
0x3c { 7 0 0 0 "%d GOLDでどうかね?" 13 0 }
0x3c { 8 0 0 0 "どうもすまないね。" 12 0 }
0x3c { 9 0 0 0 "それは買い取れないね。" 16 0 }
0x3c { a 17 0 0 "br1_tra" 0 0 }
0x56 { 28 64 0 0 0 0 0 }
0x3a { 0 0 0 0 0 0 0 }
0x3d { 0 0 0 0 0 0 0 }
0x56 { a 64 0 0 0 0 0 }
0xc { e 12 0 0 0 0 0 }
0x28 { 1f4 0 64 0 0 0 0 }
0x16 { 32 0 0 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0xa { e 12 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 95 0 230 234 0 0 0 }
0x8 { 95 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "あんたも落ちて来たんだね。,あたしの所に来た客は、,あんたで42人目だよ。#K#Dヒッヒッヒッ……,42人(死人)目とは悪かったね。#K#Dでも、風の噂じゃみんな,本当の死人になったらしいよ。#K#Dヒッヒッ、,そんな恐い顔で見なさんなよ。,哀れなババァだぁよ。#K#Dお詫びに,いいこと教えてあげるから、,機嫌を直しておくれよ。#K#Dあんた、ここへ来る途中に,崩れかけた壁を見ただろ?#K#Dあの壁は脆いから、,この大金槌で叩いてやれば,きっと崩れるよ。#K#Dそうそう、こんなのもあるよ。,ただの鉄の玉だけどさ。#K#Dここいら辺には,落し穴が沢山あるから、,こいつを使って床を調べるのさ。#K#D便利なもんだろ?,ささ、どれを買いなさる。#K" 255 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 237 0 0 0 0 0 0 }
TEXT { 5 0 0 0 "崩れかけた壁は、,この大金槌で叩いてやれば,きっと崩れるよ。#K#Dそんでもって,この鉄の玉を使えば、,落し穴のある床が分かるのさ。#K#D便利なもんだろ?,ささ、どれを買いなさる。#K" ab 0 }
0x23 { 2 0 0 0 0 0 0 }
0x2 { 237 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 1f5 0 239 24e 0 0 0 }
0x8 { 1f5 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1e { 64 0 0 0 0 0 0 }
0x13 { ffffffff 1d 2 0 0 0 0 }
0x24 { ffffffff 1d 0 1 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x2a { 0 1 0 1 0 1 0 }
0x17 { 0 0 0 0 0 0 0 }
0x2a { 1d 4 0 7d0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x13 { 0 1d 8 0 0 0 0 }
0x24 { 0 1d 5 1 0 0 0 }
0x25 { 0 0 0 0 0 0 0 }
0x19 { 0 0 1 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
0x2a { 1d 0 0 1388 0 0 0 }
0x15 { c8 0 ff 0 0 0 0 }
0x17 { 0 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x12 { 1 2 3 0 0 0 0 }
0x13 { ffffffff 1d 1e 0 0 0 0 }
0x2 { 24f 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { 1f3 0 251 276 0 0 0 }
0x1f { 1f4 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1f { 2bc 0 0 0 0 0 0 }
0x1e { c8 0 0 0 0 0 0 }
0x13 { ffffffff 10 14 3 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x2a { 2 0 fffffffe 1 0 1 0 }
0x17 { 0 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x21 { 0 e0 fffffff6 64 "p_011a" 7 0 }
0x37 { 0 0 0 0 0 0 0 }
character-name { 0 0 0 0 "傭兵風の男" b 0 }
TEXT { 1 64 0 0 "痛っ……俺としたことが……" 1a 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "ん……なんだお前は……?,お前も、財宝目当てで,この遺跡に迷い込んだのか……?" 4c 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "何? 地面に穴が開いて落ちただと?,くっくっ、間抜けな野郎だ……" 3f 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "……まあいい。,欲に目がくらんでねえ分、,俺よりはマシなようだからな。" 44 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "一言だけ忠告しておいてやる。,いいか、ここは恐ろしい場所だ。" 3b 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "お前も命が惜しけりゃ、,常に冷静になって行動することだ……" 39 0 }
0x23 { 0 0 0 0 0 0 0 }
0x19 { 1 2 1 0 0 0 0 }
0x8 { 1f3 0 0 0 0 0 0 }
0x50 { 0 0 0 0 0 0 0 }
0x36 { ff ff 0 64 0 ff0000 0 }
0x37 { 0 0 0 0 0 0 0 }
0x1f { 12c 0 0 0 0 0 0 }
0x1e { 64 0 0 0 0 0 0 }
0x13 { ffffffff 10 14 0 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x17 { 0 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x1f { 1e 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x2 { 277 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x1d { 1 0 0 0 0 0 0 }
0x1f { 1f4 0 0 0 0 0 0 }
0x1e { 64 0 0 0 0 0 0 }
0x13 { ffffffff 10 14 3 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x2a { 2 0 fffffffe 1 0 1 0 }
0x17 { 0 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x21 { 0 e0 fffffff6 64 "p_011a" 7 0 }
0x37 { 0 0 0 0 0 0 0 }
character-name { 0 0 0 0 "傭兵風の男" b 0 }
0x3 { 8d 0 284 28e 0 0 0 }
TEXT { 1 64 0 0 "ここは一体どこなのか、,このボロ臭い遺跡が何なのか……,そんな事は誰も知らん。" 4c 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "ただ一つはっきりしているのは、,ここが一瞬でも気を抜けば,死に繋がる、危険な場所だって事だ。" 5a 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "チッ……,俺もどうして、こんな地の底まで,やって来ちまったんだかな。" 42 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "くっく、まったく……,人間の欲ってのは罪深い……" 2f 0 }
0x23 { 0 0 0 0 0 0 0 }
0x8 { 8d 0 0 0 0 0 0 }
0x2 { 295 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "傷が痛むんでな、,しばらく休ませてくれ。" 27 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "……それと、お前も………,この世界から出ようなんざ考えるなよ。" 3d 0 }
0x23 { 0 0 0 0 0 0 0 }
TEXT { 1 64 0 0 "それこそ、夢物語ってやつだぜ……" 20 0 }
0x23 { 0 0 0 0 0 0 0 }
0x2 { 295 0 0 0 0 0 0 }
0x50 { 0 0 0 0 0 0 0 }
0x36 { ff ff 0 64 0 ff0000 0 }
0x37 { 0 0 0 0 0 0 0 }
0x1e { 32 0 0 0 0 0 0 }
0x2a { 0 0 0 0 0 2 0 }
0x17 { 0 0 0 0 0 0 0 }
0x2b { 0 0 0 0 0 0 0 }
0x1d { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff7 0 29f 2a1 0 0 0 }
TEXT { 0 64 0 0 "ひび割れた碑石がある。" 16 0 }
0x2 { 2a3 0 0 0 0 0 0 }
TEXT { 0 64 0 0 "碑石が壊れている。" 12 0 }
0x2 { 2a3 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x3 { fffffff9 5 2a5 2bd 0 0 0 }
0x3 { 146 0 2a6 2ba 0 0 0 }
0x7f { 64 0 0 0 0 0 0 }
0x3 { 64 1 2a8 2b0 0 0 0 }
0x2c { 1 0 0 0 0 0 0 }
0x8 { 146 0 0 0 0 0 0 }
0x7 { 1c 3 1 0 0 0 0 }
0x5 { 1c 3 0 0 0 0 0 }
0x42 { 1 a 0 0 0 0 0 }
0x27 { 8de 1c 3 0 0 0 0 }
0x28 { 1f7 0 64 0 0 0 0 }
0x2 { 2b9 0 0 0 0 0 0 }
0x3 { 8b 0 2b1 2b6 0 0 0 }
0x8 { 8b 0 0 0 0 0 0 }
0x27 { 1 1c 3 0 0 0 0 }
0x28 { 66 0 64 0 0 0 0 }
TEXT { 0 64 0 0 "何かの力によって、,大金槌が跳ね返された。" 29 0 }
0x2 { 2b8 0 0 0 0 0 0 }
TEXT { 0 64 0 0 "壊せそうだが、,何かの力によって護られている。" 2d 0 }
0x2 { 2b8 0 0 0 0 0 0 }
0x2 { 2b9 0 0 0 0 0 0 }
0x2 { 2bc 0 0 0 0 0 0 }
TEXT { 0 64 0 0 "ここは壊せない!" 10 0 }
0x2 { 2bc 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }
0x2 { 2be 0 0 0 0 0 0 }
0x53 { 0 0 0 0 0 0 0 }
0x1 { 0 0 0 0 0 0 0 }

The more opcodes you can figure out, you can replace them with actual names to make things easier to read/edit. Now I just need to take that and try to firstly get back an identical file, and then work on having it update stuff properly if the size changes.

EDIT:

Woohoo, did it. Got it all recompiled and it works perfectly. So now you can just add and change whatever you want and it'll work, provided you at least stick to the format and the correct parameter count etc.

So I added in 6 brand new opcodes:

orig:
TEXT { 7 5a 0 0 "どれほどの時間が経っただろうか。" 20 0 }
wait-for-input { 0 0 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
TEXT { 0 78 0 0 "……幸いな事に、,命を落さずに済んだようだ。" 2b 0 }
wait-for-input { 0 0 0 0 0 0 0 }

new:
TEXT { 7 5a 0 0 "Adding a new string in for ourselves right here." 20 0 }
wait-for-input { 0 0 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
TEXT { 1 5a 0 0 "Adding a second new string in for ourselves right here, let's not make it a yes/no box." 20 0 }
wait-for-input { 0 0 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
TEXT { 7 5a 0 0 "どれほどの時間が経っただろうか。" 20 0 }
wait-for-input { 0 0 0 0 0 0 0 }
0x1f { 7d0 0 0 0 0 0 0 }
TEXT { 0 78 0 0 "……幸いな事に、,命を落さずに済んだようだ。" 2b 0 }
wait-for-input { 0 0 0 0 0 0 0 }

And when put back in the game:

YHf1LGj.jpg

NvHMRbb.jpg

So it's very easy to edit I think. You can just change some variables and see what they do. Like I said earlier, 0x4 is our text (I replaced it with TEXT in the dump), and its first variable controls what sort of text it is. I made one with it as 7, a yes/no box, then a second with it as 1, our standard "press the o button to continue" text.

The only really major problem remaining I think are the 03 opcodes. Because they have their start/end block hard-coded, they have to be updated properly for you to add more codes, otherwise you'll just get infinite looping code. Not sure how to best solve that really. I don't really want to essentially copy my whole dumping code again as a part of the recompiler... Hmm...
 

G-Han

Well-Known Member
OP
Newcomer
Joined
Feb 17, 2009
Messages
64
Trophies
0
XP
204
Country
Netherlands
Superb work, Kelebek. I don't understand the technical tidbits, but the screenshots look very promising.

Looks like there's space for 40 characters on a single line up to three lines per text box (two with Yes/No question). Great to see how virtually all Falcom games make use of the same font.
 

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
EDIT:

Ok, mega fixed: http://pastebin.com/MtGMZwcA - For python 2.7

It now handles all inserting and removing, so you can add or remove as much as you want. Figured out the tables so you don't need to change anything per file either. Also added a lot more opcodes so you can hopefully get the other files, may be a few missing, but you can just add them like the others. All opcodes are 0x20 bytes after all.

Rename your original script to add ".orig" and then you can run it just like before. "script.py filename.orig -e" to extract, and "script.py filename.data -i" to recompile.

About specific editing of the data: You can remove lines without problem, if you want to get rid of an opcode just delete the line.

To add lines though, you need to add them so that they start with the { and NOT a number. For example:

function_29e --- length: 6
{
29e { jmpcond fffffff7 0 29f 2a1 0 0 0 }
29f { text 0 64 0 0 "ひび割れた碑石がある。" 16 0 }
2a0 { jmp 2a3 0 0 0 0 0 0 }
2a1 { text 0 64 0 0 "碑石が壊れている。" 12 0 }
2a2 { jmp 2a3 0 0 0 0 0 0 }
2a3 { retn 0 0 0 0 0 0 0 }
}

If you wanted to add a few text lines to this, they'd need to look like:

function_29e --- length: 6
{
29e { jmpcond fffffff7 0 29f 2a1 0 0 0 }
29f { text 0 64 0 0 "ひび割れた碑石がある。" 16 0 }
{ text 0 64 0 0 "Line 1 added here." 16 0 }
2a0 { jmp 2a3 0 0 0 0 0 0 }
2a1 { text 0 64 0 0 "碑石が壊れている。" 12 0 }
{ text 0 64 0 0 "Line 2 added here." 12 0 }
2a2 { jmp 2a3 0 0 0 0 0 0 }
2a3 { retn 0 0 0 0 0 0 0 }
}

If you leave the number at the start of the line you'll break the recompile, so just make sure the lines you add to the script begin with the {. You don't need to do anything special for editing lines. You don't need to touch that length at the start of of the function or anything either, I don't even use it.

So now you can fully and easily translate the game text. I look forward to one. :)
 

G-Han

Well-Known Member
OP
Newcomer
Joined
Feb 17, 2009
Messages
64
Trophies
0
XP
204
Country
Netherlands
Fantastic!

Admittedly, due to my lack of experience with scripts, it took me some trial and error to get the python script running and to convert the .scp to .data, but I eventually succeeded. Looks great man, excellent work.

How should we going to proceed from here? Are you still working on a tool (around Kelebek's script), neoxephon? Or is there a way for me to directly inject the .scp's back in the game?
 

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
Yeah, you can directly import it back in, very easily. Firstly, you need to get the data.lst file which is in the game's USR dir. Then, you'll need to open it up in a hex edit, and find the entry for the file you've edited. The variable at 0x8 (basically it's what's right after the filename) is the size of the file, so you need to change that to match the size of your new script file. After you've done that, just put your fixed data.lst into the game, and overwrite the old script your new one, and done.

For reimporting with UMDGen though, I had to enforce the file positions every time, a cut-down iso always crashed the game for me.

A bit more on the data.ls front if you need it:

Goto (ctrl+g usually) 3f80

You should see in the text window that this position starts with "script." That's the folder name of what we want to edit, and then you can see below it, that every 0x10 bytes has a new filename, and it lists all the files in the script folder.

So say you edited mp1_01.scp, well that's directly under "script," it's our first file. So from where "mp1_01" starts, if you go 0x8 bytes, the value EE80 is there right? That's the one we need to change, and it's in the same position for every file, 0x8 bytes after the start of the filename.

So the file is little endian, meaning to get the actual value you need to reverse the numbers. So say for instance, the size of your new mp1_01 file is 32778 bytes in decimal, as reported by viewing a file's properties in Windows. So open Windows' calculator, and go to View > Programmer. On the left should be a radio button for Hex and Dec. Put in your filesize with Dec selected, and then just select Hex, and it'll give you your filesize in hex. So 32778 becomes 800A. Now to get that back into the data.lst, you just need to reverse the bytes in 2s (so 80 0a to 0a 80). Then in your data.lst, overwrite that EE80 with 0A80 (or whatever your filesize is), and that's it.
 

flame1234

Well-Known Member
Member
Joined
May 17, 2009
Messages
734
Trophies
0
XP
957
Country
United States
I was able to use the extractor. No idea how it was developed. I feel like I just took the "how to walk" tutorial in your favorite videogame.

How to run Python script (Windows).
1) Install python
2) At the command prompt: python script.py

Also I was having trouble viewing the Japanese content of the output file. I ended up succeeding with JWPce.

Now it is time to talk about doing the project. Which script file should be worked on first so we can test insert it?
There are 46 script files. There are 8 text tables. There are 25 ITP files but I'm not sure how many of them need modifying. I posted the text contents of mp1_01.scp here. Not sure if that was useful.

I could use advice on crowd-source translation wikis. We can probably use that one but there must be better ones out there. I think the project will go faster if we have multiple translators working on it. I'm new if you couldn't tell.
 

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
mp1_14 is the tutorial, mp1_01 is the first level, I mainly used mp1_01, but either work for testing stuff as they're both equally easy to access.

With the output, if you have Notepad++, just go Encoding > Character Sets > Japanese > SHIFT-JIS and it'll display the strings properly.
 

G-Han

Well-Known Member
OP
Newcomer
Joined
Feb 17, 2009
Messages
64
Trophies
0
XP
204
Country
Netherlands
That explanation was certainly helpful and taught me a lot about the files, yet iso still keeps crashing on me. Allow me to retrace my steps:

1. Exported mp1_01 using your Python script, translated a line (replaced "どれほどの時間が経っただろうか。" with "I wonder how much time had passed.") and imported it with the Python script again. The new file size is 32,780 bytes, which is 800C in hex. Renamed the file to "mp1_01.scp" again.

2. Using UMDGen to open data.lst, I modified 3f90 by replacing EE80 with 0C80 to match the new file size. I saved it as "data.lst" locally and then used UMDGen to reinsert the data.lst again.

3. Used UMDGen to import the new "mp1_01.scp" in the /script folder.

4. Saved the game as .iso, opened it in PPSSPP and it crashes.

I did note that when importing files, the file size drops from 385.50 Mb to 284.10 Mb. Other than that, I followed your guide faithfully - apart from, and I think this is where it's going wrong, I don't know how to "enforce file positions".
 

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
Yeah, that crashes the game, the filesize being cut.

Open up the original game, and in UMDGen go to File > File List > Export. You only need to do this once.

Then add in your changed files, and every time you want to save the iso, go to File > File List > Import, and find that original list. Choose yes to forcing the file positions, and then save it uncompressed. It should keep the original size and not crash.
 
  • Like
Reactions: G-Han and GHANMI

G-Han

Well-Known Member
OP
Newcomer
Joined
Feb 17, 2009
Messages
64
Trophies
0
XP
204
Country
Netherlands
Great, thanks a lot man! It works like a charm.

IAVhE21.jpg

Final question (I think): is there a way for me to use commas? Right now, they're being used to start a new line.
 
  • Like
Reactions: GHANMI

Kelebek

Well-Known Member
Member
Joined
May 25, 2012
Messages
165
Trophies
0
XP
156
Country
Oh err, I didn't end up looking into that. That's sort of beyond my ability I think, I don't know anything about font editing, and to change the character from comma to something else with would require ASM hacking.

But on page 2 omarrrio already found a solution for it, so I didn't think I really needed to fix it if he's been able to edit the font to get it working. So I'd say look into editing the font, or ask omarrrio to explain how he did it. :D
 
  • Like
Reactions: G-Han

GHANMI

Well-Known Member
Member
Joined
Jun 10, 2012
Messages
969
Trophies
0
XP
914
Country
While you're at it, you could also check if that tool works as well on the scripts for Nayuta no Kiseki. (and G-Han could take a look on it as well whenever he's interested... even though it's MASSIVE)
The one translation project on that one got cancelled because of "technical issues", and since the text is similar it would be a shame not to expand the tool's functionality to include it as well. I wrote years ago an article about it on tcrf, about an internal file forgotten there by Falcom which details exactly what each map script file is for (0000 is for example for the center of the village in Lost Haven, the "hub" of the game).
 

Attachments

  • Nayuta script.rar
    1.1 MB · Views: 308

GHANMI

Well-Known Member
Member
Joined
Jun 10, 2012
Messages
969
Trophies
0
XP
914
Country
About the comma... I guess I should make myself useful for once in this thread :P
Here is a pspfont (extracted from Nayuta no Kiseki, but since they are identical...) where I redraw the @ character (you shouldn't need it, right?) with a "comma+space".
Try if it works when you just write @ instead of a comma in the text.

I can easily affirm just from a rapid peek at the font that all Falcom games on the PSP are variable width and the values have to be stored somewhere (... could be in the font itself, even).
 

Attachments

  • pspfont.rar
    297.7 KB · Views: 227

GHANMI

Well-Known Member
Member
Joined
Jun 10, 2012
Messages
969
Trophies
0
XP
914
Country
The scripts in there are ENTIRELY different to these ones, they're not similar at all lol. So yeah, I'm really not sure about those, sorry.

I figured it wouldn't be that easy :P
Well, hopefully someone has a look on that one eventually (other than it using 0A as a breakline, and it accepting ascii English characters... the volume of the text makes it not the type of the game where I just hex edit the text inside like I usually do), but let's enjoy what we have here :)
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    LeoTCK @ LeoTCK: hmm