2012-01-03 03:26:32 +00:00
|
|
|
#!/usr/bin/python
|
2012-01-07 07:34:22 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2012-01-03 03:26:32 +00:00
|
|
|
#author: Bryan Bishop <kanzure@gmail.com>
|
|
|
|
#date: 2012-01-02
|
|
|
|
#purpose: dump asm for each map header
|
|
|
|
import json
|
|
|
|
import extract_maps
|
2012-01-06 01:51:32 +00:00
|
|
|
import sprite_helper
|
2012-01-03 03:26:32 +00:00
|
|
|
import random
|
|
|
|
import string
|
2012-01-10 04:24:04 +00:00
|
|
|
import analyze_texts #hopefully not a dependency loop
|
2012-01-03 03:26:32 +00:00
|
|
|
|
|
|
|
base = 16
|
|
|
|
spacing = " "
|
2012-01-07 07:34:22 +00:00
|
|
|
all_texts = None
|
2012-01-03 03:26:32 +00:00
|
|
|
|
2012-01-05 18:49:17 +00:00
|
|
|
#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
|
|
|
|
|
2012-01-07 07:34:22 +00:00
|
|
|
#these appear outside of quotes
|
|
|
|
constant_abbreviation_bytes = {
|
|
|
|
0x4A: "Char4A",
|
|
|
|
0x52: "Char52",
|
|
|
|
0x53: "Char53",
|
|
|
|
0x54: "Char54",
|
|
|
|
0x56: "Char56",
|
|
|
|
0x5B: "Char5B",
|
|
|
|
0x5C: "Char5C",
|
|
|
|
0x5D: "Char5D",
|
|
|
|
0x5E: "Char5E",
|
|
|
|
}
|
|
|
|
|
|
|
|
#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),
|
2012-01-07 18:11:12 +00:00
|
|
|
("'d", 0xBB),
|
|
|
|
("'l", 0xBC),
|
2012-01-07 07:34:22 +00:00
|
|
|
("'s", 0xBD),
|
|
|
|
("'t", 0xBE),
|
2012-01-07 18:11:12 +00:00
|
|
|
("'v", 0xBF),
|
2012-01-07 07:34:22 +00:00
|
|
|
("'", 0xE0),
|
|
|
|
("-", 0xE3),
|
2012-01-07 18:11:12 +00:00
|
|
|
("'r", 0xE4),
|
|
|
|
("'m", 0xE5),
|
2012-01-07 07:34:22 +00:00
|
|
|
("?", 0xE6),
|
|
|
|
("!", 0xE7),
|
|
|
|
(".", 0xE8),
|
|
|
|
("♂", 0xEF),
|
|
|
|
("/", 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
|
|
|
|
|
2012-01-03 03:26:32 +00:00
|
|
|
#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":
|
2012-01-05 18:49:17 +00:00
|
|
|
#name += "_" + random_hash() + "_h"
|
2012-01-03 03:26:32 +00:00
|
|
|
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"
|
2012-01-03 04:23:58 +00:00
|
|
|
output += spacing + "dw $" + connected_map_tile_pointer + ", $" + current_map_tile_pointer + " ; pointers (connected, current) (strip)\n"
|
2012-01-03 03:26:32 +00:00
|
|
|
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
|
|
|
|
|
2012-01-03 07:18:32 +00:00
|
|
|
tileset = map_header["tileset"][2:]
|
2012-01-03 03:26:32 +00:00
|
|
|
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,)
|
|
|
|
|
2012-01-03 22:09:16 +00:00
|
|
|
output = asm_name + ": ; " + address + " to " + hex(int(address, base) + byte_size) + " (" + str(byte_size) + " bytes) (id=" + str(id) + ")\n"
|
2012-01-03 03:26:32 +00:00
|
|
|
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"
|
2012-01-03 22:46:26 +00:00
|
|
|
|
|
|
|
if len(connections) > 0:
|
|
|
|
output += spacing + "; connections data\n\n"
|
|
|
|
output += connection_pretty_printer(connections)
|
|
|
|
output += spacing + "; end connection data\n\n"
|
|
|
|
|
2012-01-05 18:49:17 +00:00
|
|
|
#TODO: print out label for object_data_pointer if it's already in the file
|
2012-01-03 03:26:32 +00:00
|
|
|
output += spacing + "dw $" + object_data_pointer + " ; objects\n"
|
|
|
|
|
|
|
|
return output
|
|
|
|
|
2012-01-05 18:49:17 +00:00
|
|
|
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"
|
|
|
|
|
2012-01-06 01:51:32 +00:00
|
|
|
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
|
|
|
|
|
2012-01-05 18:49:17 +00:00
|
|
|
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"]
|
|
|
|
|
2012-01-06 02:57:41 +00:00
|
|
|
try:
|
|
|
|
warp_to_map_constant = map_constants[warp_to_map_id]
|
|
|
|
except Exception, exc:
|
|
|
|
warp_to_map_constant = "$" + hex(warp_to_map_id)[2:]
|
2012-01-05 18:49:17 +00:00
|
|
|
|
|
|
|
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"]
|
|
|
|
|
2012-01-06 01:51:32 +00:00
|
|
|
output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(text_id))[2:] + " ; " + make_text_label(map["name"], text_id) + "\n"
|
2012-01-05 18:49:17 +00:00
|
|
|
|
|
|
|
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:]
|
|
|
|
|
2012-01-06 01:51:32 +00:00
|
|
|
output += spacing + "db " + sprite_helper.sprites[thing["picture_number"]] + ", $" + y + " + 4, $" + x + " + 4, $" + movement1 + ", $" + movement2 + ", $" + text_id + ending
|
2012-01-05 18:49:17 +00:00
|
|
|
|
|
|
|
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]
|
2012-01-05 23:10:21 +00:00
|
|
|
map_width = map["x"]
|
|
|
|
warp_to_y = hex(int(warp_to["y"]))[2:]
|
|
|
|
warp_to_x = hex(int(warp_to["x"]))[2:]
|
|
|
|
|
2012-01-06 02:57:41 +00:00
|
|
|
try:
|
|
|
|
previous_location = map_constants[object["warps"][warp_to_id]["warp_to_map_id"]]
|
|
|
|
comment = " ; " + previous_location
|
|
|
|
except Exception, exc:
|
|
|
|
comment = ""
|
2012-01-06 01:51:32 +00:00
|
|
|
|
2012-01-06 02:57:41 +00:00
|
|
|
output += spacing + "EVENT_DISP $" + map_width[2:] + ", $" + warp_to_y + ", $" + warp_to_x + comment + "\n"
|
2012-01-05 23:10:21 +00:00
|
|
|
#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"
|
2012-01-06 01:51:32 +00:00
|
|
|
#output += "\n"
|
2012-01-05 18:49:17 +00:00
|
|
|
|
|
|
|
output += "\n"
|
|
|
|
|
|
|
|
while output[-1] == "\n":
|
|
|
|
output = output[:-1]
|
|
|
|
|
|
|
|
output += "\n"
|
|
|
|
return output
|
|
|
|
|
2012-01-07 07:34:22 +00:00
|
|
|
def find_all_tx_fars():
|
|
|
|
global all_texts
|
2012-01-07 21:13:24 +00:00
|
|
|
tx_fars = [] #[map_id, text_id, text_pointer, tx_far_pointer, TX_FAR]
|
2012-01-07 07:34:22 +00:00
|
|
|
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:
|
2012-01-07 21:13:24 +00:00
|
|
|
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])
|
2012-01-07 07:34:22 +00:00
|
|
|
return tx_fars
|
|
|
|
|
2012-01-07 21:13:24 +00:00
|
|
|
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):
|
2012-01-07 07:34:22 +00:00
|
|
|
"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"]
|
2012-01-07 21:13:24 +00:00
|
|
|
label = tx_far_label_maker(map2["name"], text_id)
|
2012-01-07 07:34:22 +00:00
|
|
|
|
2012-01-07 18:11:12 +00:00
|
|
|
#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"])
|
|
|
|
|
2012-01-07 21:13:24 +00:00
|
|
|
output = "\n"
|
|
|
|
output += label + ": ; " + hex(tx_far_start_address) + "\n"
|
2012-01-07 07:34:22 +00:00
|
|
|
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
|
2012-01-07 18:11:12 +00:00
|
|
|
was_byte = False
|
2012-01-07 07:34:22 +00:00
|
|
|
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
|
2012-01-07 18:11:12 +00:00
|
|
|
if not first_byte:
|
|
|
|
output += ", "
|
|
|
|
output += constant_abbreviation_bytes[byte]
|
2012-01-07 07:34:22 +00:00
|
|
|
else:
|
|
|
|
if quotes_open:
|
|
|
|
output += "\""
|
|
|
|
quotes_open = False
|
2012-01-07 18:11:12 +00:00
|
|
|
|
|
|
|
#if you want the ending byte on the last line
|
|
|
|
#if not (byte == 0x57 or byte == 0x50 or byte == 0x58):
|
2012-01-07 21:13:24 +00:00
|
|
|
if not first_byte:
|
|
|
|
output += ", "
|
2012-01-07 18:11:12 +00:00
|
|
|
|
|
|
|
output += "$" + hex(byte)[2:]
|
|
|
|
was_byte = True
|
2012-01-07 07:34:22 +00:00
|
|
|
|
|
|
|
#add a comma unless it's the end of the line
|
2012-01-07 18:11:12 +00:00
|
|
|
#if byte_count+1 != len(line):
|
|
|
|
# output += ", "
|
|
|
|
|
|
|
|
first_byte = False
|
2012-01-07 07:34:22 +00:00
|
|
|
byte_count += 1
|
|
|
|
#close final quotes
|
|
|
|
if quotes_open:
|
|
|
|
output += "\""
|
|
|
|
quotes_open = False
|
|
|
|
|
|
|
|
output += "\n"
|
|
|
|
|
2012-01-07 21:13:24 +00:00
|
|
|
#output += "\n"
|
2012-01-07 07:34:22 +00:00
|
|
|
return output
|
|
|
|
|
2012-01-03 03:26:32 +00:00
|
|
|
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()
|
|
|
|
|
2012-01-07 07:34:22 +00:00
|
|
|
#load texts
|
|
|
|
all_texts = analyze_texts.analyze_texts()
|
|
|
|
|
2012-01-03 03:26:32 +00:00
|
|
|
#print them out
|
2012-01-05 18:49:17 +00:00
|
|
|
#print_all_headers()
|
|
|
|
|
|
|
|
#print out only the object data for pallet town (map 0)
|
2012-01-07 07:34:22 +00:00
|
|
|
#print object_data_pretty_printer(0)
|
|
|
|
|
2012-01-07 21:13:24 +00:00
|
|
|
#prepare to pretty print tx_fars
|
|
|
|
#first you must load all_texts
|
2012-01-07 07:34:22 +00:00
|
|
|
tx_fars = find_all_tx_fars()
|
|
|
|
for entry in tx_fars:
|
2012-01-07 21:13:24 +00:00
|
|
|
print tx_far_pretty_printer(entry)
|