shithub: pokered

Download patch

ref: 3948f21d57389b0467cc8fd1ede11b8e559f201d
parent: a1dcf11f7c7a519536b930f3164cdf20c3a2e279
author: Bryan Bishop <kanzure@gmail.com>
date: Sat Jan 7 19:23:52 EST 2012

script to insert TX_FAR labels

hg-commit-id: 6be98c7af43b


--- a/extras/insert_texts.py
+++ b/extras/insert_texts.py
@@ -73,7 +73,7 @@
     print diff
     apply_diff(diff)
 
-def insert_all_tx_fars():
+def insert_all_tx_far_targets():
     for tx_far in tx_fars:
         map_id = tx_far[0]
         text_id = tx_far[1]
@@ -94,6 +94,186 @@
         isolate_incbins()
         process_incbins()
 
+def all_texts_are_tx_fars(map_id):
+    map2 = extract_maps.map_headers[map_id]
+    for text_id in map2["texts"]:
+        txt = map2["texts"][text_id]
+        if not "TX_FAR" in txt[0].keys(): return False
+    return True
+
+def texts_label_pretty_printer(map_id):
+    "output a texts label for map if all texts are TX_FARs and in the asm already"
+    #extract_maps.map_headers[map_id]["texts"][text_id][0]["TX_FAR"]
+    if not all_texts_are_tx_fars(map_id): return None
+    map2 = extract_maps.map_headers[map_id]
+
+    #pointer to the list of texts
+    texts_list_pointer = int(map2["texts_pointer"], 16)
+
+    #get the label for this texts list
+    base_label = map_name_cleaner(map2["name"], None)[:-2]
+    label = base_label + "Texts"
+
+    #make up a label for each text
+    text_labels = []
+    text_id = 1
+    for text in map2["texts"].keys():
+        text_label = base_label + "Text" + str(text_id)
+        text_labels.append(text_label)
+        text_id += 1
+    
+    output = label + ": ; " + hex(texts_list_pointer)
+    output += "\n"
+    output += spacing + "dw "
+
+    first = True
+    for labela in text_labels:
+        if not first:
+            output += ", " + labela
+        else:
+            output += labela
+            first = False
+
+    return output
+
+def insert_texts_label(map_id):
+    if not all_texts_are_tx_fars(map_id): return None
+    map2 = extract_maps.map_headers[map_id]
+    
+    base_label = map_name_cleaner(map2["name"], None)[:-2]
+    label = base_label + "Texts"
+    texts_pointer = int(map2["texts_pointer"], 16)
+
+    insert_asm = texts_label_pretty_printer(map_id)
+
+    line_number = find_incbin_to_replace_for(texts_pointer)
+    if line_number == None:
+        print "skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the address is taken"
+        return
+
+    #also do a name check
+    if (label + ":") in "\n".join(analyze_incbins.asm):
+        print "skipping texts label for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " because the label is already used"
+        return
+    
+    newlines = split_incbin_line_into_three(line_number, texts_pointer, len(map2["referenced_texts"])*2 )
+
+    newlines = newlines.split("\n")
+    if len(newlines) == 2: index = 0 #replace the 1st line with new content
+    elif len(newlines) == 3: index = 1 #replace the 2nd line with new content
+    
+    newlines[index] = insert_asm
+
+    if len(newlines) == 3 and newlines[2][-2:] == "$0":
+        #get rid of the last incbin line if it is only including 0 bytes
+        del newlines[2]
+        #note that this has to be done after adding in the new asm
+    newlines = "\n".join(line for line in newlines)
+    newlines = newlines.replace("$x", "$")
+
+    diff = generate_diff_insert(line_number, newlines)
+    print "working on map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer)
+    print diff
+    #apply_diff(diff)
+
+#untested as of 2012-01-07
+def insert_all_texts_labels():
+    for map_id in extract_maps.map_headers.keys():
+        if map_id not in extract_maps.bad_maps:
+            if len(extract_maps.map_headers[map_id]["referenced_texts"]) > 0:
+                insert_texts_label(map_id)
+        
+                reset_incbins()
+                analyze_incbins.reset_incbins()
+                asm = None
+                incbin_lines = []
+                processed_incbins = {}
+                analyze_incbins.asm = None
+                analyze_incbins.incbin_lines = []
+                analyze_incbins.processed_incbins = {}
+        
+                load_asm()
+                isolate_incbins()
+                process_incbins()
+
+def txt_to_tx_far_pretty_printer(address, label, target_label, include_byte=False):
+    output = "\n" + label + ": ; " + hex(address) + "\n"
+    output += spacing + "TX_FAR " + target_label + "\n"
+    if include_byte:
+        output += spacing + "db $50\n"
+    return output
+
+def insert_text_label_tx_far(map_id, text_id):
+    if map_id in extract_maps.bad_maps:
+        print "bad map id=" + str(map_id)
+        return
+    map2 = extract_maps.map_headers[map_id]
+    if map2["texts"][text_id] == {0: {}}: return None
+
+    base_label = map_name_cleaner(map2["name"], None)[:-2]
+    label = base_label + "Text" + str(text_id)
+    target_label = "_" + label
+    start_address = map2["texts"][text_id][0]["start_address"]
+    include_byte = False
+    print map2["texts"][text_id]
+    if "type" in map2["texts"][text_id][1].keys():
+        if map2["texts"][text_id][1]["type"] == 0x50:
+            include_byte = True
+    tx_far_asm = txt_to_tx_far_pretty_printer(start_address, label, target_label, include_byte=include_byte)
+    
+    line_number = find_incbin_to_replace_for(start_address)
+    if line_number == None:
+        print "skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id=" + hex(text_id) + " because the address is taken"
+        return
+
+    #also do a name check
+    if ("\n".join(analyze_incbins.asm)).count(label + ":") > 1:
+        print "skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id" + hex(text_id) + " because the label is already used (" + label + ":)"
+        return
+    
+    extra = 0
+    if include_byte: extra += 1
+    newlines = split_incbin_line_into_three(line_number, start_address, 4 + extra )
+
+    newlines = newlines.split("\n")
+    if len(newlines) == 2: index = 0 #replace the 1st line with new content
+    elif len(newlines) == 3: index = 1 #replace the 2nd line with new content
+    
+    newlines[index] = tx_far_asm
+
+    if len(newlines) == 3 and newlines[2][-2:] == "$0":
+        #get rid of the last incbin line if it is only including 0 bytes
+        del newlines[2]
+        #note that this has to be done after adding in the new asm
+    newlines = "\n".join(line for line in newlines)
+
+    newlines = newlines.replace("$x", "$")
+
+    diff = generate_diff_insert(line_number, newlines)
+    print "working on map_id=" + str(map_id) + " text_id=" + str(text_id)
+    print diff
+    apply_diff(diff)
+
+def insert_all_text_labels():
+    for map_id in extract_maps.map_headers.keys():
+        if map_id < 40: continue #skip
+        if map_id not in extract_maps.bad_maps:
+            for text_id in extract_maps.map_headers[map_id]["referenced_texts"]:
+                insert_text_label_tx_far(map_id, text_id)
+        
+                reset_incbins()
+                analyze_incbins.reset_incbins()
+                asm = None
+                incbin_lines = []
+                processed_incbins = {}
+                analyze_incbins.asm = None
+                analyze_incbins.incbin_lines = []
+                analyze_incbins.processed_incbins = {}
+        
+                load_asm()
+                isolate_incbins()
+                process_incbins()
+
 if __name__ == "__main__":
     #load map headers and object data
     extract_maps.load_rom()
@@ -111,8 +291,19 @@
     #insert _ViridianCityText10
     #insert_tx_far(1, 10)
 
-    insert_all_tx_fars()
-
     #just me testing a pokemart sign duplicate
     #insert_tx_far(3, 14)
 
+    #this is the big one
+    #insert_all_tx_far_targets()
+    
+    #for map_id in extract_maps.map_headers.keys():
+    #    if map_id not in extract_maps.bad_maps:
+    #        if len(extract_maps.map_headers[map_id]["referenced_texts"]) > 0:
+    #            texts_label_pretty_printer(map_id)
+    
+    #insert_texts_label(240)
+    #insert_all_texts_label()
+
+    #insert_text_label_tx_far(240, 1)
+    insert_all_text_labels()