summaryrefslogtreecommitdiff
path: root/redtools/pretty_map_headers.py
diff options
context:
space:
mode:
authorBryan Bishop <kanzure@gmail.com>2013-09-01 02:04:34 -0500
committerBryan Bishop <kanzure@gmail.com>2013-09-01 02:05:18 -0500
commita5b718db57a361cf3c196d73cbc5b3e21d3ddf6e (patch)
tree312937bcf9bced31a13e854e25b1ffb92f5cf48b /redtools/pretty_map_headers.py
parentfc6785b87b7ddd27437ac2ac15bcc0870cc0fe90 (diff)
dump in pokered/extras/ python stuff from b185b245
Diffstat (limited to 'redtools/pretty_map_headers.py')
-rw-r--r--redtools/pretty_map_headers.py755
1 files changed, 755 insertions, 0 deletions
diff --git a/redtools/pretty_map_headers.py b/redtools/pretty_map_headers.py
new file mode 100644
index 0000000..ef26be3
--- /dev/null
+++ b/redtools/pretty_map_headers.py
@@ -0,0 +1,755 @@
+# -*- coding: utf-8 -*-
+#author: Bryan Bishop <kanzure@gmail.com>
+#date: 2012-01-02
+#purpose: dump asm for each map header
+import json
+import extract_maps
+import sprite_helper
+import random
+import string
+import analyze_texts #hopefully not a dependency loop
+
+base = 16
+spacing = " "
+all_texts = None
+
+#map constants
+map_constants = [
+["PALLET_TOWN", 0x00],
+["VIRIDIAN_CITY", 0x01],
+["PEWTER_CITY", 0x02],
+["CERULEAN_CITY", 0x03],
+["LAVENDER_TOWN", 0x04],
+["VERMILION_CITY", 0x05],
+["CELADON_CITY", 0x06],
+["FUCHSIA_CITY", 0x07],
+["CINNABAR_ISLAND", 0x08],
+["INDIGO_PLATEAU", 0x09],
+["SAFFRON_CITY", 0x0A],
+["ROUTE_1", 0x0C],
+["ROUTE_2", 0x0D],
+["ROUTE_3", 0x0E],
+["ROUTE_4", 0x0F],
+["ROUTE_5", 0x10],
+["ROUTE_6", 0x11],
+["ROUTE_7", 0x12],
+["ROUTE_8", 0x13],
+["ROUTE_9", 0x14],
+["ROUTE_10", 0x15],
+["ROUTE_11", 0x16],
+["ROUTE_12", 0x17],
+["ROUTE_13", 0x18],
+["ROUTE_14", 0x19],
+["ROUTE_15", 0x1A],
+["ROUTE_16", 0x1B],
+["ROUTE_17", 0x1C],
+["ROUTE_18", 0x1D],
+["ROUTE_19", 0x1E],
+["ROUTE_20", 0x1F],
+["ROUTE_21", 0x20],
+["ROUTE_22", 0x21],
+["ROUTE_23", 0x22],
+["ROUTE_24", 0x23],
+["ROUTE_25", 0x24],
+["REDS_HOUSE_1F", 0x25],
+["REDS_HOUSE_2F", 0x26],
+["BLUES_HOUSE", 0x27],
+["OAKS_LAB", 0x28],
+["VIRIDIAN_POKECENTER", 0x29],
+["VIRIDIAN_MART", 0x2A],
+["VIRIDIAN_SCHOOL", 0x2B],
+["VIRIDIAN_HOUSE", 0x2C],
+["VIRIDIAN_GYM", 0x2D],
+["DIGLETTS_CAVE_EXIT", 0x2E],
+["VIRIDIAN_FOREST_EXIT", 0x2F],
+["ROUTE_2_HOUSE", 0x30],
+["ROUTE_2_GATE", 0x31],
+["VIRIDIAN_FOREST_ENTRANCE", 0x32],
+["VIRIDIAN_FOREST", 0x33],
+["MUSEUM_1F", 0x34],
+["MUSEUM_2F", 0x35],
+["PEWTER_GYM", 0x36],
+["PEWTER_HOUSE_1", 0x37],
+["PEWTER_MART", 0x38],
+["PEWTER_HOUSE_2", 0x39],
+["PEWTER_POKECENTER", 0x3A],
+["MT_MOON_1", 0x3B],
+["MT_MOON_2", 0x3C],
+["MT_MOON_3", 0x3D],
+["TRASHED_HOUSE", 0x3E],
+["CERULEAN_HOUSE", 0x3F],
+["CERULEAN_POKECENTER", 0x40],
+["CERULEAN_GYM", 0x41],
+["BIKE_SHOP", 0x42],
+["CERULEAN_MART", 0x43],
+["MT_MOON_POKECENTER", 0x44],
+["ROUTE_5_GATE", 0x46],
+["PATH_ENTRANCE_ROUTE_5", 0x47],
+["DAYCAREM", 0x48],
+["ROUTE_6_GATE", 0x49],
+["PATH_ENTRANCE_ROUTE_6", 0x4A],
+["ROUTE_7_GATE", 0x4C],
+["PATH_ENTRANCE_ROUTE_7", 0x4D],
+["ROUTE_8_GATE", 0x4F],
+["PATH_ENTRANCE_ROUTE_8", 0x50],
+["ROCK_TUNNEL_POKECENTER", 0x51],
+["ROCK_TUNNEL_1", 0x52],
+["POWER_PLANT", 0x53],
+["ROUTE_11_GATE_1F", 0x54],
+["DIGLETTS_CAVE_ENTRANCE", 0x55],
+["ROUTE_11_GATE_2F", 0x56],
+["ROUTE_12_GATE", 0x57],
+["BILLS_HOUSE", 0x58],
+["VERMILION_POKECENTER", 0x59],
+["POKEMON_FAN_CLUB", 0x5A],
+["VERMILION_MART", 0x5B],
+["VERMILION_GYM", 0x5C],
+["VERMILION_HOUSE_1", 0x5D],
+["VERMILION_DOCK", 0x5E],
+["SS_ANNE_1", 0x5F],
+["SS_ANNE_2", 0x60],
+["SS_ANNE_3", 0x61],
+["SS_ANNE_4", 0x62],
+["SS_ANNE_5", 0x63],
+["SS_ANNE_6", 0x64],
+["SS_ANNE_7", 0x65],
+["SS_ANNE_8", 0x66],
+["SS_ANNE_9", 0x67],
+["SS_ANNE_10", 0x68],
+["VICTORY_ROAD_1", 0x6C],
+["LANCES_ROOM", 0x71],
+["HALL_OF_FAME", 0x76],
+["UNDERGROUND_PATH_NS", 0x77],
+["CHAMPIONS_ROOM", 0x78],
+["UNDERGROUND_PATH_WE", 0x79],
+["CELADON_MART_1", 0x7A],
+["CELADON_MART_2", 0x7B],
+["CELADON_MART_3", 0x7C],
+["CELADON_MART_4", 0x7D],
+["CELADON_MART_5", 0x7E],
+["CELADON_MART_6", 0x7F],
+["CELADON_MANSION_1", 0x80],
+["CELADON_MANSION_2", 0x81],
+["CELADON_MANSION_3", 0x82],
+["CELADON_MANSION_4", 0x83],
+["CELADON_MANSION_5", 0x84],
+["CELADON_POKECENTER", 0x85],
+["CELADON_GYM", 0x86],
+["GAME_CORNER", 0x87],
+["CELADON_HOUSE", 0x88],
+["CELADONPRIZE_ROOM", 0x89],
+["CELADON_DINER", 0x8A],
+["CELADON_HOUSE_2", 0x8B],
+["CELADONHOTEL", 0x8C],
+["LAVENDER_POKECENTER", 0x8D],
+["POKEMONTOWER_1", 0x8E],
+["POKEMONTOWER_2", 0x8F],
+["POKEMONTOWER_3", 0x90],
+["POKEMONTOWER_4", 0x91],
+["POKEMONTOWER_5", 0x92],
+["POKEMONTOWER_6", 0x93],
+["POKEMONTOWER_7", 0x94],
+["LAVENDER_HOUSE_1", 0x95],
+["LAVENDER_MART", 0x96],
+["LAVENDER_HOUSE_2", 0x97],
+["FUCHSIA_MART", 0x98],
+["FUCHSIA_HOUSE_1", 0x99],
+["FUCHSIA_POKECENTER", 0x9A],
+["FUCHSIA_HOUSE_2", 0x9B],
+["SAFARIZONEENTRANCE", 0x9C],
+["FUCHSIA_GYM", 0x9D],
+["FUCHSIAMEETINGROOM", 0x9E],
+["SEAFOAM_ISLANDS_2", 0x9F],
+["SEAFOAM_ISLANDS_3", 0xA0],
+["SEAFOAM_ISLANDS_4", 0xA1],
+["SEAFOAM_ISLANDS_5", 0xA2],
+["VERMILION_HOUSE_2", 0xA3],
+["FUCHSIA_HOUSE_3", 0xA4],
+["MANSION_1", 0xA5],
+["CINNABAR_GYM", 0xA6],
+["CINNABAR_LAB_1", 0xA7],
+["CINNABAR_LAB_2", 0xA8],
+["CINNABAR_LAB_3", 0xA9],
+["CINNABAR_LAB_4", 0xAA],
+["CINNABAR_POKECENTER", 0xAB],
+["CINNABAR_MART", 0xAC],
+["INDIGO_PLATEAU_LOBBY", 0xAE],
+["COPYCATS_HOUSE_1F", 0xAF],
+["COPYCATS_HOUSE_2F", 0xB0],
+["FIGHTINGDOJO", 0xB1],
+["SAFFRON_GYM", 0xB2],
+["SAFFRON_HOUSE_1", 0xB3],
+["SAFFRON_MART", 0xB4],
+["SILPH_CO_1F", 0xB5],
+["SAFFRON_POKECENTER", 0xB6],
+["SAFFRON_HOUSE_2", 0xB7],
+["ROUTE_15_GATE", 0xB8],
+["ROUTE_16_GATE_1F", 0xBA],
+["ROUTE_16_GATE_2F", 0xBB],
+["ROUTE_16_HOUSE", 0xBC],
+["ROUTE_12_HOUSE", 0xBD],
+["ROUTE_18_GATE_1F", 0xBE],
+["ROUTE_18_GATE_2F", 0xBF],
+["SEAFOAM_ISLANDS_1", 0xC0],
+["ROUTE_22_GATE", 0xC1],
+["VICTORY_ROAD_2", 0xC2],
+["ROUTE_12_GATE_2F", 0xC3],
+["VERMILION_HOUSE_3", 0xC4],
+["DIGLETTS_CAVE", 0xC5],
+["VICTORY_ROAD_3", 0xC6],
+["ROCKET_HIDEOUT_1", 0xC7],
+["ROCKET_HIDEOUT_2", 0xC8],
+["ROCKET_HIDEOUT_3", 0xC9],
+["ROCKET_HIDEOUT_4", 0xCA],
+["ROCKET_HIDEOUT_ELEVATOR", 0xCB],
+["SILPH_CO_2F", 0xCF],
+["SILPH_CO_3F", 0xD0],
+["SILPH_CO_4F", 0xD1],
+["SILPH_CO_5F", 0xD2],
+["SILPH_CO_6F", 0xD3],
+["SILPH_CO_7F", 0xD4],
+["SILPH_CO_8F", 0xD5],
+["MANSION_2", 0xD6],
+["MANSION_3", 0xD7],
+["MANSION_4", 0xD8],
+["SAFARI_ZONE_EAST", 0xD9],
+["SAFARI_ZONE_NORTH", 0xDA],
+["SAFARI_ZONE_WEST", 0xDB],
+["SAFARI_ZONE_CENTER", 0xDC],
+["SAFARI_ZONE_REST_HOUSE_1", 0xDD],
+["SAFARI_ZONE_SECRET_HOUSE", 0xDE],
+["SAFARI_ZONE_REST_HOUSE_2", 0xDF],
+["SAFARI_ZONE_REST_HOUSE_3", 0xE0],
+["SAFARI_ZONE_REST_HOUSE_4", 0xE1],
+["UNKNOWN_DUNGEON_2", 0xE2],
+["UNKNOWN_DUNGEON_3", 0xE3],
+["UNKNOWN_DUNGEON_1", 0xE4],
+["NAME_RATERS_HOUSE", 0xE5],
+["CERULEAN_HOUSE_3", 0xE6],
+["ROCK_TUNNEL_2", 0xE8],
+["SILPH_CO_9F", 0xE9],
+["SILPH_CO_10F", 0xEA],
+["SILPH_CO_11F", 0xEB],
+["SILPH_CO_ELEVATOR", 0xEC],
+["BATTLE_CENTER", 0xEF],
+["TRADE_CENTER", 0xF0],
+["LORELEIS_ROOM", 0xF5],
+["BRUNOS_ROOM", 0xF6],
+["AGATHAS_ROOM", 0xF7],
+["BEACH_HOUSE", 0xF8]]
+
+#i prefer a different data structure
+temp = {}
+for constant in map_constants:
+ value = constant[1]
+ name = constant[0]
+ temp[value] = name
+map_constants = temp
+del temp
+
+#these appear outside of quotes
+constant_abbreviation_bytes = {
+}
+
+#these appear in quotes
+char_conversion = [
+(" ", 0x7F),
+("A", 0x80),
+("B", 0x81),
+("C", 0x82),
+("D", 0x83),
+("E", 0x84),
+("F", 0x85),
+("G", 0x86),
+("H", 0x87),
+("I", 0x88),
+("J", 0x89),
+("K", 0x8A),
+("L", 0x8B),
+("M", 0x8C),
+("N", 0x8D),
+("O", 0x8E),
+("P", 0x8F),
+("Q", 0x90),
+("R", 0x91),
+("S", 0x92),
+("T", 0x93),
+("U", 0x94),
+("V", 0x95),
+("W", 0x96),
+("X", 0x97),
+("Y", 0x98),
+("Z", 0x99),
+("(", 0x9A),
+(")", 0x9B),
+(":", 0x9C),
+(";", 0x9D),
+("[", 0x9E),
+("]", 0x9F),
+("a", 0xA0),
+("b", 0xA1),
+("c", 0xA2),
+("d", 0xA3),
+("e", 0xA4),
+("f", 0xA5),
+("g", 0xA6),
+("h", 0xA7),
+("i", 0xA8),
+("j", 0xA9),
+("k", 0xAA),
+("l", 0xAB),
+("m", 0xAC),
+("n", 0xAD),
+("o", 0xAE),
+("p", 0xAF),
+("q", 0xB0),
+("r", 0xB1),
+("s", 0xB2),
+("t", 0xB3),
+("u", 0xB4),
+("v", 0xB5),
+("w", 0xB6),
+("x", 0xB7),
+("y", 0xB8),
+("z", 0xB9),
+("é", 0xBA),
+("'d", 0xBB),
+("'l", 0xBC),
+("'s", 0xBD),
+("'t", 0xBE),
+("'v", 0xBF),
+("'", 0xE0),
+("-", 0xE3),
+("'r", 0xE4),
+("'m", 0xE5),
+("?", 0xE6),
+("!", 0xE7),
+(".", 0xE8),
+("♂", 0xEF),
+#("¥", 0xF0),
+("/", 0xF3),
+(",", 0xF4),
+("♀", 0xF5),
+("0", 0xF6),
+("1", 0xF7),
+("2", 0xF8),
+("3", 0xF9),
+("4", 0xFA),
+("5", 0xFB),
+("6", 0xFC),
+("7", 0xFD),
+("8", 0xFE),
+("9", 0xFF)]
+#these appear in quotes
+txt_bytes = {
+ 0x50: "@",
+ 0x54: "#",
+ 0x75: "…",
+}
+for item in char_conversion:
+ txt_bytes[item[1]] = item[0]
+del char_conversion
+
+#this was originally for renaming freeze maps for a unique name
+def random_hash():
+ available_chars = string.hexdigits[:16]
+ return ''.join(
+ random.choice(available_chars)
+ for dummy in xrange(5))
+
+def offset_to_pointer(offset):
+ if type(offset) == str: offset = int(offset, base)
+ return int(offset) % 0x4000 + 0x4000
+
+def map_name_cleaner(name, id):
+ "names have to be acceptable asm labels"
+
+ #duck out early
+ if name == "FREEZE":
+ #name += "_" + random_hash() + "_h"
+ name += "_" + str(id) + "_h"
+ return name
+
+ #the long haul
+ name = name.replace(":", "")
+ name = name.replace("(", "")
+ name = name.replace(")", "")
+ name = name.replace("'", "")
+ name = name.replace("/", "") #N/S -> NS, W/E -> WE
+ name = name.replace(".", "") #S.S. -> SS, Mt. -> Mt
+ name = name.replace(" ", "") #or '_' ??
+ name = name + "_h"
+
+ return name
+
+def write_connections(north, south, west, east):
+ #north 0, south 1, west 2, east 3
+ if north and south and west and east: return "NORTH | SOUTH | WEST | EAST"
+ if north and south and west and not east: return "NORTH | SOUTH | WEST"
+ if north and south and not west and east: return "NORTH | SOUTH | EAST"
+ if north and not south and west and east: return "NORTH | WEST | EAST"
+ if not north and south and west and east: return "SOUTH | WEST | EAST"
+ if north and south and not west and not east: return "NORTH | SOUTH"
+ if not north and not south and west and east: return "WEST | EAST"
+ if not north and south and west and not east: return "SOUTH | WEST"
+ if not north and south and not west and east: return "SOUTH | EAST"
+ if north and not south and west and not east: return "NORTH | WEST"
+ if north and not south and not west and east: return "NORTH | EAST"
+ raise Exception, "unpredicted outcome on write_connections"
+
+#TODO: make this elegant
+def connection_line(byte):
+ if type(byte) == str:
+ byte = int(byte, base)
+
+ connections = 0
+ north, south, west, east = False, False, False, False
+
+ temp = bin(byte)[2:]
+
+ if len(temp) == 1:
+ if temp[0] == "1": #EAST
+ east = True
+ elif len(temp) == 2:
+ if temp[0] == "1": #WEST
+ west = True
+ if temp[1] == "1": #EAST
+ east = True
+ elif len(temp) == 3:
+ if temp[0] == "1": #SOUTH
+ south = True
+ if temp[1] == "1": #WEST
+ west = True
+ if temp[2] == "1": #EAST
+ east = True
+ elif len(temp) == 4:
+ if temp[0] == "1": #NORTH
+ north = True
+ if temp[1] == "1": #SOUTH
+ south = True
+ if temp[2] == "1": #WEST
+ west = True
+ if temp[3] == "1": #EAST
+ east = True
+
+ if north: connections += 1
+ if south: connections += 1
+ if west: connections += 1
+ if east: connections += 1
+
+ #i don't have time to optimize this
+ if connections == 0:
+ return "$00"
+ if connections == 1:
+ if north: return "NORTH"
+ if south: return "SOUTH"
+ if west: return "WEST"
+ if east: return "EAST"
+ if connections >= 2:
+ return write_connections(north, south, west, east)
+
+def connection_pretty_printer(connections):
+#map_id, connected_map_tile_pointer, current_map_tile_pointer, bigness, width, y, x, window_pointer
+ output = ""
+
+ for connection in connections.keys():
+ connection = connections[connection]
+ map_id = hex(connection["map_id"])[2:].zfill(2)
+ connected_map_tile_pointer = connection["connected_map_tile_pointer"][2:]
+ current_map_tile_pointer = connection["current_map_tile_pointer"][2:]
+ bigness = hex(int(connection["bigness"], base))[2:].zfill(2)
+ width = hex(int(connection["width"], base))[2:].zfill(2)
+ y = hex(connection["y"])[2:].zfill(2)
+ x = hex(connection["x"])[2:].zfill(2)
+ window_pointer = connection["window_pointer"][2:]
+
+ output += spacing + "db $" + map_id + " ; some map\n"
+ output += spacing + "dw $" + connected_map_tile_pointer + ", $" + current_map_tile_pointer + " ; pointers (connected, current) (strip)\n"
+ output += spacing + "db $" + bigness + ", $" + width + " ; bigness, width\n"
+ output += spacing + "db $" + y + ", $" + x + " ; alignments (y, x)\n"
+ output += spacing + "dw $" + window_pointer + " ; window\n\n"
+
+ return output
+
+def map_header_pretty_printer(map_header):
+ address = map_header["address"]
+ bank = map_header["bank"]
+ id = map_header["id"]
+
+ name = map_header["name"]
+ asm_name = map_name_cleaner(name, id)
+ if name == "FREEZE": return "" #skip freeze maps
+
+ tileset = map_header["tileset"][2:]
+ y = int(map_header["y"], base)
+ x = int(map_header["x"], base)
+ map_pointer = map_header["map_pointer"]
+ texts_pointer = map_header["texts_pointer"]
+ script_pointer = map_header["script_pointer"]
+ connection_byte = map_header["connection_byte"]
+ connections = map_header["connections"]
+ object_data_pointer = map_header["object_data_pointer"]
+
+ byte_size = 12 + (11 * len(connections.keys()))
+
+ map_pointer = hex(offset_to_pointer(map_pointer))[2:]
+ texts_pointer = hex(offset_to_pointer(texts_pointer))[2:]
+ script_pointer = hex(offset_to_pointer(script_pointer))[2:]
+ object_data_pointer = hex(offset_to_pointer(object_data_pointer))[2:]
+
+ #formatting: hex(y)[2:].zill(2) or "%02x" % (y,)
+
+ output = asm_name + ": ; " + address + " to " + hex(int(address, base) + byte_size) + " (" + str(byte_size) + " bytes) (id=" + str(id) + ")\n"
+ output += spacing + "db $" + str(tileset).zfill(2) + " ; tileset\n"
+ output += spacing + "db $" + hex(y)[2:].zfill(2) + ", $" + hex(x)[2:].zfill(2) + " ; dimensions (y, x)\n"
+ output += spacing + "dw $" + map_pointer + ", $" + texts_pointer + ", $" + script_pointer + " ; blocks, texts, scripts\n"
+ output += spacing + "db " + connection_line(connection_byte) + " ; connections\n\n"
+
+ if len(connections) > 0:
+ output += spacing + "; connections data\n\n"
+ output += connection_pretty_printer(connections)
+ output += spacing + "; end connection data\n\n"
+
+ #TODO: print out label for object_data_pointer if it's already in the file
+ output += spacing + "dw $" + object_data_pointer + " ; objects\n"
+
+ return output
+
+def make_object_label_name(name):
+ """make a label for the asm file
+ like: PalletTownObject"""
+ name = map_name_cleaner(name, None)
+ return name.replace("_h", "") + "Object"
+
+def make_text_label(map_name, id):
+ """using standard object labels
+ for instance, PalletTownText3"""
+ label = map_name_cleaner(map_name, None)[:-2] + "Text" + str(id)
+ return label
+
+def object_data_pretty_printer(map_id):
+ map = extract_maps.map_headers[map_id]
+ output = ""
+
+ label_name = make_object_label_name(map["name"])
+ object_data_pointer = map["object_data_pointer"]
+ object = map["object_data"]
+ size = extract_maps.compute_object_data_size(object)
+
+ output += label_name + ": ; " + object_data_pointer + " (size=" + str(size) + ")\n"
+ output += spacing + "db $" + hex(object["maps_border_tile"])[2:] + " ; border tile\n"
+ output += "\n"
+ output += spacing + "db $" + hex(int(object["number_of_warps"]))[2:] + " ; warps\n"
+
+ #warps
+ for warp_id in object["warps"]:
+ warp = object["warps"][warp_id]
+ y = warp["y"]
+ x = warp["x"]
+ warp_to_point = warp["warp_to_point"]
+ warp_to_map_id = warp["warp_to_map_id"]
+
+ try:
+ warp_to_map_constant = map_constants[warp_to_map_id]
+ except Exception, exc:
+ warp_to_map_constant = "$" + hex(warp_to_map_id)[2:]
+
+ output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(warp_to_point))[2:] + ", " + warp_to_map_constant + "\n"
+
+ output += "\n"
+ output += spacing + "db $" + hex(int(object["number_of_signs"]))[2:] + " ; signs\n"
+
+ #signs
+ for sign_id in object["signs"]:
+ sign = object["signs"][sign_id]
+ y = sign["y"]
+ x = sign["x"]
+ text_id = sign["text_id"]
+
+ output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(text_id))[2:] + " ; " + make_text_label(map["name"], text_id) + "\n"
+
+ output += "\n"
+ output += spacing + "db $" + hex(int(object["number_of_things"]))[2:] + " ; people\n"
+
+ #people
+ for thing_id in object["things"]:
+ thing = object["things"][thing_id]
+
+ ending = ""
+ if thing["type"] == "item":
+ ending = ", $" + hex(int(thing["item_number"]))[2:] + " ; item\n"
+ elif thing["type"] == "trainer":
+ ending = ", $" + hex(int(thing["trainer_type"]))[2:] + ", $" + hex(int(thing["pokemon_set"]))[2:] + " ; trainer\n"
+ else:
+ ending = " ; person\n"
+
+ picture_number = hex(int(thing["picture_number"]))[2:]
+ y = hex(int(thing["y"]) - 4)[2:]
+ x = hex(int(thing["x"]) - 4)[2:]
+ movement1 = hex(int(thing["movement1"]))[2:]
+ movement2 = hex(int(thing["movement2"]))[2:]
+ text_id = hex(int(thing["original_text_string_number"]))[2:]
+
+ output += spacing + "db " + sprite_helper.sprites[thing["picture_number"]] + ", $" + y + " + 4, $" + x + " + 4, $" + movement1 + ", $" + movement2 + ", $" + text_id + ending
+
+ output += "\n"
+
+ if object["number_of_warps"] > 0:
+ output += spacing + "; warp-to\n"
+
+ for warp_to_id in object["warp_tos"]:
+ warp_to = object["warp_tos"][warp_to_id]
+ map_width = map["x"]
+ warp_to_y = hex(int(warp_to["y"]))[2:]
+ warp_to_x = hex(int(warp_to["x"]))[2:]
+
+ try:
+ previous_location = map_constants[object["warps"][warp_to_id]["warp_to_map_id"]]
+ comment = " ; " + previous_location
+ except Exception, exc:
+ comment = ""
+
+ output += spacing + "EVENT_DISP $" + map_width[2:] + ", $" + warp_to_y + ", $" + warp_to_x + comment + "\n"
+ #output += spacing + "dw $" + hex(int(warp_to["event_displacement"][1]))[2:] + hex(int(warp_to["event_displacement"][0]))[2:] + "\n"
+ #output += spacing + "db $" + hex(int(warp_to["y"]))[2:] + ", $" + hex(int(warp_to["x"]))[2:] + "\n"
+ #output += "\n"
+
+ output += "\n"
+
+ while output[-1] == "\n":
+ output = output[:-1]
+
+ output += "\n"
+ return output
+
+def find_all_tx_fars():
+ global all_texts
+ tx_fars = [] #[map_id, text_id, text_pointer, tx_far_pointer, TX_FAR]
+ for map_id in all_texts:
+ map2 = all_texts[map_id]
+ for text_id in map2.keys():
+ text = map2[text_id]
+ for command_id in text.keys():
+ command = text[command_id]
+ if "TX_FAR" in command.keys():
+ TX_FAR = command["TX_FAR"]
+ if TX_FAR[0]["type"] == 0x0:
+ tx_fars.append([map_id, text_id, analyze_texts.get_text_pointer(int(extract_maps.map_headers[map_id]["texts_pointer"], 16), text_id), command["pointer"], TX_FAR])
+ return tx_fars
+
+def tx_far_label_maker(map_name, text_id):
+ label = "_" + map_name_cleaner(map_name, None)[:-2] + "Text" + str(text_id)
+ return label
+
+def tx_far_pretty_printer(tx_far):
+ "pretty output for a tx_far"
+ map_id = tx_far[0]
+ map2 = extract_maps.map_headers[map_id]
+ text_id = tx_far[1]
+ text_pointer = tx_far[2]
+ tx_far_start_address = tx_far[3]
+ text_far = tx_far[4]
+ lines = text_far[0]["lines"]
+ label = tx_far_label_maker(map2["name"], text_id)
+
+ #add the ending byte on the next line
+ #lines[len(lines.keys())+1] = [text_far[1]["type"]]
+
+ #add the ending byte to the last line- always seems $57
+ lines[len(lines.keys())-1].append(text_far[1]["type"])
+
+ output = "\n"
+ output += label + ": ; " + hex(tx_far_start_address) + "\n"
+ first = True
+ for line_id in lines:
+ line = lines[line_id]
+ output += spacing + "db "
+ if first:
+ output += "$0, "
+ first = False
+
+ quotes_open = False
+ first_byte = True
+ was_byte = False
+ byte_count = 0
+ for byte in line:
+ if byte in txt_bytes:
+ if not quotes_open and not first_byte: #start text
+ output += ", \""
+ quotes_open = True
+ first_byte = False
+ if not quotes_open and first_byte: #start text
+ output += "\""
+ quotes_open = True
+ output += txt_bytes[byte]
+ elif byte in constant_abbreviation_bytes:
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+ if not first_byte:
+ output += ", "
+ output += constant_abbreviation_bytes[byte]
+ else:
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+
+ #if you want the ending byte on the last line
+ #if not (byte == 0x57 or byte == 0x50 or byte == 0x58):
+ if not first_byte:
+ output += ", "
+
+ output += "$" + hex(byte)[2:]
+ was_byte = True
+
+ #add a comma unless it's the end of the line
+ #if byte_count+1 != len(line):
+ # output += ", "
+
+ first_byte = False
+ byte_count += 1
+ #close final quotes
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+
+ output += "\n"
+
+ #output += "\n"
+ return output
+
+def print_all_headers():
+ maps = []
+ for map in extract_maps.map_headers:
+ maps.append(extract_maps.map_headers[map])
+
+ maps = sorted(maps, key=lambda map: int(map["address"], base))
+
+ for map in maps:
+ output = map_header_pretty_printer(map)
+ if output != "": print output
+
+if __name__ == "__main__":
+ #read binary data from file
+ extract_maps.load_rom()
+
+ #where are the map structs?
+ extract_maps.load_map_pointers()
+
+ #load map headers into memory
+ extract_maps.read_all_map_headers()
+
+ #load texts
+ all_texts = analyze_texts.analyze_texts()
+
+ #print them out
+ #print_all_headers()
+
+ #print out only the object data for pallet town (map 0)
+ #print object_data_pretty_printer(0)
+
+ #prepare to pretty print tx_fars
+ #first you must load all_texts
+ #tx_fars = find_all_tx_fars()
+ #for entry in tx_fars:
+ # print tx_far_pretty_printer(entry)