2nd demon file & contact parser
This commit is contained in:
BIN
_Utils/Dungeon/001.ContTRNSL
Normal file
BIN
_Utils/Dungeon/001.ContTRNSL
Normal file
Binary file not shown.
9761
_Utils/Dungeon/001.ContTRNSL.txt
Normal file
9761
_Utils/Dungeon/001.ContTRNSL.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
_Utils/Dungeon/002.ContTRNSL
Normal file
BIN
_Utils/Dungeon/002.ContTRNSL
Normal file
Binary file not shown.
307
_Utils/Dungeon/002.ContTRNSL.txt
Normal file
307
_Utils/Dungeon/002.ContTRNSL.txt
Normal file
@@ -0,0 +1,307 @@
|
||||
00:
|
||||
cmd_3C //
|
||||
0071
|
||||
cmd_4D //
|
||||
cmd_8D //
|
||||
0001
|
||||
cmd_08 //
|
||||
0001
|
||||
01:
|
||||
cmd_0E //
|
||||
055A
|
||||
0006
|
||||
cmd_11 //
|
||||
0002
|
||||
0002
|
||||
cmd_11 //
|
||||
0000
|
||||
0003
|
||||
cmd_11 //
|
||||
0004
|
||||
0004
|
||||
cmd_11 //
|
||||
0006
|
||||
000B
|
||||
cmd_08 //
|
||||
000D
|
||||
02:
|
||||
cmd_11 //
|
||||
0000
|
||||
000E
|
||||
cmd_11 //
|
||||
0004
|
||||
000E
|
||||
cmd_11 //
|
||||
0006
|
||||
0011
|
||||
cmd_08 //
|
||||
000E
|
||||
03:
|
||||
cmd_11 //
|
||||
0004
|
||||
000D
|
||||
cmd_11 //
|
||||
0006
|
||||
0010
|
||||
cmd_08 //
|
||||
000D
|
||||
04:
|
||||
cmd_11 //
|
||||
0006
|
||||
0010
|
||||
cmd_08 //
|
||||
000D
|
||||
05:
|
||||
cmd_0E //
|
||||
055A
|
||||
000A
|
||||
cmd_08 //
|
||||
0001
|
||||
06:
|
||||
cmd_11 //
|
||||
0003
|
||||
0007
|
||||
cmd_11 //
|
||||
0001
|
||||
0008
|
||||
cmd_11 //
|
||||
0005
|
||||
0009
|
||||
cmd_11 //
|
||||
0007
|
||||
000B
|
||||
cmd_08 //
|
||||
000D
|
||||
07:
|
||||
cmd_11 //
|
||||
0001
|
||||
000E
|
||||
cmd_11 //
|
||||
0005
|
||||
000E
|
||||
cmd_11 //
|
||||
0007
|
||||
0011
|
||||
cmd_08 //
|
||||
000E
|
||||
08:
|
||||
cmd_11 //
|
||||
0005
|
||||
000D
|
||||
cmd_11 //
|
||||
0007
|
||||
0010
|
||||
cmd_08 //
|
||||
000D
|
||||
09:
|
||||
cmd_11 //
|
||||
0007
|
||||
0010
|
||||
cmd_08 //
|
||||
000D
|
||||
0A:
|
||||
cmd_08 //
|
||||
0006
|
||||
0B:
|
||||
cmd_42 //
|
||||
0001
|
||||
cmd_14 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
0C:
|
||||
cmd_42 //
|
||||
0002
|
||||
cmd_15 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
0D:
|
||||
cmd_42 //
|
||||
0003
|
||||
cmd_16 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
0E:
|
||||
cmd_42 //
|
||||
0004
|
||||
cmd_17 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
0F:
|
||||
cmd_42 //
|
||||
0005
|
||||
cmd_14 //
|
||||
0003
|
||||
0014
|
||||
cmd_15 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
10:
|
||||
cmd_42 //
|
||||
0006
|
||||
cmd_14 //
|
||||
0003
|
||||
0014
|
||||
cmd_16 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
11:
|
||||
cmd_42 //
|
||||
0007
|
||||
cmd_14 //
|
||||
0003
|
||||
0014
|
||||
cmd_17 //
|
||||
0003
|
||||
0014
|
||||
cmd_09 //
|
||||
0012
|
||||
0013
|
||||
12:
|
||||
cmd_1E //
|
||||
0017
|
||||
cmd_60 //
|
||||
cmd_1E //
|
||||
0015
|
||||
cmd_60 //
|
||||
cmd_75 //
|
||||
0002
|
||||
cmd_78 //
|
||||
0000
|
||||
cmd_7A //
|
||||
0080
|
||||
0080
|
||||
0080
|
||||
0010
|
||||
cmd_7B //
|
||||
cmd_01 // ShowTextID (u16)
|
||||
0000
|
||||
cmd_1E //
|
||||
0016
|
||||
cmd_60 //
|
||||
cmd_34 //
|
||||
cmd_1E //
|
||||
0018
|
||||
cmd_60 //
|
||||
cmd_0C //
|
||||
13:
|
||||
cmd_1E //
|
||||
0017
|
||||
cmd_60 //
|
||||
cmd_1E //
|
||||
0015
|
||||
cmd_60 //
|
||||
cmd_75 //
|
||||
0002
|
||||
cmd_78 //
|
||||
0000
|
||||
cmd_7A //
|
||||
0080
|
||||
0080
|
||||
0080
|
||||
0010
|
||||
cmd_7B //
|
||||
cmd_01 // ShowTextID (u16)
|
||||
0001
|
||||
cmd_1E //
|
||||
0016
|
||||
cmd_60 //
|
||||
cmd_34 //
|
||||
cmd_1E //
|
||||
0018
|
||||
cmd_60 //
|
||||
cmd_0C //
|
||||
14:
|
||||
cmd_1E //
|
||||
0017
|
||||
cmd_60 //
|
||||
cmd_1E //
|
||||
0015
|
||||
cmd_60 //
|
||||
cmd_75 //
|
||||
0002
|
||||
cmd_78 //
|
||||
0000
|
||||
cmd_7A //
|
||||
0080
|
||||
0080
|
||||
0080
|
||||
0010
|
||||
cmd_7B //
|
||||
cmd_01 // ShowTextID (u16)
|
||||
0002
|
||||
cmd_1E //
|
||||
0016
|
||||
cmd_60 //
|
||||
cmd_34 //
|
||||
cmd_1E //
|
||||
0018
|
||||
cmd_60 //
|
||||
cmd_0C //
|
||||
15:
|
||||
cmd_2F //
|
||||
0001
|
||||
0005
|
||||
0000
|
||||
0001
|
||||
cmd_1F //
|
||||
16:
|
||||
cmd_75 //
|
||||
0002
|
||||
cmd_7A //
|
||||
0000
|
||||
0000
|
||||
0000
|
||||
0010
|
||||
cmd_7B //
|
||||
cmd_79 //
|
||||
cmd_1F //
|
||||
17:
|
||||
cmd_56 //
|
||||
0750
|
||||
0750
|
||||
0750
|
||||
0001
|
||||
cmd_84 //
|
||||
0000
|
||||
0015
|
||||
0000
|
||||
0000
|
||||
0088
|
||||
0090
|
||||
0090
|
||||
0008
|
||||
cmd_6A //
|
||||
cmd_74 //
|
||||
07D0
|
||||
0008
|
||||
cmd_67 //
|
||||
cmd_74 //
|
||||
1000
|
||||
0008
|
||||
cmd_1F //
|
||||
18:
|
||||
cmd_68 //
|
||||
cmd_6D //
|
||||
0000
|
||||
cmd_1F //
|
||||
0000
|
||||
004C
|
||||
0080
|
||||
30
_Utils/Dungeon/ContTRNSL.hexpat
Normal file
30
_Utils/Dungeon/ContTRNSL.hexpat
Normal file
@@ -0,0 +1,30 @@
|
||||
struct Header {
|
||||
u16 scriptPointersTableOffset;
|
||||
u16 scriptStartOffset;
|
||||
u16 textPointersTableOffset;
|
||||
u16 textStartOffset;
|
||||
};
|
||||
|
||||
Header header @ 0x00;
|
||||
|
||||
// Важно: вычитание двух u16 может дать underflow → результат интерпретируется как большое положительное число
|
||||
// Поэтому лучше сразу привести к u32, чтобы избежать проблем
|
||||
u32 scriptCount = (u32(header.scriptStartOffset) - u32(header.scriptPointersTableOffset)) / 2;
|
||||
u32 textCount = (u32(header.textStartOffset) - u32(header.textPointersTableOffset)) / 2;
|
||||
|
||||
struct ScriptEntry {
|
||||
u16 relativeOffset;
|
||||
|
||||
// Явно приводим к u32 перед сложением — на всякий случай
|
||||
u16 firstWord @ (u32(header.scriptStartOffset) + this.relativeOffset);
|
||||
};
|
||||
|
||||
ScriptEntry scripts[scriptCount] @ header.scriptPointersTableOffset;
|
||||
|
||||
struct TextEntry {
|
||||
u16 relativeOffset;
|
||||
|
||||
u16 firstWord @ (u32(header.textStartOffset) + this.relativeOffset);
|
||||
};
|
||||
|
||||
TextEntry texts[textCount] @ header.textPointersTableOffset;
|
||||
97
_Utils/Dungeon/contact_parser.py
Normal file
97
_Utils/Dungeon/contact_parser.py
Normal file
@@ -0,0 +1,97 @@
|
||||
import sys
|
||||
import struct
|
||||
import os
|
||||
|
||||
# Таблица команд
|
||||
COMMANDS = {
|
||||
0x01: "ShowTextID (u16)",
|
||||
# Сюда можно добавлять другие команды по мере обнаружения
|
||||
}
|
||||
|
||||
def read_int16(data, offset):
|
||||
"""Читает int16 из данных по смещению"""
|
||||
return struct.unpack('<h', data[offset:offset+2])[0]
|
||||
|
||||
def read_uint16(data, offset):
|
||||
"""Читает uint16 из данных по смещению"""
|
||||
return struct.unpack('<H', data[offset:offset+2])[0]
|
||||
|
||||
def parse_script_commands(data, start_offset, end_offset):
|
||||
"""Парсит скриптовые данные от start_offset до end_offset"""
|
||||
results = []
|
||||
offset = start_offset
|
||||
|
||||
while offset < end_offset:
|
||||
value = read_uint16(data, offset)
|
||||
results.append({
|
||||
'offset': offset,
|
||||
'value': value,
|
||||
'is_command': (value & 0x8000) != 0
|
||||
})
|
||||
offset += 2
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python script.py <file_path>")
|
||||
sys.exit(1)
|
||||
|
||||
file_path = sys.argv[1]
|
||||
|
||||
# Читаем файл
|
||||
with open(file_path, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
# Читаем заголовок
|
||||
header = {
|
||||
'script_pointers_offset': read_int16(data, 0),
|
||||
'script_start_offset': read_int16(data, 2),
|
||||
'text_pointers_offset': read_int16(data, 4),
|
||||
'text_start_offset': read_int16(data, 6)
|
||||
}
|
||||
|
||||
# Вычисляем количество указателей
|
||||
script_count = (header['script_start_offset'] - header['script_pointers_offset']) // 2
|
||||
text_count = (header['text_start_offset'] - header['text_pointers_offset']) // 2
|
||||
|
||||
# Читаем указатели скриптов
|
||||
script_pointers = []
|
||||
for i in range(script_count):
|
||||
offset = header['script_pointers_offset'] + i * 2
|
||||
ptr = read_uint16(data, offset)
|
||||
abs_offset = header['script_start_offset'] + ptr
|
||||
script_pointers.append(abs_offset)
|
||||
|
||||
# Добавляем фиктивный указатель на конец области скриптов (до текстовых данных)
|
||||
script_pointers.append(header['text_start_offset'])
|
||||
|
||||
# Формируем имя выходного файла
|
||||
output_file = file_path + '.txt'
|
||||
|
||||
with open(output_file, 'w', encoding='utf-8') as out:
|
||||
for i in range(script_count):
|
||||
start = script_pointers[i]
|
||||
end = script_pointers[i + 1]
|
||||
|
||||
# Пишем заголовок указателя
|
||||
out.write(f"{i:02X}:\n")
|
||||
|
||||
# Парсим команды на этом участке
|
||||
offset = start
|
||||
while offset < end:
|
||||
value = read_uint16(data, offset)
|
||||
|
||||
if value & 0x8000: # Это команда
|
||||
cmd_id = value & 0xFF
|
||||
cmd_desc = COMMANDS.get(cmd_id, "")
|
||||
out.write(f" cmd_{cmd_id:02X} // {cmd_desc}\n")
|
||||
else: # Это данные
|
||||
out.write(f" {value:04X}\n")
|
||||
|
||||
offset += 2
|
||||
|
||||
print(f"Done! Output saved to: {output_file}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user