ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Mon Jul 13, 2020 6:10 am

All times are UTC




Post new topic  Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Sun Jun 07, 2020 5:51 pm 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
Hello, I'm trying to translate Zero Escape The Nonary Games but have some problems.

I extracted .sir files from ze1_data.bin, and making any change of data size cause errors in game.

Of course, I used reimport2.bat for reimporting the sir files and adjusted their offsets.

Also, I checked just that exchanging a word is fine. (door -> dddd is printed well)

I don't know what the problem is. Please give some help.
(And what is the 5-byte data at the end of offsets?)


Attachments:
File comment: sir files with text
sir.zip [555.42 KiB]
Downloaded 20 times
Top
   
PostPosted: Tue Jun 09, 2020 10:21 pm 

Joined: Wed Apr 17, 2019 4:03 pm
Posts: 8
search old posts. i've explained why reimport2 is not working well.
For some kind of files, you also need to modify the last few bytes which contains a 7-bit encoded (check variable-length quantity on wikipedia) data size.
It has been a while since i finished the localization for my language so i need to check my codes for details if you need.
All questions are welcome :D


Top
   
PostPosted: Wed Jun 10, 2020 12:06 pm 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
haibaer wrote:
search old posts. i've explained why reimport2 is not working well.
For some kind of files, you also need to modify the last few bytes which contains a 7-bit encoded (check variable-length quantity on wikipedia) data size.
It has been a while since i finished the localization for my language so i need to check my codes for details if you need.
All questions are welcome :D


Thank you for the answer. I learned the variable-length quantitiy but still have some question.

A file name is 00009f13.sir and [04 08 84 A8 78] is on the last.

I thought [84 A8 78] designates the file size and changed it to binary number.

1000 0100
1010 1000
0111 1000

-> 100 010 1000 111 1000 = 70776(dec) = 0x14478

but the file size is 102KB (105,264 Bytes). I don't know what's going on.

And second, how did you change the fonts to your language?

Thanks again.


Top
   
PostPosted: Thu Jun 11, 2020 6:07 am 

Joined: Wed Apr 17, 2019 4:03 pm
Posts: 8
00009f13.sir contains script texts.
0x00 - 0x03: SIR1
0x04 - 0x07: start offset of text index table(0001147C)
0x08 - 0x0B: 0
0x0B - 0x0F: end offset of text index table
0x10 - 0x13: 0
0x14 - 0001147B: texts
0001147C : text index table
...

Each entry of the text index table is a 8-byte absolute offset of the file and each text is a 0-terminated string:
0x00000014: M10a_050_010_02_10
0x00000027: Talk
...
...

If your final script text won't exceed the original size, you can simply modify the index table, adjust the offset of each text item, and fill the rest part of texts with zero.(No need to use reimport2, and I believe aluigi has already provided a bms script to do this automatically)
If not, you need to modify the 7-bit encoded data.

04 -> the first 4-byte of the file
08 -> next 8 bytes
84 A8 70 -> 0x11470 next 0x11470 bytes (to the start offset of text index table)
08 08 08 08 ...... -> Each '08' corresponds to an text index table entry.

00009ec1.sir is a font file, you need to modify these font files if your language contains non-ascii characters. They are stored as 8-bit grayscale bitmaps.


Top
   
PostPosted: Thu Jun 11, 2020 10:10 am 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
haibaer wrote:
00009f13.sir contains script texts.
0x00 - 0x03: SIR1
0x04 - 0x07: start offset of text index table(0001147C)
0x08 - 0x0B: 0
0x0B - 0x0F: end offset of text index table
0x10 - 0x13: 0
0x14 - 0001147B: texts
0001147C : text index table
...

Each entry of the text index table is a 8-byte absolute offset of the file and each text is a 0-terminated string:
0x00000014: M10a_050_010_02_10
0x00000027: Talk
...
...

If your final script text won't exceed the original size, you can simply modify the index table, adjust the offset of each text item, and fill the rest part of texts with zero.(No need to use reimport2, and I believe aluigi has already provided a bms script to do this automatically)
If not, you need to modify the 7-bit encoded data.

04 -> the first 4-byte of the file
08 -> next 8 bytes
84 A8 70 -> 0x11470 next 0x11470 bytes (to the start offset of text index table)
08 08 08 08 ...... -> Each '08' corresponds to an text index table entry.

00009ec1.sir is a font file, you need to modify these font files if your language contains non-ascii characters. They are stored as 8-bit grayscale bitmaps.



I've tried it and still the error comes out. :(

Could you check my 00009f13.sir file? (I changed the last text 'door' to 'dooooor' so that the offset table still works.)

Or just give me your localization files, then i'll check it.


Attachments:
00009f13.zip [27.63 KiB]
Downloaded 8 times
Top
   
PostPosted: Fri Jun 12, 2020 12:35 am 

Joined: Wed Apr 17, 2019 4:03 pm
Posts: 8
sorry but i did the whole work based on the japanese version so i didn't modify 00009f13.sir.

