def dump(output_root, prebuilt_root, name, data, character_map={}): character_map[0xfe] = '\n' output_path = os.path.join(output_root, f"{name}.txt") prebuilt_path = os.path.join(prebuilt_root, f"{name}.map") with open(output_path, "w", encoding="utf-8") as output: compression = data[0] map_bytes = data[1:] output.write(f"[{compression:X}]\n") # Compressed if compression & 0x03: with open(prebuilt_path, "wb") as binary: binary.write(data) # Write and include the compression byte binary.write(bytearray([0xFF])) # Add 0xFF to the end when decompressing map_bytes.append(0xFF) # The 0xFF at the end is implied though map_bytes = tilemaps.decompress_tilemap(map_bytes)[:-1] output.write("".join(utils.bin2txt(map_bytes, character_map)))
]) with open("baserom_parts_collection.gb", "rb") as rom: for l in list_map: addr, term, n, prefixlen = list_map[l] if isinstance(addr, tuple): bank = addr[0] addr = utils.rom2realaddr(addr) else: bank = utils.real2romaddr(addr)[0] rom.seek(addr) with open('text/ptrlists/{}.txt'.format(l), 'w', encoding="utf-8") as output: output.write(f"({term},{prefixlen})\n") ptrs = [utils.read_short(rom) for i in range(0, n)] for ptr in ptrs: rom.seek(utils.rom2realaddr((bank, ptr))) prefix = [utils.read_byte(rom) for i in range(0, prefixlen)] # If the first 2 are 00, there's no data if prefixlen > 0 and prefix[0] == 0x0: b = [] else: b = list(iter(partial(utils.read_byte, rom), term)) # In the case of an empty string, print out at least the terminator # Doing this allows the ptrlist2asm script to properly identify when to actually skip the terminator # (Medarotters with a null prefix shouldn't have a terminator, but empty part descriptions should) if len(b) == 0: b = [term] p = "".join(utils.bin2txt(bytearray(prefix), {})) t = "".join(utils.bin2txt(bytearray(b), tileset)) output.write(f"{p}{t}\n")
]) for lst in list_map: merged_dict = {} addr, length, term, pad, n = list_map[lst] for version in VERSIONS: with open(version[0], "rb") as rom: if isinstance(addr, tuple): addr = utils.rom2realaddr(addr) rom.seek(addr) for i in range(0, n): c = 0 for l in length if isinstance(length, tuple) else (length, ): b = list(iter(partial(utils.read_byte, rom), term)) rom.seek(l - len(b) - 1, 1) # Account for the terminator value = "{}\n".format("".join( utils.bin2txt(bytearray(b), tileset))) key = "{:03}_{:02}".format(i, c) c += 1 if key in merged_dict and merged_dict[ key] != value: # Just assume 2 versions, so the existence of a previous entry must belong to the 'default' version merged_dict[key + VERSIONS[0][1]] = "[{}]{}".format( VERSIONS[0][1], merged_dict[key]) del merged_dict[key] key = key + version[1] value = "[{}]{}".format(version[1], value) merged_dict[key] = value with open('text/lists/{}.txt'.format(lst), 'w', encoding="utf-8") as output: output.write("{}|{}|{}\n".format(length, term, pad)) for i in sorted(merged_dict.keys(), key=lambda x: x.lower()):
# We can rebuild every non-compressed tilemap, but we need to keep every compressed one until we figure out the compression algorithm if compressed: tmap_path = f"game/tilemaps/{fname}.tmap" with open(tmap_path, "wb") as binary: binary.write( bytearray([compressed] + tilemap_bytes[i] + [0xFF])) output.write("[DIRECT]\n") tilemap_bytes[i] = tilemaps.decompress_tilemap( tilemap_bytes[i]) else: output.write("[OVERLAY]\n") # Assume tilesets[fname] in tiletables if fname is in tilesets output.write("".join( utils.bin2txt( tilemap_bytes[i], tiletables[tileset_table[fname]] if fname in tileset_table else tileset_default))) print(f"total length 0x{len(tilemap_bytes[i]):02x}") else: print("Duplicate") if ptrfile: ptrfile.write(f"{i:02X}={os.path.basename(fname)}\n") for fname in tilemap_files: if tileset_file: tileset_file.write(f"{fname}=MainDialog,MainSpecial\n") finally: if ptrfile: ptrfile.close() if tileset_file:
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 = "Tilemap_{:04X}".format(ptr) if i not in ptrtable else ptrtable[i] txt_path = "text/tilemaps/{}.txt".format(fname) if not fname in tilemap_files: tilemap_files.append(fname) with open(txt_path, "w", encoding = "utf-8") as output: # We can rebuild every non-compressed tilemap, but we need to keep every compressed one until we figure out the compression algorithm if compressed: tmap_path = "game/tilemaps/{}.tmap".format(fname) with open(tmap_path, "wb") as binary: binary.write(bytearray([compressed] + tilemap_bytes[i] + [0xFF])) output.write("[DIRECT]\n") tilemap_bytes[i] = tilemaps.decompress_tilemap(tilemap_bytes[i]) else: output.write("[OVERLAY]\n") # Assume tilesets[fname] in tiletables if fname is in tilesets output.write("".join(utils.bin2txt(tilemap_bytes[i], tiletables[tilesets[fname]] if fname in tilesets else tileset_default))) print("total length 0x{:02x}".format(len(tilemap_bytes[i]))) else: print("Duplicate") if ptrfile: ptrfile.write("{:02X}={}\n".format(i, fname)) if tileset_file: tileset_file.write("{}=scripts/res/tileset_MainDialog.tbl\n".format(fname)) finally: if ptrfile: ptrfile.close() if tileset_file: tileset_file.close()