Files
GalScripts/unpack_softpal_text_dat.py

74 lines
1.8 KiB
Python

import struct
from io import BytesIO
import json
from os.path import splitext
def read_u32(f):
return struct.unpack('<I', f.read(4))[0]
def read_cstring(f):
chars = []
while True:
c = f.read(1)
if c == b'\x00' or c == b'':
break
chars.append(c)
return b''.join(chars)
def rotate_left(val, rshift):
return ((val << rshift) & 0xFF) | (val >> (8 - rshift))
def decrypt(data: bytes) -> BytesIO:
pos = 0x10
shift = 4
decrypted = bytearray(data)
while pos + 4 <= len(decrypted):
data = decrypted[pos:pos+4]
data[0] = rotate_left(data[0], shift)
shift = (shift + 1) % 8
data = struct.unpack('<I', data)[0]
data ^= 0x084DF873 ^ 0xFF987DEE
decrypted[pos:pos+4] = struct.pack('<I', data)
pos += 4
return BytesIO(decrypted)
def load_text_data(f, e):
f.read(12) # Skip header
count = read_u32(f)
first_idx = read_u32(f)
if first_idx != 0:
f.seek(0)
f = decrypt(f.read())
f.read(16)
first_idx = read_u32(f)
f.seek(16)
table = {}
for j in range(count):
cur = read_u32(f)
s = read_cstring(f).decode(e)
table[cur] = s
return table
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print("Usage: python unpack_softpal_text_dat.py <file> [<output>] [<encoding>]")
sys.exit(1)
filename = sys.argv[1]
output = sys.argv[2] if len(sys.argv) > 2 else splitext(filename)[0] + '.json'
encoding = sys.argv[3] if len(sys.argv) > 3 else 'cp932'
with open(filename, 'rb') as f:
table = load_text_data(f, encoding)
with open(output, 'w', encoding='utf-8') as f:
json.dump(table, f, ensure_ascii=False, indent=4)