pretty printer for object labels and asm

hg-commit-id: 9bde3604346f
This commit is contained in:
Bryan Bishop 2012-01-05 12:49:17 -06:00
parent 78aa8a08a4
commit 238a5e62ae
3 changed files with 353 additions and 5 deletions

View file

@ -513,6 +513,7 @@ def get_object_data(address):
thing["x"] = x
thing["movement1"] = movement1
thing["movement2"] = movement2
thing["original_text_string_number"] = text_string_number
thing["text_string_number"] = text_string_number & 0xF
things[thing_id] = thing
@ -529,6 +530,25 @@ def get_object_data(address):
return output
def compute_object_data_size(object):
size = 4
size += 6 * (object["number_of_things"])
trainer_count = 0
item_count = 0
for thing in object["things"]:
thing = object["things"][thing]
if thing["type"] == "trainer": trainer_count += 1
elif thing["type"] == "item": item_count += 1
size += 2 * trainer_count
size += item_count
size += 8 * object["number_of_warps"]
size += 3 * object["number_of_signs"]
return size
def read_map_header(address, bank):
address = int(address, base)
bank = int(bank, base)
@ -646,7 +666,6 @@ def read_all_map_headers():
return map_headers
if __name__ == "__main__":
#read binary data from file
load_rom()

View file

@ -10,6 +10,240 @@ import string
base = 16
spacing = " "
#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
#this was originally for renaming freeze maps for a unique name
def random_hash():
available_chars = string.hexdigits[:16]
@ -26,7 +260,7 @@ def map_name_cleaner(name, id):
#duck out early
if name == "FREEZE":
name += "_" + random_hash() + "_h"
#name += "_" + random_hash() + "_h"
name += "_" + str(id) + "_h"
return name
@ -170,10 +404,102 @@ def map_header_pretty_printer(map_header):
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 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"]
warp_to_map_constant = map_constants[warp_to_map_id]
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:] + "\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 $" + picture_number + ", $" + y + " + 4, $" + x + " + 4, $" + movement1 + ", $" + movement2 + ", $" + text_id + ending
output += "\n"
if object["number_of_warps"] > 0:
output += spacing + "; warp-to\n"
output += "\n"
#TODO: use EVENT_DISP per sawakita
for warp_to_id in object["warp_tos"]:
warp_to = object["warp_tos"][warp_to_id]
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 print_all_headers():
maps = []
for map in extract_maps.map_headers:
@ -196,4 +522,7 @@ if __name__ == "__main__":
extract_maps.read_all_map_headers()
#print them out
print_all_headers()
#print_all_headers()
#print out only the object data for pallet town (map 0)
print object_data_pretty_printer(0)

View file

@ -4986,7 +4986,7 @@ PalletTown_h:
dw PalletTownObject
PalletTownObject: ; 182C3
PalletTownObject: ; 182C3 0x182c3
db $0B ; border tile
db 3 ; warps
@ -5016,7 +5016,7 @@ PalletTownObject: ; 182C3
dw $C74F
db $B,$C
PalletTownBlocks:
PalletTownBlocks: ; 0x182fd
INCBIN "maps/pallettown.blk"
ViridianCity_h: ; 0x18357 to 0x18384 (45 bytes) (bank=6) (id=1)