diff options
Diffstat (limited to 'extras/analyze_texts.py')
-rw-r--r-- | extras/analyze_texts.py | 154 |
1 files changed, 151 insertions, 3 deletions
diff --git a/extras/analyze_texts.py b/extras/analyze_texts.py index 9d2ce8bf..4d089975 100644 --- a/extras/analyze_texts.py +++ b/extras/analyze_texts.py @@ -3,7 +3,10 @@ #date: 2012-01-06 #analyze texts, how many commands are unknown? import extract_maps -from pretty_map_headers import map_name_cleaner +import analyze_incbins #for asm +try: + from pretty_map_headers import map_name_cleaner, txt_bytes, spacing, constant_abbreviation_bytes +except Exception, exc: pass from operator import itemgetter import sys debug = False #set to True to increase logging output @@ -203,6 +206,11 @@ def parse_text_script(text_pointer, text_id, map_id, txfar=False): #07 = shift texts 1 row above (2nd line becomes 1st line); address for next text = 2nd line. [07] command = {"type": command_byte, "start_address": offset, "end_address": offset} offset += 1 + elif command_byte == 0x8: + #08 = asm until whenever + command = {"type": command_byte, "start_address": offset, "end_address": offset} + offset += 1 + end = True elif command_byte == 0x9: #09 = write hex-to-dec number from RAM to textbox [09][2-byte RAM address][byte bbbbcccc] # bbbb = how many bytes to read (read number is big-endian) @@ -303,8 +311,6 @@ def parse_text_script(text_pointer, text_id, map_id, txfar=False): #FF = change music to a specific song that i don't know the name of command = {"type": command_byte, "start_address": offset, "end_address": offset} offset += 1 - elif command_byte == 0x8: #not ready to process asm - end = True else: #if len(commands) > 0: # print "Unknown text command " + hex(command_byte) + " at " + hex(offset) + ", script began with " + hex(commands[0]["type"]) @@ -362,6 +368,141 @@ def analyze_texts(): extract_maps.map_headers[map_id]["texts"] = map2["texts"] return texts +def find_missing_08s(all_texts): + """determines which $08s have yet to be inserted + based on their start addresses""" + missing_08s = 0 + for map_id in all_texts.keys(): + for text_id in all_texts[map_id].keys(): + for line_id in all_texts[map_id][text_id].keys(): + if not line_id == 0: + current_line = all_texts[map_id][text_id][line_id] + if "type" in current_line.keys(): + if current_line["type"] == 0x8: + missing_08s += 1 + print "missing $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " line_id=" + str(line_id) + " at " + hex(current_line["start_address"]) + return missing_08s + +def text_pretty_printer_at(start_address, label="SomeLabel"): + commands = parse_text_script(start_address, None, None) + + 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" + + lines = commands[wanted_command]["lines"] + + #add the ending byte to the last line- always seems $57 + lines[len(lines.keys())-1].append(commands[1]["type"]) + + output = "\n" + output += label + ": ; " + hex(start_address) + "\n" + 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 + was_byte = False + 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 + if not first_byte: + output += ", " + output += constant_abbreviation_bytes[byte] + else: + if quotes_open: + output += "\"" + quotes_open = False + + #if you want the ending byte on the last line + #if not (byte == 0x57 or byte == 0x50 or byte == 0x58): + if not first_byte: + output += ", " + + output += "$" + hex(byte)[2:] + was_byte = True + + #add a comma unless it's the end of the line + #if byte_count+1 != len(line): + # output += ", " + + first_byte = False + byte_count += 1 + #close final quotes + if quotes_open: + output += "\"" + quotes_open = False + + output += "\n" + + #output += "\n" + print output + return output + +def is_label_in_asm(label): + for line in analyze_incbins.asm: + if label in line: + if line[0:len(label)] == label: + return True + return False + +def find_undone_texts(): + usable_table = {} + if analyze_incbins.asm == None: + analyze_incbins.load_asm() + + for map_id in extract_maps.map_headers: + #skip bad maps + if map_id in extract_maps.bad_maps: continue + + map2 = extract_maps.map_headers[map_id] + name = map_name_cleaner(map2["name"], None)[:-2] + "Text" + + for text_id in map2["referenced_texts"]: + label = name + str(text_id) + + if len(extract_maps.map_headers[map_id]["texts"][text_id].keys()) == 0: continue + if len(extract_maps.map_headers[map_id]["texts"][text_id][0].keys()) == 0: continue + + try: + address = extract_maps.map_headers[map_id]["texts"][text_id][0]["start_address"] + except: + address = extract_maps.map_headers[map_id]["texts"][text_id][1]["start_address"] + + if not is_label_in_asm(label): + print label + " map_id=" + str(map_id) + " text_id=" + str(text_id) + " at " + hex(address) + " byte is: " + hex(ord(extract_maps.rom[address])) + if not address in usable_table.keys(): + usable_table[address] = 1 + else: + usable_table[address] += 1 + + print "\n\n which ones are priority?" + sorted_results = sorted(usable_table.iteritems(), key=itemgetter(1), reverse=True) + for result in sorted_results: + print str(result[1]) + " times: " + hex(result[0]) + if __name__ == "__main__": extract_maps.load_rom() extract_maps.load_map_pointers() @@ -369,6 +510,8 @@ if __name__ == "__main__": text_output = analyze_texts() #print text_output + missing_08s = find_missing_08s(text_output) + print "\n\n---- stats ----\n\n" popular_text_commands = sorted(totals.iteritems(), key=itemgetter(1), reverse=True) @@ -379,3 +522,8 @@ if __name__ == "__main__": 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() |