diff options
author | stag019 <stag019@gmail.com> | 2012-01-18 01:45:10 -0500 |
---|---|---|
committer | stag019 <stag019@gmail.com> | 2012-01-18 01:45:10 -0500 |
commit | 549637d0dfbb0adedcd6b05ec028c58044c8c46f (patch) | |
tree | 7a0cebc72707797842f284d1bcaa6c2f543f24c8 /extras | |
parent | 73d483e5d48df6ca9177172e0dc0a3d690af6e1d (diff) | |
parent | 25cc7be1a5e1ab2484bbfacf35033ffb5259baba (diff) |
fucking you and yours
hg-commit-id: 8a2a1f3736f2
Diffstat (limited to 'extras')
-rw-r--r-- | extras/analyze_incbins.py | 7 | ||||
-rw-r--r-- | extras/analyze_texts.py | 198 | ||||
-rw-r--r-- | extras/insert_texts.py | 82 | ||||
-rw-r--r-- | extras/pretty_map_headers.py | 1 |
4 files changed, 249 insertions, 39 deletions
diff --git a/extras/analyze_incbins.py b/extras/analyze_incbins.py index 353e5ea6..9069a3ae 100644 --- a/extras/analyze_incbins.py +++ b/extras/analyze_incbins.py @@ -79,7 +79,9 @@ def process_incbins(): "end": end, } - processed_incbins[line_number] = processed_incbin + #don't add this incbin if the interval is 0 + if interval != 0: + processed_incbins[line_number] = processed_incbin def find_incbin_to_replace_for(address): """returns a line number for which incbin to edit @@ -235,7 +237,8 @@ def apply_diff(diff, try_fixing=True): #confirm it's working try: - subprocess.check_call("cd ../; make clean; LC_CTYPE=UTF-8 make", shell=True) + subprocess.check_call("cd ../; make clean; LC_CTYPE=C make", shell=True) + return True except Exception, exc: if try_fixing: os.system("mv ../common1.asm ../common.asm") diff --git a/extras/analyze_texts.py b/extras/analyze_texts.py index 36d80413..30a6b5dc 100644 --- a/extras/analyze_texts.py +++ b/extras/analyze_texts.py @@ -226,7 +226,7 @@ def parse_text_script(text_pointer, text_id, map_id, txfar=False): "read_byte": read_byte, #split this up when we make a macro for this } - offset += 4 + 1 + offset += 4 elif command_byte == 0xB: #0B = sound_86 (Hiro obtains ITEM)[same as 0F] command = {"type": command_byte, "start_address": offset, "end_address": offset} @@ -385,34 +385,109 @@ def find_missing_08s(all_texts): def text_pretty_printer_at(start_address, label="SomeLabel"): commands = parse_text_script(start_address, None, None) - needs_to_begin_with_0 = False + needs_to_begin_with_0 = True #how should this be determined? - wanted_command = None - if needs_to_begin_with_0: - wanted_command = None - for command_id in commands: - command = commands[command_id] - if command["type"] == 0: - wanted_command = command_id - - if wanted_command == None: - raise "error: address did not start with a $0 text" + #wanted_command = None + #if needs_to_begin_with_0: + # wanted_command = None + # for command_id in commands: + # command = commands[command_id] + # if command["type"] == 0: + # wanted_command = command_id + # + # if wanted_command == None: + # raise "error: address did not start with a $0 text" #start with zero please byte_count = 0 + had_text_end_byte = False + had_text_end_byte_57_58 = False + had_db_last = False first_line = True for this_command in commands.keys(): - if not "lines" in commands[this_command].keys(): continue + if not "lines" in commands[this_command].keys(): + command = commands[this_command] + if not "type" in command.keys(): + print "ERROR in command: " + str(command) + continue #dunno what to do here? + + if command["type"] == 0x1: #TX_RAM + if first_line: + output = "\n" + output += label + ": ; " + hex(start_address) + first_line = False + p1 = command["pointer"][0] + p2 = command["pointer"][1] + + #remember to account for big endian -> little endian + output += "\n" + spacing + "TX_RAM $%.2x%.2x" %(p2, p1) + byte_count += 3 + had_db_last = False + elif command["type"] == 0x17: #TX_FAR + if first_line: + output = "\n" + output += label + ": ; " + hex(start_address) + first_line = False + #p1 = command["pointer"][0] + #p2 = command["pointer"][1] + output += "\n" + spacing + "TX_FAR _" + label + byte_count += 4 #$17, bank, address word + had_db_last = False + elif command["type"] == 0x9: #TX_RAM_HEX2DEC + if first_line: + output = "\n" + label + ": ; " + hex(start_address) + first_line = False + #address, read_byte + output += "\n" + spacing + "TX_NUM $%.2x%.2x, $%.2x" % (command["address"][1], command["address"][0], command["read_byte"]) + had_db_last = False + byte_count += 4 + elif command["type"] == 0x50 and not had_text_end_byte: + #had_text_end_byte helps us avoid repeating $50s + if first_line: + output = "\n" + label + ": ; " + hex(start_address) + first_line = False + if had_db_last: + output += ", $50" + else: + output += "\n" + spacing + "db $50" + byte_count += 1 + had_db_last = True + elif command["type"] in [0x57, 0x58] and not had_text_end_byte_57_58: + if first_line: #shouldn't happen, really + output = "\n" + label + ": ; " + hex(start_address) + first_line = False + if had_db_last: + output += ", $%.2x" % (command["type"]) + else: + output += "\n" + spacing + "db $%.2x" % (command["type"]) + byte_count += 1 + had_db_last = True + elif command["type"] in [0x57, 0x58] and had_text_end_byte_57_58: + pass #this is ok + elif command["type"] == 0x50 and had_text_end_byte: + pass #this is also ok + else: + print "ERROR in command: " + hex(command["type"]) + had_db_last = False + + #everything else is for $0s, really + continue lines = commands[this_command]["lines"] + + #reset this in case we have non-$0s later + had_db_last = False #add the ending byte to the last line- always seems $57 - lines[len(lines.keys())-1].append(commands[1]["type"]) + #this should already be in there, but it's not because of a bug in the text parser + lines[len(lines.keys())-1].append(commands[len(commands.keys())-1]["type"]) if first_line: output = "\n" output += label + ": ; " + hex(start_address) + "\n" first_line = False + else: + output += "\n" first = True #first byte for line_id in lines: @@ -421,11 +496,17 @@ def text_pretty_printer_at(start_address, label="SomeLabel"): if first and needs_to_begin_with_0: output += "$0, " first = False + byte_count += 1 quotes_open = False first_byte = True was_byte = False for byte in line: + if byte == 0x50: + had_text_end_byte = True #don't repeat it + if byte in [0x58, 0x57]: + had_text_end_byte_57_58 = True + if byte in txt_bytes: if not quotes_open and not first_byte: #start text output += ", \"" @@ -467,9 +548,10 @@ def text_pretty_printer_at(start_address, label="SomeLabel"): quotes_open = False output += "\n" - - #output += "\n" - output += "; " + hex(start_address + byte_count) + include_newline = "\n" + if output[-1] == "\n": + include_newline = "" + output += include_newline + "; " + hex(start_address) + " + " + str(byte_count) + " bytes" print output return (output, byte_count) @@ -515,27 +597,87 @@ def find_undone_texts(): for result in sorted_results: print str(result[1]) + " times: " + hex(result[0]) +def scan_rom_for_tx_fars(printer=True): + """find TX_FARs + search only addresses that are INCBINed + keep only TX_FARs that are valid + + returns a list of [TX_FAR target address, TX_FAR address]""" + rom = extract_maps.rom + + analyze_incbins.load_asm() + analyze_incbins.isolate_incbins() + analyze_incbins.process_incbins() + + possible_tx_fars = [] + possible_tx_far_targets = [] + + for incbin_line_number in analyze_incbins.processed_incbins.keys(): + incbin = analyze_incbins.processed_incbins[incbin_line_number] + start_address = incbin["start"] + end_address = incbin["end"] + if incbin["interval"] == 0: continue #skip this one + + subrom = rom[start_address:end_address] + for address in range(start_address, end_address): + current_byte = ord(rom[address]) + if current_byte == 0x17: + if ord(rom[address+4]) == 0x50: + byte1 = ord(rom[address+1]) + byte2 = ord(rom[address+2]) + address2 = byte1 + (byte2 << 8) + if address2 > 0x3fff: + address2 = extract_maps.calculate_pointer(address2, ord(rom[address+3])) + #print "possible TX_FAR at " + hex(address) + " to " + hex(address2) + + possible_tx_fars.append(address) + possible_tx_far_targets.append([address2, address]) + + if printer: + pre_handled = [] + #address_bundle is [TX_FAR target address, TX_FAR address] + for address_bundle in possible_tx_far_targets: + if address_bundle[0] in [0xa82f8, 0xa8315]: + continue #bad + if address_bundle[0] in pre_handled: + continue #already did this + + print "-------" + print "TX_FAR is at: " + hex(address_bundle[1]) + + #let's try printing out the TX_FAR? + text_pretty_printer_at(address_bundle[1], "blah") + + text_pretty_printer_at(address_bundle[0], "_blah") + print "-------" + pre_handled.append(address_bundle[0]) + return possible_tx_far_targets + if __name__ == "__main__": extract_maps.load_rom() extract_maps.load_map_pointers() extract_maps.read_all_map_headers() - text_output = analyze_texts() + #text_output = analyze_texts() #print text_output - missing_08s = find_missing_08s(text_output) + #these aren't really "missing", just a certain type that was + #known to be missed on a first pass. + #missing_08s = find_missing_08s(text_output) - print "\n\n---- stats ----\n\n" + #print "\n\n---- stats ----\n\n" - popular_text_commands = sorted(totals.iteritems(), key=itemgetter(1), reverse=True) + #popular_text_commands = sorted(totals.iteritems(), key=itemgetter(1), reverse=True) #convert the first values (command byte) to hex - for popular_item in popular_text_commands: - print hex(popular_item[0]) + " was used " + str(popular_item[1]) + " times." + #for popular_item in popular_text_commands: + # print hex(popular_item[0]) + " was used " + str(popular_item[1]) + " times." #print "popular text commands: " + str(popular_text_commands) - print "total text commands: " + str(total_text_commands) - print "total text scripts: " + str(should_be_total) - print "missing 08s: " + str(missing_08s) - print "\n\n" + #print "total text commands: " + str(total_text_commands) + #print "total text scripts: " + str(should_be_total) + #print "missing 08s: " + str(missing_08s) + #print "\n\n" #text_pretty_printer_at(0x800b1) - find_undone_texts() + #find_undone_texts() + + scan_rom_for_tx_fars() diff --git a/extras/insert_texts.py b/extras/insert_texts.py index 7a61e854..6d7b7b6d 100644 --- a/extras/insert_texts.py +++ b/extras/insert_texts.py @@ -1,9 +1,9 @@ #!/usr/bin/python2.7 #author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-07 +#date: 2012-01-07, 2012-01-17 #insert TX_FAR targets into pokered.asm import extract_maps -from analyze_texts import analyze_texts, text_pretty_printer_at +from analyze_texts import analyze_texts, text_pretty_printer_at, scan_rom_for_tx_fars from pretty_map_headers import map_name_cleaner, make_text_label, map_constants, find_all_tx_fars, tx_far_pretty_printer, tx_far_label_maker import pretty_map_headers from analyze_incbins import asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins, reset_incbins, apply_diff @@ -15,6 +15,19 @@ spacing = " " tx_fars = None failed_attempts = {} +def local_reset_incbins(): + asm = None + incbin_lines = [] + processed_incbins = {} + analyze_incbins.asm = None + analyze_incbins.incbin_lines = [] + analyze_incbins.processed_incbins = {} + + #reload + load_asm() + isolate_incbins() + process_incbins() + def find_tx_far_entry(map_id, text_id): for tx_far_line in tx_fars: if tx_far_line[0] == map_id and tx_far_line[1] == text_id: @@ -396,14 +409,20 @@ def insert_asm(start_address, label, text_asm=None, end_address=None): result = apply_diff(diff, try_fixing=True) return True -def insert_text(address, label): +def insert_text(address, label, apply=False, try_fixing=True): "inserts a text script (but not $8s)" start_address = address line_number = find_incbin_to_replace_for(start_address) if line_number == None: print "skipping text at " + hex(start_address) + " with address " + label - return + return "skip" + + #another reason to skip is if the interval is 0 + processed_incbin = analyze_incbins.processed_incbins[line_number] + if processed_incbin["interval"] == 0: + print "skipping text at " + hex(start_address) + " with address " + label + " because the interval is 0" + return "skip" text_asm, byte_count = text_pretty_printer_at(start_address, label) end_address = start_address + byte_count @@ -427,7 +446,10 @@ def insert_text(address, label): diff = generate_diff_insert(line_number, newlines) print diff - #apply_diff(diff) + if apply: + return apply_diff(diff, try_fixing=try_fixing) + else: #simulate a successful insertion + return True #move this into another file? def scan_for_map_scripts_pointer(): @@ -586,6 +608,47 @@ def scan_for_map_scripts_pointer(): print script_asm sys.exit(0) +def scan_rom_for_tx_fars_and_insert(): + """calls analyze_texts.scan_rom_for_tx_fars() + looks through INCBIN'd addresses from common.asm, + finds TX_FARs that aren't included yet. + """ + x = 0 + address_bundles = scan_rom_for_tx_fars(printer=True) + for address_bundle in address_bundles: + tx_far_address = address_bundle[1] + tx_far_target_address = address_bundle[0] + if tx_far_address in [0xeff2]: continue #skip + #if tx_far_address < 0x7627b: continue #because it stopped a few times for errors + + tx_far_label = "UnnamedText_%.2x" % (tx_far_address) + tx_far_target_label = "_" + tx_far_label + + #let's also do a quick check if it might be in the file already + if not (": ; " + hex(tx_far_address) in analyze_incbins.asm): + print "inserting text at " + hex(tx_far_address) + result = insert_text(tx_far_target_address, tx_far_target_label, apply=True) + else: + #we can't just pretend like it worked, because we don't know what label was used + #so, figure out the label + for line in analyze_incbins.asm_lines: + if ": ; " + hex(tx_far_address) in line: + tx_far_target_label = line.split(":")[0] + result = "skip" + + if result == True or result == None: + local_reset_incbins() + result2 = insert_text(tx_far_address, tx_far_label, apply=True) + local_reset_incbins() + elif result == "skip": + print "skipping " + hex(tx_far_address) + # result2 = insert_text(tx_far_address, tx_far_label, apply=True) + # local_reset_incbins() + + #just skip these for now + #if not result or not result2: + # sys.exit(0) + if __name__ == "__main__": #load map headers and object data extract_maps.load_rom() @@ -593,15 +656,16 @@ if __name__ == "__main__": extract_maps.read_all_map_headers() #load texts (these two have different formats) - all_texts = pretty_map_headers.analyze_texts.analyze_texts() - pretty_map_headers.all_texts = all_texts - tx_fars = pretty_map_headers.find_all_tx_fars() + #all_texts = pretty_map_headers.analyze_texts.analyze_texts() + #pretty_map_headers.all_texts = all_texts + #tx_fars = pretty_map_headers.find_all_tx_fars() #load incbins reset_incbins() #scan_for_map_scripts_pointer() - insert_text(0xa586b, "_VermilionCityText14") + scan_rom_for_tx_fars_and_insert() + #insert_text(0xa586b, "_VermilionCityText14") #insert _ViridianCityText10 #insert_tx_far(1, 10) diff --git a/extras/pretty_map_headers.py b/extras/pretty_map_headers.py index b36d9242..4b577e36 100644 --- a/extras/pretty_map_headers.py +++ b/extras/pretty_map_headers.py @@ -327,6 +327,7 @@ char_conversion = [ ("!", 0xE7), (".", 0xE8), ("♂", 0xEF), +#("¥", 0xF0), ("/", 0xF3), (",", 0xF4), ("♀", 0xF5), |