text_table_ptrs = {} texts = {} text_version_specific = {} text_shifted_pointers = {} text_unused = {} for info in rom_info: filename = info[0] suffix = info[1] txt_bank_ptr = info[2] txt_tbl_ptr = info[3] entry_count = info[4] with open(filename, 'rb') as rom: rom.seek(txt_bank_ptr) banks = [utils.read_byte(rom) for i in range(0, entry_count)] rom.seek(txt_tbl_ptr) text_ptrs = list( zip(banks, [utils.read_short(rom) for i in range(0, entry_count)])) text_table_ptrs[suffix] = (txt_bank_ptr, txt_tbl_ptr, text_ptrs) class SpecialCharacter(): def __init__(self, symbol, default=0, bts=1, end=False, names=None, always_print=False,
ptrs.seek(0) name_table = {} for line in ptrs: n, p = line.strip().split("=") name_table[int(p, 16)] = n for info in rom_info: filename = info[0] suffix = info[1] txt_bank_ptr = info[2] txt_tbl_ptr = info[3] entry_count = info[4] with open(filename, 'rb') as rom: rom.seek(txt_bank_ptr) banks = [utils.read_byte(rom) for i in range(0, entry_count)] rom.seek(txt_tbl_ptr) text_ptrs = list( zip(banks, [utils.read_short(rom) for i in range(0, entry_count)])) with open("./game/src/data/text_tables.asm", "w") as f: f.write( f'INCLUDE "build/dialog/text_table_constants_{{GAMEVERSION}}.asm"\n\n' ) for i, entry in enumerate([t for t in text_ptrs if t[0] != 0]): f.write( f'SECTION "TextSection{i}", ROMX[${entry[1]:04x}], BANK[${entry[0]:02x}]\n' ) f.write(f'TextSection{i}:\n') f.write(f' INCBIN cTextSection{i}\n\n')
if isinstance(ptr, str): entries[idx][version_suffix].append(ptr) else: real_addr = utils.rom2realaddr((bank, ptr)) rom.seek(real_addr) for i in range(0, spp): t = term[i] fl = fix_len[i][0] ph = print_hex[i] b = [] if fl != None: b = [utils.read_byte(rom) for i in range(0, fl)] else: b = list(iter(partial(utils.read_byte, rom), t)) if len(b) == 0: b = [t] txt = "" i = 0 while i < len(b): if b[i] == 0xD3 and not ph: # Kanji i += 1 txt += kanji[b[i]] else: if ph or b[i] not in tileset: txt += f'\\x{b[i]:02x}' else: txt += tileset[b[i]]
]) tiletables[tileset_table[fname]][0xFE] = '\n' else: tileset_file = open("scripts/res/meta_tilemap_tilesets.tbl", "w") try: for i in sorted(tilemap_ptr): ptr = tilemap_ptr[i] if ptr == TERMINATOR: print(f"{i:02x} is a null tilemap") if ptrfile: ptrfile.write(f"{i:02X}=\n") continue addr = BASE_ADDR + ptr - BANK_SIZE rom.seek(addr) compressed = utils.read_byte(rom) assert compressed in [ 0x0, 0x1 ], f"Unexpected compression byte 0x{compressed:02x}" print( f"{i:02x} @ [{ptr:04X} / {rom.tell()-1:08X}] {'Compressed' if compressed else 'Uncompressed'} | ", end="") tilemap_bytes[i] = list(iter(partial(utils.read_byte, rom), 0xFF)) # Read ROM until 0xFF # tilemaps are all adjacent to each other, so we don't need to do anything more than make sure they're sorted fname = f"Tilemap_{ptr:04X}" if i not in ptrtable else ptrtable[i] txt_path = f"text/tilemaps/{fname}.txt" if not fname in tilemap_files: tilemap_files.append(fname) with open(txt_path, "w", encoding="utf-8") as output:
# Map real address to a defined name nametable = {} namefile = None if os.path.exists(meta_tilemap_names_file): nametable = utils.read_table(meta_tilemap_names_file, keystring=True) else: namefile = open(meta_tilemap_names_file, "w") default_version = roms[0] tilemap_tables = None try: with open(default_version[0], "rb") as rom: rom.seek(map_bank_table) tilemap_banks = [ utils.read_byte(rom) for i in range(0, map_table_count) ] rom.seek(map_addr_table) tilemap_addrs = [ utils.read_short(rom) for i in range(0, map_table_count) ] # The tilemap locations are in the same place in both versions tilemap_tables = list(zip(tilemap_banks, tilemap_addrs)) tilemap_data = {} # [version] -> [identifier] -> (realaddr, data) duplicate_map = {} # [version] -> [identifier] -> identity version_specific_ids = set() basename_map = OrderedDict() version_suffixes = [i[1] for i in roms]