mirror of
https://github.com/thornAvery/kep-hack.git
synced 2025-09-17 02:40:50 +12:00
tool to dump asm for each map header
hg-commit-id: 812226d99dc0
This commit is contained in:
parent
020ccf422a
commit
d74daf3273
196
extras/pretty_map_headers.py
Normal file
196
extras/pretty_map_headers.py
Normal file
|
@ -0,0 +1,196 @@
|
|||
#!/usr/bin/python
|
||||
#author: Bryan Bishop <kanzure@gmail.com>
|
||||
#date: 2012-01-02
|
||||
#purpose: dump asm for each map header
|
||||
import json
|
||||
import extract_maps
|
||||
import random
|
||||
import string
|
||||
|
||||
base = 16
|
||||
spacing = " "
|
||||
|
||||
#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 + "db $" + 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 = int(map_header["tileset"], base)
|
||||
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) (bank=" + str(int(bank, base)) + ") (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"
|
||||
output += spacing + "; connections data\n\n"
|
||||
output += connection_pretty_printer(connections)
|
||||
output += spacing + "; end connection data\n\n"
|
||||
output += spacing + "dw $" + object_data_pointer + " ; objects\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()
|
||||
|
||||
#print them out
|
||||
print_all_headers()
|
Loading…
Reference in a new issue