2012-01-03 20:18:11 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
#author: Bryan Bishop <kanzure@gmail.com>
|
|
|
|
#date: 2012-01-03
|
|
|
|
#purpose: map which addresses are left
|
|
|
|
import sys, os
|
|
|
|
from copy import copy, deepcopy
|
|
|
|
import subprocess
|
2012-01-03 23:13:46 +00:00
|
|
|
from extract_maps import rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers
|
|
|
|
from pretty_map_headers import map_header_pretty_printer, map_name_cleaner
|
2012-01-03 20:18:11 +00:00
|
|
|
|
|
|
|
#store each line of source code here
|
|
|
|
asm = None
|
|
|
|
|
|
|
|
#store each incbin line separately
|
|
|
|
incbin_lines = []
|
|
|
|
|
|
|
|
#storage for processed incbin lines
|
|
|
|
processed_incbins = {}
|
|
|
|
|
|
|
|
def offset_to_pointer(offset):
|
|
|
|
if type(offset) == str: offset = int(offset, base)
|
|
|
|
return int(offset) % 0x4000 + 0x4000
|
|
|
|
|
|
|
|
def load_asm(filename="../pokered.asm"):
|
|
|
|
"loads the asm source code into memory"
|
|
|
|
global asm
|
|
|
|
asm = open(filename, "r").read().split("\n")
|
|
|
|
return asm
|
|
|
|
|
|
|
|
def isolate_incbins():
|
|
|
|
"find each incbin line"
|
|
|
|
global incbin_lines
|
|
|
|
incbin_lines = []
|
|
|
|
for line in asm:
|
|
|
|
if line == "": continue
|
|
|
|
|
|
|
|
#clean up whitespace at beginning of line
|
|
|
|
while line[0] == " ":
|
|
|
|
line = line[1:]
|
|
|
|
|
|
|
|
if line[0:6] == "INCBIN" and "baserom.gbc" in line:
|
|
|
|
incbin_lines.append(line)
|
|
|
|
return incbin_lines
|
|
|
|
|
|
|
|
def process_incbins():
|
|
|
|
"parse incbin lines into memory"
|
|
|
|
global incbins
|
|
|
|
incbins = {} #reset
|
|
|
|
for incbin in incbin_lines:
|
|
|
|
processed_incbin = {}
|
|
|
|
|
|
|
|
line_number = asm.index(incbin)
|
|
|
|
|
|
|
|
partial_start = incbin[21:]
|
|
|
|
start = partial_start.split(",")[0].replace("$", "0x")
|
|
|
|
start = eval(start)
|
|
|
|
start_hex = hex(start).replace("0x", "$")
|
|
|
|
|
|
|
|
partial_interval = incbin[21:].split(",")[1]
|
|
|
|
partial_interval = partial_interval.replace(";", "#")
|
2012-01-03 23:13:46 +00:00
|
|
|
partial_interval = partial_interval.replace("$", "0x").replace("0xx", "0x")
|
2012-01-03 20:18:11 +00:00
|
|
|
interval = eval(partial_interval)
|
2012-01-03 23:13:46 +00:00
|
|
|
interval_hex = hex(interval).replace("0x", "$").replace("x", "")
|
2012-01-03 20:18:11 +00:00
|
|
|
|
|
|
|
end = start + interval
|
|
|
|
end_hex = hex(end).replace("0x", "$")
|
|
|
|
|
|
|
|
processed_incbin = {
|
|
|
|
"line_number": line_number,
|
|
|
|
"line": incbin,
|
|
|
|
"start": start,
|
|
|
|
"interval": interval,
|
|
|
|
"end": end,
|
|
|
|
}
|
|
|
|
|
|
|
|
processed_incbins[line_number] = processed_incbin
|
|
|
|
|
|
|
|
def find_incbin_to_replace_for(address):
|
|
|
|
"""returns a line number for which incbin to edit
|
|
|
|
if you were to insert bytes into pokered.asm"""
|
2012-01-03 23:13:46 +00:00
|
|
|
if type(address) == str: address = int(address, 16)
|
2012-01-03 20:18:11 +00:00
|
|
|
|
|
|
|
for incbin_key in processed_incbins.keys():
|
|
|
|
incbin = processed_incbins[incbin_key]
|
|
|
|
|
|
|
|
start = incbin["start"]
|
|
|
|
end = incbin["end"]
|
2012-01-03 23:13:46 +00:00
|
|
|
|
|
|
|
print "start is: " + str(start)
|
|
|
|
print "end is: " + str(end)
|
|
|
|
print "address is: " + str(type(address))
|
|
|
|
print "checking.... " + hex(start) + " <= " + hex(address) + " <= " + hex(end)
|
|
|
|
|
2012-01-03 20:18:11 +00:00
|
|
|
if start <= address <= end:
|
|
|
|
return incbin_key
|
|
|
|
return None
|
|
|
|
|
|
|
|
def split_incbin_line_into_three(line, start_address, byte_count):
|
|
|
|
"""
|
|
|
|
splits an incbin line into three pieces.
|
|
|
|
you can replace the middle one with the new content of length bytecount
|
|
|
|
|
|
|
|
start_address: where you want to start inserting bytes
|
|
|
|
byte_count: how many bytes you will be inserting
|
|
|
|
"""
|
|
|
|
if type(start_address) == str: start_address = int(start_address, 16)
|
|
|
|
|
|
|
|
original_incbin = processed_incbins[line]
|
|
|
|
start = original_incbin["start"]
|
|
|
|
end = original_incbin["end"]
|
|
|
|
|
|
|
|
#start, end1, end2 (to be printed as start, end1 - end2)
|
|
|
|
if start_address - start > 0:
|
|
|
|
first = (start, start_address, start)
|
|
|
|
else:
|
|
|
|
first = (None) #skip this one because we're not including anything
|
|
|
|
|
|
|
|
#this is the one you will replace with whatever content
|
|
|
|
second = (start_address, byte_count)
|
|
|
|
|
|
|
|
third = (start_address + byte_count, end - (start_address + byte_count))
|
|
|
|
|
|
|
|
output = ""
|
|
|
|
|
|
|
|
if first:
|
|
|
|
output += "INCBIN \"baserom.gbc\",$" + hex(first[0])[2:] + ",$" + hex(first[1])[2:] + " - $" + hex(first[2])[2:] + "\n"
|
|
|
|
output += "INCBIN \"baserom.gbc\",$" + hex(second[0])[2:] + "," + str(byte_count) + "\n"
|
|
|
|
output += "INCBIN \"baserom.gbc\",$" + hex(third[0])[2:] + ",$" + hex(third[1])[2:] #no newline
|
|
|
|
return output
|
|
|
|
|
|
|
|
def generate_diff_insert(line_number, newline):
|
|
|
|
original = "\n".join(line for line in asm)
|
|
|
|
newfile = deepcopy(asm)
|
|
|
|
newfile[line_number] = newline #possibly inserting multiple lines
|
|
|
|
newfile = "\n".join(line for line in newfile)
|
|
|
|
|
|
|
|
original_filename = "ejroqjfoad.temp"
|
|
|
|
newfile_filename = "fjiqefo.temp"
|
|
|
|
|
|
|
|
original_fh = open(original_filename, "w")
|
|
|
|
original_fh.write(original)
|
|
|
|
original_fh.close()
|
|
|
|
|
|
|
|
newfile_fh = open(newfile_filename, "w")
|
|
|
|
newfile_fh.write(newfile)
|
|
|
|
newfile_fh.close()
|
|
|
|
|
|
|
|
try:
|
2012-01-03 23:13:46 +00:00
|
|
|
diffcontent = subprocess.check_output("diff -u ../pokered.asm " + newfile_filename, shell=True)
|
2012-01-03 20:18:11 +00:00
|
|
|
except Exception, exc:
|
|
|
|
diffcontent = exc.output
|
|
|
|
|
|
|
|
os.system("rm " + original_filename)
|
|
|
|
os.system("rm " + newfile_filename)
|
|
|
|
|
|
|
|
return diffcontent
|
|
|
|
|
2012-01-03 23:13:46 +00:00
|
|
|
def insert_map_header_asm(map_id):
|
|
|
|
map = map_headers[map_id]
|
|
|
|
line_number = find_incbin_to_replace_for(map["address"])
|
|
|
|
if line_number == None: # or map_name_cleaner(map["name"], 0) in "\n".join(line for line in asm):
|
|
|
|
print "i think map id=" + str(map_id) + " has previously been added."
|
|
|
|
return #this map has already been added i bet
|
|
|
|
newlines = split_incbin_line_into_three(line_number, map["address"], 12 + (11 * len(map["connections"])))
|
|
|
|
|
|
|
|
map_header_asm = map_header_pretty_printer(map_headers[map_id])
|
|
|
|
|
|
|
|
newlines = newlines.split("\n")
|
|
|
|
if len(newlines) == 2: index = 0
|
|
|
|
elif len(newlines) == 3:
|
|
|
|
index = 1
|
|
|
|
newlines[0] += "\n" #spacing is a nice thing to have
|
|
|
|
newlines[index] = map_header_asm
|
|
|
|
newlines = "\n".join(line for line in newlines)
|
|
|
|
|
|
|
|
diff = generate_diff_insert(line_number, newlines)
|
|
|
|
|
|
|
|
print diff
|
|
|
|
print "... Applying diff."
|
|
|
|
|
|
|
|
#write the diff to a file
|
|
|
|
fh = open("temp.patch", "w")
|
|
|
|
fh.write(diff)
|
|
|
|
fh.close()
|
|
|
|
|
|
|
|
#apply the patch
|
|
|
|
os.system("patch ../pokered.asm temp.patch")
|
|
|
|
|
|
|
|
#remove the patch
|
|
|
|
os.system("rm temp.patch")
|
|
|
|
|
|
|
|
def wrapper_insert_map_header_asm(map_id):
|
|
|
|
"reload the asm because it has changed (probably)"
|
|
|
|
load_asm()
|
|
|
|
isolate_incbins()
|
|
|
|
process_incbins()
|
|
|
|
insert_map_header_asm(map_id)
|
|
|
|
|
|
|
|
def dump_all_remaining_maps():
|
|
|
|
for map_id in map_headers:
|
|
|
|
print "Inserting map id=" + str(map_id)
|
|
|
|
wrapper_insert_map_header_asm(map_id)
|
|
|
|
|
2012-01-03 20:18:11 +00:00
|
|
|
if __name__ == "__main__":
|
2012-01-03 23:13:46 +00:00
|
|
|
#load map headers
|
|
|
|
load_rom()
|
|
|
|
load_map_pointers()
|
|
|
|
read_all_map_headers()
|
|
|
|
|
|
|
|
#load incbins (mandatory)
|
2012-01-03 20:18:11 +00:00
|
|
|
load_asm()
|
|
|
|
isolate_incbins()
|
|
|
|
process_incbins() #print processed_incbins
|
|
|
|
|
2012-01-03 23:13:46 +00:00
|
|
|
#line_number = find_incbin_to_replace_for(0x492c3)
|
|
|
|
#newlines = split_incbin_line_into_three(line_number, 0x492c3, 12)
|
|
|
|
#diff = generate_diff_insert(line_number, newlines)
|
|
|
|
#print diff
|
|
|
|
|
2012-01-03 23:15:42 +00:00
|
|
|
insert_map_header_asm(86)
|
2012-01-03 23:13:46 +00:00
|
|
|
#dump_all_remaining_maps()
|
2012-01-03 20:18:11 +00:00
|
|
|
|