Here are the possible reasons why your file is not working:
1. AA AA AA at the end of the texts is used to keep the whole address things 4 bytes aligned. you can add one more 'o' to keep the alignment.
2. you've added 5 'o's so 84 a8 70 should now be 84 a8 75, not 84 a8 73.
3. maybe the offset and new file size are not corrected after reimort2.

I also uploaded my 0000119d.sir, a font file that I've modified both the contents and the file size. hope this could help.

I'll test your file on the english version on the weekend if you still have problem :)


Attachments:
0000119d.zip [332.38 KiB]
Downloaded 16 times
Top
   
PostPosted: Fri Jun 12, 2020 3:12 am 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
haibaer wrote:
sorry but i did the whole work based on the japanese version so i didn't modify 00009f13.sir.

Here are the possible reasons why your file is not working:
1. AA AA AA at the end of the texts is used to keep the whole address things 4 bytes aligned. you can add one more 'o' to keep the alignment.
2. you've added 5 'o's so 84 a8 70 should now be 84 a8 75, not 84 a8 73.
3. maybe the offset and new file size are not corrected after reimort2.

I also uploaded my 0000119d.sir, a font file that I've modified both the contents and the file size. hope this could help.

I'll test your file on the english version on the weekend if you still have problem :)


Thank you!! I tried the first solution(adjust number of AA AA AA to keep the alignment) and it works!!

No more error occurs. Have a nice weekend!


Top
   
PostPosted: Sat Jun 13, 2020 10:54 am 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
Me again.
I reimported your font file and it did't work in japanese mode.

So I have two questions.
1. How did you change the characters? Did you use Python or crystaltiles2?(I'm trying to with crystaltile2 but it's difficult)

2. What are the offsets in the font files? They are pointing middle of a character(so I cant insert more characters)

sorry for many questions. I really want to localize this game. Thank you.


Top
   
PostPosted: Wed Jun 17, 2020 5:05 am 

Joined: Wed Apr 17, 2019 4:03 pm
Posts: 8
zkdldk95 wrote:
Me again.
I reimported your font file and it did't work in japanese mode.

So I have two questions.
1. How did you change the characters? Did you use Python or crystaltiles2?(I'm trying to with crystaltile2 but it's difficult)

2. What are the offsets in the font files? They are pointing middle of a character(so I cant insert more characters)

sorry for many questions. I really want to localize this game. Thank you.


I didn't use crystaltiles2.
The index table of the font files uses a relative offset (and divide by 2).
Here's my python code to modify the font file (000011a4.sir). hope this could help.
(The 7-bit encoded part is almost the same as other files If you need modify it.)

Code:
# @brief modify font files so that the game contains our own fonts.
def modify_fonts():
    fin = open('4.sir', 'rb')
    fout = open('000011a4.sir', 'wb')
    rel_poses = []
    old_file = fin.read()
    start = 0
    num = len(CN_ALL_CHAR)
    end = start + num * 4 + 20
    fout.write(b'\x53\x49\x52\x31')
    fout.write(start.to_bytes(8, byteorder='little'))
    fout.write(end.to_bytes(8, byteorder='little'))
    cur_pos = 20

    chs = list(ENCODE_TABLE.keys())
    chs.sort(key = sort_byte)

    for ch in chs:
        rel_poses.append(cur_pos)
        img = to_font(ch, 'fonts', 26)
        fout.write(img)
        cur_pos = cur_pos + len(img)
        if cur_pos % 4 != 0:
            pad = bytearray(cur_pos % 4)
            pad = pad.replace(b'\x00', b'\xaa')
            fout.write(pad)
            cur_pos = cur_pos + cur_pos % 4
   
    # update start and end position
    start = cur_pos
    end = start + num * 4 + 20

    fout.write(num.to_bytes(8, byteorder='little'))
    fout.write((0x0000001b).to_bytes(4, byteorder='little'))
    fout.write((0x00000014).to_bytes(4, byteorder='little'))
    fout.write((0x00000000).to_bytes(4, byteorder='little'))
    for rel in rel_poses:
        fout.write(int((rel - 0x14) / 2).to_bytes(4, byteorder='little'))           # <- the offset
    tab_pad = (16 - (start + 20 + 4 * num) % 16) % 16
    pad = bytearray(tab_pad)
    pad = pad.replace(b'\x00', b'\xaa')
    fout.write(pad)

    fout.write(old_file[-16:])
    fin.close()
    fout.close()
   


Top
   
PostPosted: Fri Jun 19, 2020 7:19 pm 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
haibaer wrote:

Code:
# @brief modify font files so that the game contains our own fonts.
def modify_fonts():
    fin = open('4.sir', 'rb')
    fout = open('000011a4.sir', 'wb')
    rel_poses = []
    old_file = fin.read()
    start = 0
    num = len(CN_ALL_CHAR)
    end = start + num * 4 + 20
    fout.write(b'\x53\x49\x52\x31')
    fout.write(start.to_bytes(8, byteorder='little'))
    fout.write(end.to_bytes(8, byteorder='little'))
    cur_pos = 20

    chs = list(ENCODE_TABLE.keys())
    chs.sort(key = sort_byte)

    for ch in chs:
        rel_poses.append(cur_pos)
        img = to_font(ch, 'fonts', 26)
        fout.write(img)
        cur_pos = cur_pos + len(img)
        if cur_pos % 4 != 0:
            pad = bytearray(cur_pos % 4)
            pad = pad.replace(b'\x00', b'\xaa')
            fout.write(pad)
            cur_pos = cur_pos + cur_pos % 4
   
    # update start and end position
    start = cur_pos
    end = start + num * 4 + 20

    fout.write(num.to_bytes(8, byteorder='little'))
    fout.write((0x0000001b).to_bytes(4, byteorder='little'))
    fout.write((0x00000014).to_bytes(4, byteorder='little'))
    fout.write((0x00000000).to_bytes(4, byteorder='little'))
    for rel in rel_poses:
        fout.write(int((rel - 0x14) / 2).to_bytes(4, byteorder='little'))           # <- the offset
    tab_pad = (16 - (start + 20 + 4 * num) % 16) % 16
    pad = bytearray(tab_pad)
    pad = pad.replace(b'\x00', b'\xaa')
    fout.write(pad)

    fout.write(old_file[-16:])
    fin.close()
    fout.close()
   


It is difficult to understand a little bit but it's ok.

I wonder how can I change a font to byte arrays. ("to_font" in your code might has that function)

I hope this is the last question...

Thanks a lot.


Top
   
PostPosted: Sat Jun 20, 2020 8:12 am 

Joined: Wed Apr 17, 2019 4:03 pm
Posts: 8
The font file uses 8-bit grayscale bitmaps.
You can generate grayscale bitmaps from ttf/otf fonts using any font engine. For me I use freetype. (You can use the Pillow library if you are using python).
Here is the structure of each glyph in the font file:

Shift-JIS encoding of that glyph (2 bytes) (Note: the game uses binary search to find the right glyph, so this encoding value should always be in increasing order.)
0x00 (4 bytes)
width of the glyph (1 byte)
height of the glyph (1 byte)
width of the border glyph (1 byte) (a larger bitmap used to draw borders, you can use the same glyph if you don't need border)
height of the border glyph (1 byte)
the glyph (a width * height grayscale bitmap)
the border glyph (a (width of the border glyph) * (height of the border glyph) grayscale bitmap)

Here's the source code of to_font, which may looks confusing too...
Code:
def to_font(ch, fontpath, height):
    enc = ENCODE_TABLE[ch]
    uni_idx = ord(ch)
    ret = bytearray()

    # read font bitmap
    fin = open(fontpath + '/' + str(uni_idx) + '.txt', 'rb')    # I generated the bitmaps and stored them to a text file.
    img = fin.read()
    mc = len(img)
    fin.close()

    metrics = FONT_METRIC

    width = metrics[uni_idx][4]

    if len(enc) == 1:
        L = [str(enc[0]), '0x0', '0x0', '0x0', '0x0', '0x0', str(width), str(height), str(width + 2), str(height + 2)]
    else:
        L = [str(enc[1]), str(enc[0]), '0x0', '0x0', '0x0', '0x0', str(width), str(height), str(width + 2), str(height + 2)]
    ret.extend(bytes(int(x, 0) for x in L))

    canvas = bytearray(width * height)
    # I removed some codes here because I did some tricks to draw the image onto the canvas, which may look confusing.
    # (I need to do so because my language has some special feature.)
    # You can use 'img' directly without using the canvas
    # e.g.
    # ret.extend(bytes(img))
    # ret.extend(bytes(img))
    # return ret
   
    ret.extend(bytes(canvas))
    ret.extend(bytes(to_border(img, mc, width, height, metrics, uni_idx)))
    return ret


Top
   
PostPosted: Fri Jun 26, 2020 6:15 pm 

Joined: Sun Jun 07, 2020 5:29 pm
Posts: 7
haibaer wrote:
The font file uses 8-bit grayscale bitmaps.
You can generate grayscale bitmaps from ttf/otf fonts using any font engine. For me I use freetype. (You can use the Pillow library if you are using python).
Here is the structure of each glyph in the font file:

Shift-JIS encoding of that glyph (2 bytes) (Note: the game uses binary search to find the right glyph, so this encoding value should always be in increasing order.)
0x00 (4 bytes)
width of the glyph (1 byte)
height of the glyph (1 byte)
width of the border glyph (1 byte) (a larger bitmap used to draw borders, you can use the same glyph if you don't need border)
height of the border glyph (1 byte)
the glyph (a width * height grayscale bitmap)
the border glyph (a (width of the border glyph) * (height of the border glyph) grayscale bitmap)



Could you see my modified font file and check what's wrong?

At the end of the file, i added the glyph '가' (at 0x2a834)

And then i changed offset tables (head and bottom both) and
number of characters (84 -> 85 at 0x2b18c) and
the data size(variable-length quantity).

But still the game is crashed.

it is English-font file, but you might understand it.


Attachments:
00009ed8.zip [25.78 KiB]
Downloaded 9 times
Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 12 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited