diff options
| author | Bryan Bishop <kanzure@gmail.com> | 2013-09-10 20:08:49 -0500 | 
|---|---|---|
| committer | Bryan Bishop <kanzure@gmail.com> | 2013-09-10 20:08:49 -0500 | 
| commit | e47308a1f88f19dfc0ee5cb42dc643a520d9175b (patch) | |
| tree | 7ae7bb3ff46ceeab012869db3cbdad86545a0496 /extras | |
| parent | a684941cfcf88942cbecaecf997609acc3652a1a (diff) | |
| parent | 37c80175368352710e20f752ebfdc1e9e3ac3e2b (diff) | |
Merge branch kanzure/master into dannye-incbins
Conflicts:
	extras
Diffstat (limited to 'extras')
| m--------- | extras | 0 | ||||
| -rw-r--r-- | extras/add_map_labels_to_map_headers.py | 41 | ||||
| -rw-r--r-- | extras/analyze_incbins.py | 507 | ||||
| -rw-r--r-- | extras/analyze_texts.py | 716 | ||||
| -rw-r--r-- | extras/connection_helper.py | 104 | ||||
| -rw-r--r-- | extras/extract_maps.py | 702 | ||||
| -rw-r--r-- | extras/extract_tileblocks.py | 94 | ||||
| -rw-r--r-- | extras/extract_tilesets.py | 37 | ||||
| -rw-r--r-- | extras/fix_labels.py | 82 | ||||
| -rw-r--r-- | extras/gbz80disasm.py | 853 | ||||
| -rw-r--r-- | extras/generate_sys.py | 8 | ||||
| -rw-r--r-- | extras/insert_object_data.py | 82 | ||||
| -rw-r--r-- | extras/insert_texts.py | 891 | ||||
| -rw-r--r-- | extras/make_map_size_constants.py | 37 | ||||
| -rw-r--r-- | extras/map_block_dumper.py | 171 | ||||
| -rw-r--r-- | extras/pokered_dir.py | 4 | ||||
| -rw-r--r-- | extras/pretty_map_headers.py | 755 | ||||
| -rw-r--r-- | extras/pretty_text.py | 21 | ||||
| -rw-r--r-- | extras/pretty_trainer_headers.py | 126 | ||||
| -rw-r--r-- | extras/redrle.c | 128 | ||||
| -rw-r--r-- | extras/replace_dimensions.py | 245 | ||||
| -rw-r--r-- | extras/romvisualizer.py | 28 | ||||
| -rw-r--r-- | extras/romviz.py | 40 | ||||
| -rw-r--r-- | extras/sprite_helper.py | 402 | ||||
| -rw-r--r-- | extras/text_pointers.py | 55 | 
25 files changed, 0 insertions, 6129 deletions
| diff --git a/extras b/extras new file mode 160000 +Subproject 7aa016fb528bcc8dcb30c6a887957851623eccc diff --git a/extras/add_map_labels_to_map_headers.py b/extras/add_map_labels_to_map_headers.py deleted file mode 100644 index 89e6f361..00000000 --- a/extras/add_map_labels_to_map_headers.py +++ /dev/null @@ -1,41 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2011-01-04 -#purpose: insert labels into map headers -import sys - -asm = None -asm_lines = [] -def load_asm(): -    global asm, asm_lines -    asm = open("../pokered.asm", "r").read() -    asm_lines = asm.split("\n") - -def find_with_start_of_line(name): -    global asm_lines -    for line in asm_lines: -        if len(line) > len(name) and ": " in line: -            if line[:len(name)] == name: return True -    return False - -def process_lines(): -    global asm, asm_lines -    for line in asm_lines: -        if not "_h:" in line: continue #skip -        index = asm_lines.index(line) -        name = line.split("_h:")[0] - -        if "Blocks" in asm_lines[index+3]: continue #skip, already done -        #if not (str(name + "Blocks:") in asm): continue #skip, no block label found -        if not find_with_start_of_line(name + "Blocks:"): continue #skip - -        orig_line = asm_lines[index+3] -        fixed_line = orig_line.split(",") -        fixed_line[0] = "    dw " + name + "Blocks" -        fixed_line = ",".join(fixed_line) - -        asm_lines[index+3] = fixed_line - -if __name__ == "__main__": -    load_asm() -    process_lines() -    sys.stdout.write("\n".join(asm_lines)) diff --git a/extras/analyze_incbins.py b/extras/analyze_incbins.py deleted file mode 100644 index db503ff1..00000000 --- a/extras/analyze_incbins.py +++ /dev/null @@ -1,507 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-03 -#purpose: map which addresses are left -#note: use python2.7 because of subprocess -import sys, os -from copy import copy, deepcopy -import subprocess -import json -from extract_maps import rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers -from pokered_dir import pokered_dir - -try: -    from pretty_map_headers import map_header_pretty_printer, map_name_cleaner -except Exception: -    pass - -#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=os.path.join(pokered_dir, "main.asm")): -    """loads the asm source code into memory -    this also detects if the revision of the repository -    is using main.asm, common.asm or pokered.asm, which is -    useful when generating images in romvisualizer.py""" -    global asm -    # chronological order is important -    defaults = [os.path.join(pokered_dir, f) for f in ["main.asm", "common.asm", "pokered.asm"]] -    if filename in defaults: -        if not load_asm_if_one_exists_in(defaults): -            raise Exception("This shouldn't happen") -    elif os.path.exists(filename): -        asm = get_all_lines_from_file(filename) -    if asm is None: -        raise Exception("file doesn't exists (did you mean one among: {0}?)".format(", ".join(defaults))) -    return asm - -def load_asm_if_one_exists_in(defaults): -    global asm -    for f in defaults: -        if os.path.exists(f): -            asm = get_all_lines_from_file(f) -            return True -    return False - -def get_all_lines_from_file(filename): -    try: -        return open(filename, "r").read().split("\n") -    except IOError as e: -        raise(e) - -def isolate_incbins(): -    "find each incbin line" -    global incbin_lines -    incbin_lines = [] -    for line in asm: -        if line == "": continue -        if line.count(" ") == len(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(";", "#") -        partial_interval = partial_interval.replace("$", "0x").replace("0xx", "0x") -        interval = eval(partial_interval) -        interval_hex = hex(interval).replace("0x", "$").replace("x", "") - -        end = start + interval -        end_hex = hex(end).replace("0x", "$") - -        processed_incbin = { -                            "line_number": line_number, -                            "line": incbin, -                            "start": start, -                            "interval": interval, -                            "end": end, -                           } -         -        #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 -    if you were to insert bytes into main.asm""" -    if type(address) == str: address = int(address, 16) - -    for incbin_key in processed_incbins.keys(): -        incbin = processed_incbins[incbin_key] - -        start = incbin["start"] -        end = incbin["end"] -         -        #print "start is: " + str(start) -        #print "end is: " + str(end) -        #print "address is: " + str(type(address)) -        #print "checking.... " + hex(start) + " <= " + hex(address) + " <= " + hex(end) -         -        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: -        diffcontent = subprocess.check_output( -                "diff -u {0} {1}".format(os.path.join(pokered_dir, "main.asm"), newfile_filename), -                shell=True) -    except AttributeError, exc: -        raise exc -    except Exception, exc: -        diffcontent = exc.output - -    os.system("rm " + original_filename) -    os.system("rm " + newfile_filename) - -    return diffcontent - -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 {0} temp.patch".format(os.path.join(pokered_dir, "main.asm"))) -     -    #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) - -def reset_incbins(): -    "reset asm before inserting another diff" -    asm = None -    incbin_lines = [] -    processed_incbins = {} -    load_asm() -    isolate_incbins() -    process_incbins() - -def apply_diff(diff, try_fixing=True, do_compile=True): -    print "... Applying diff." - -    #write the diff to a file -    fh = open("temp.patch", "w") -    fh.write(diff) -    fh.close() - -    #apply the patch -    os.system("cp {0} {1}".format( -        os.path.join(pokered_dir, "main.asm"), -        os.path.join(pokered_dir, "main1.asm"))) -    os.system("patch {0} {1}".format( -        os.path.join(pokered_dir, "main.asm"), -        "temp.patch")) - -    #remove the patch -    os.system("rm temp.patch") - -    #confirm it's working -    if do_compile: -        try: -            subprocess.check_call("cd {0}; make clean; LC_CTYPE=C make".format(pokered_dir), shell=True) -            return True -        except Exception, exc: -            if try_fixing: -                os.system("mv {0} {1}".format( -                    os.path.join(pokered_dir, "main1.asm"), -                    os.path.join(pokered_dir, "main.asm"))) -            return False - -def index(seq, f): -    """return the index of the first item in seq -    where f(item) == True.""" -    return next((i for i in xrange(len(seq)) if f(seq[i])), None) - -def is_probably_pointer(input): -    try: -        blah = int(input, 16) -        return True -    except: -        return False - -label_errors = "" -def get_labels_between(start_line_id, end_line_id, bank_id): -    labels = [] -    #label = { -    #   "line_number": 15, -    #   "bank_id": 32, -    #   "label": "PalletTownText1", -    #   "local_pointer": "$5315", -    #   "address": 0x75315, -    #} -    global label_errors -    errors = "" -    current_line_offset = 0 - -    sublines = asm[start_line_id : end_line_id + 1] -    for line in sublines: -        label = {} -        line_id = start_line_id + current_line_offset -        address = None -        local_pointer = None - -        if ": ; 0x" in line: -            temp = line.split(": ; 0x")[1] - -            # just read until the comma appears -            if "," in line: -                temp = temp.split(",")[0] - -            if not " " in temp: -                address = int("0x" + temp, 16) -            else: -                temp2 = temp.split(" ")[0] -                address = int("0x" + temp2, 16) -        elif ": ; " in line: -            partial = line.split(": ; ")[1] -            if ": ; $" in line: -                temp = line.split(": ; $")[1] -                if " " in temp: -                    temp = temp.split(" ")[0] -                local_pointer = "$" + temp -            elif " " in partial: -                if " to " in partial: -                    temp = partial.split(" to ")[0] -                    if "0x" in temp: -                        address = int(temp, 16) -                    elif len(temp) == 4: -                        local_pointer = "$" + temp -                    else: -                        errors += "found \" to \" in partial on line " + str(line_id) + ", but don't know what to do (debug14)" + "\n" -                        errors += "line is: " + line + "\n" -                        continue -                elif partial[4] == " " and partial[5] == "(": -                    temp = partial[0:4] -                    address = int(temp, 16) -                elif partial[5] == " " and partial[6] == "(": -                    temp = partial[0:5] -                    address = int(temp, 16) -                elif len(partial[4]) == 4 or partial[4] == " ": #then it's probably a local pointer -                    temp = partial[0:4] -                    local_pointer = "$" + temp -                else: -                    errors += "found \": ; \" and another \" \" in line " + str(line_id) + ", but don't know what to do (debug15)" + "\n" -                    errors += "line is: " + line + "\n" -                    continue -            else: -                if len(partial) > 3 and partial[2] == ":": #14:3BAC -                    temp = partial[2].split(":")[1] -                    if len(temp) == 3 or len(temp) == 4: -                        local_pointer = "$" + temp -                    else: -                        temp = temp.split(" ")[0] -                        local_pointer = "$" + temp -                elif len(partial) == 4 or (len(partial) == 3 and is_probably_pointer(partial)): -                    local_pointer = "$" + partial -                else: -                    errors += "found \": ; \" in line " + str(line_id) + ", but don't know what to do (debug16)" + "\n" -                    errors += "line is: " + line + "\n" -                    continue -        else: -            #this line doesn't have a label -            continue - -        if local_pointer != None and not is_probably_pointer(local_pointer.replace("0x", "").replace("$", "")): -            continue - -        line_label = line.split(": ;")[0] - -        if address == None and local_pointer != None: -            temp = int(local_pointer.replace("$", "0x"), 16) -            if temp < 0x4000 or bank_id == 0: -                address = temp -            else: -                address = calculate_pointer(int(local_pointer.replace("$", "0x"), 16), bank_id) -        elif local_pointer == None and address != None: -            if address < 0x4000: -                local_pointer = hex(address).replace("0x", "$") -            else: -                local_pointer = hex((address % 0x4000) + 0x4000).replace("0x", "$") - -        print line_label + " is at " + hex(address) -         -        label = { -            "line_number": line_id, -            "bank_id": bank_id, -            "label": line_label, -            "local_pointer": local_pointer, -            "address": address -        } -        labels.append(label) - -        current_line_offset += 1  -    label_errors += errors -    return labels - -def scan_for_predefined_labels(): -    """looks through the asm file for labels at specific addresses, -    this relies on the label having its address after. ex: - -    ViridianCity_h: ; 0x18357 to 0x18384 (45 bytes) (bank=6) (id=1) -    PalletTownText1: ; 4F96 0x18f96 -    ViridianCityText1: ; 0x19102 - -    It would be more productive to use rgbasm to spit out all label -    addresses, but faster to write this script. rgbasm would be able -    to grab all label addresses better than this script.. -    """ -    bank_intervals = {} -    all_labels = [] - -    if asm is None: -        load_asm() - -    #figure out line numbers for each bank -    for bank_id in range(0x2d): -        abbreviation = ("%.x" % (bank_id)).upper() -        abbreviation_next = ("%.x" % (bank_id+1)).upper() -        if bank_id == 0: -            abbreviation = "0" -            abbreviation_next = "1" - -        start_line_id = index(asm, lambda line: "\"bank" + abbreviation + "\"" in line) - -        if bank_id != 0x2c: -            end_line_id = index(asm, lambda line: "\"bank" + abbreviation_next + "\"" in line) -        else: -            end_line_id = len(asm) - 1 - -        print "bank" + abbreviation + " starts at " + str(start_line_id) + " to " + str(end_line_id) - -        bank_intervals[bank_id] = { -                                    "start": start_line_id, -                                    "end": end_line_id, -                                  } -      -    for bank_id in bank_intervals.keys(): -        bank_data = bank_intervals[bank_id] - -        start_line_id = bank_data["start"] -        end_line_id   = bank_data["end"] - -        labels = get_labels_between(start_line_id, end_line_id, bank_id) -        #bank_intervals[bank_id]["labels"] = labels -        all_labels.extend(labels) - -    write_all_labels(all_labels) -    return all_labels - -def write_all_labels(all_labels): -    fh = open("labels.json", "w") -    fh.write(json.dumps(all_labels)) -    fh.close() - -def analyze_intervals(): -    """find the largest baserom.gbc intervals""" -    global asm -    global processed_incbins -    if asm == None: -        load_asm() -    if processed_incbins == {}: -        isolate_incbins() -        process_incbins() -     -    results = [] -    ordered_keys = sorted(processed_incbins, key=lambda entry: processed_incbins[entry]["interval"]) -    ordered_keys.reverse() -    for key in ordered_keys: -        results.append(processed_incbins[key]) - -    return results - -if __name__ == "__main__": -    #load map headers -    load_rom() -    load_map_pointers() -    read_all_map_headers() -     -    #load incbins (mandatory) -    load_asm() -    #isolate_incbins() -    #process_incbins() -    #print processed_incbins -     -    #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 - -    #insert_map_header_asm(86) -    #dump_all_remaining_maps() - -    scan_for_predefined_labels() -    print "Errors:" -    print label_errors - diff --git a/extras/analyze_texts.py b/extras/analyze_texts.py deleted file mode 100644 index 08b8ab03..00000000 --- a/extras/analyze_texts.py +++ /dev/null @@ -1,716 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-06 -#analyze texts, how many commands are unknown? -import extract_maps -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 - -#how many times is each command byte called? -totals = {} -total_text_commands = 0 -should_be_total = 0 - -def get_text_pointer(texts_pointer, text_id): -    if type(texts_pointer) == str: texts_pointer = int(texts_pointer, 16) -    if type(text_id) == str: text_id = int(text_id) - -    byte1 = ord(extract_maps.rom[texts_pointer + ((text_id - 1) * 2)]) -    byte2 = ord(extract_maps.rom[texts_pointer + ((text_id - 1) * 2) + 1]) -    pointer = (byte1 + (byte2 << 8)) - -    return pointer - -def how_many_until(byte, starting): -    index = extract_maps.rom.find(byte, starting) -    return index-starting - -def print_command_debug_info(command_byte, text_id, text_pointer, map_id): -    if debug: -        print "byte is " + str(command_byte) + " on text #" + str(text_id) + " at " + hex(text_pointer) + " on map " + str(map_id) + " (" + extract_maps.map_headers[map_id]["name"] + ")" - -def add_command_byte_to_totals(byte): -    global totals -    if not byte in totals.keys(): totals[byte] = 1 -    else: totals[byte] += 1 - -def process_00_subcommands(start_address, end_address): -    """split this text up into multiple lines -    based on subcommands ending each line""" -    lines = {} -    subsection = extract_maps.rom[start_address:end_address+1] - -    line_count = 0 -    current_line = [] -    for pbyte in subsection: -        byte = ord(pbyte) -        current_line.append(byte) -        if  byte == 0x4f or byte == 0x51 or byte == 0x55: -            lines[line_count] = current_line -            current_line = [] -            line_count += 1 - -    #don't forget the last line -    lines[line_count] = current_line -    line_count += 1 -    return lines - -def parse_text_script(text_pointer, text_id, map_id, txfar=False): -    global total_text_commands -    offset = text_pointer -    commands = {} -    command_counter = 0 - -    if extract_maps.rom == None: -        extract_maps.load_rom() -     -    end = False -    while not end: -        command = {} -        command_byte = ord(extract_maps.rom[offset]) -         -        print_command_debug_info(command_byte, text_id, text_pointer, map_id) -        if  command_byte == 0: -            #read until $57, $50 or $58 -            jump57 = how_many_until(chr(0x57), offset) -            jump50 = how_many_until(chr(0x50), offset) -            jump58 = how_many_until(chr(0x58), offset) -             -            #whichever command comes first -            jump = min([jump57, jump50, jump58]) - -            end_address = offset + jump - 1 #we want the address before $57 - -            command = {"type": command_byte, -                       "start_address": offset, -                       "end_address": end_address, -                       "size": jump, -                       "lines": process_00_subcommands(offset+1, end_address), -                      } - -            offset += jump -        elif command_byte == 0x17: -            #TX_FAR [pointer][bank] -            pointer_byte1 = ord(extract_maps.rom[offset+1]) -            pointer_byte2 = ord(extract_maps.rom[offset+2]) -            pointer_bank = ord(extract_maps.rom[offset+3]) - -            pointer = (pointer_byte1 + (pointer_byte2 << 8)) -            pointer = extract_maps.calculate_pointer(pointer, pointer_bank) - -            command = {"type": command_byte, -                       "start_address": offset, -                       "end_address": offset + 3, #last byte belonging to this command -                       "pointer": pointer, #parameter -                      } - -            offset += 3 + 1 -        elif command_byte == 0x50 or command_byte == 0x57 or command_byte == 0x58: #end text -            command = {"type": command_byte, -                       "start_address": offset, -                       "end_address": offset, -                      } - -            #this byte simply indicates to end the script -            end = True -             -            #this byte simply indicates to end the script -            if command_byte == 0x50 and ord(extract_maps.rom[offset+1]) == 0x50: #$50$50 means end completely -                end = True -                commands[command_counter+1] = command - -                #also save the next byte, before we quit -                commands[command_counter+1]["start_address"] += 1 -                commands[command_counter+1]["end_address"] += 1 -                add_command_byte_to_totals(command_byte) -            elif command_byte == 0x50: #only end if we started with $0 -                if len(commands.keys()) > 0: -                    if commands[0]["type"] == 0x0: end = True -            elif command_byte == 0x57 or command_byte == 0x58: #end completely -                end = True -                offset += 1 #go past this 0x50 -        elif command_byte == 0x1: -            #01 = text from RAM. [01][2-byte pointer] -            size = 3 #total size, including the command byte -            pointer_byte1 = ord(extract_maps.rom[offset+1]) -            pointer_byte2 = ord(extract_maps.rom[offset+2]) -             -            command = {"type": command_byte, -                       "start_address": offset+1, -                       "end_address": offset+2, #last byte belonging to this command -                       "pointer": [pointer_byte1, pointer_byte2], #RAM pointer -                      } -             -            #view near these bytes -            #subsection = extract_maps.rom[offset:offset+size+1] #peak ahead -            #for x in subsection: -            #    print hex(ord(x)) -            #print "--" - -            offset += 2 + 1 #go to the next byte - -            #use this to look at the surrounding bytes -            if debug: -                print "next command is: " + hex(ord(extract_maps.rom[offset])) + " ... we are at command number: " + str(command_counter) + " near " + hex(offset) + " on map_id=" + str(map_id) + " for text_id=" + str(text_id) + " and txfar(recursion)=" + str(txfar) -        elif command_byte == 0x7: -            #07 = shift texts 1 row above (2nd line becomes 1st line); address for next text = 2nd line. [07] -            size = 1 -            command = {"type": command_byte, -                       "start_address": offset, -                       "end_address": offset, -                      } -            offset += 1 -        elif command_byte == 0x3: -            #03 = set new address in RAM for text. [03][2-byte RAM address] -            size = 3 -            command = {"type": command_byte, "start_address": offset, "end_address": offset+2} -            offset += size -        elif command_byte == 0x4: #draw box -            #04 = draw box. [04][2-Byte pointer][height Y][width X] -            size = 5 #including the command -            command = { -                        "type": command_byte, -                        "start_address": offset, -                        "end_address": offset + size, -                        "pointer_bytes": [ord(extract_maps.rom[offset+1]), ord(extract_maps.rom[offset+2])], -                        "y": ord(extract_maps.rom[offset+3]), -                        "x": ord(extract_maps.rom[offset+4]), -                      } -            offset += size + 1 -        elif command_byte == 0x5: -            #05 = write text starting at 2nd line of text-box. [05][text][ending command] -            #read until $57, $50 or $58 -            jump57 = how_many_until(chr(0x57), offset) -            jump50 = how_many_until(chr(0x50), offset) -            jump58 = how_many_until(chr(0x58), offset) -             -            #whichever command comes first -            jump = min([jump57, jump50, jump58]) - -            end_address = offset + jump - 1 #we want the address before $57 - -            command = {"type": command_byte, -                       "start_address": offset, -                       "end_address": end_address, -                       "size": jump, -                       "lines": process_00_subcommands(offset+1, end_address), -                      } -            offset = end_address + 1 -        elif command_byte == 0x6: -            #06 = wait for keypress A or B (put blinking arrow in textbox). [06] -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x7: -            #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) -            #  cccc = how many digits display (decimal) -            #(note: max of decimal digits is 7,i.e. max number correctly displayable is 9999999) -            ram_address_byte1 = ord(extract_maps.rom[offset+1]) -            ram_address_byte2 = ord(extract_maps.rom[offset+2]) -            read_byte = ord(extract_maps.rom[offset+3]) - -            command = { -                        "type": command_byte, -                        "address": [ram_address_byte1, ram_address_byte2], -                        "read_byte": read_byte, #split this up when we make a macro for this -                      } - -            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} -            offset += 1 -        elif command_byte == 0xE: -            #0E = sound_91 (learnt something) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xF: -            #0F = sound_86 (given rare candy)[same as 0B] -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x10: -            #10 = sound_89 (PKMN successfully caught) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x11: -            #11 = sound_94 (Hiro gives OAK the PARCEL) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x12: -            #12 = sound_9A (successfully caught) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x13: -            #13 = sound_98 (song heard when "new data will be added for..") -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x14: -            #14 = MonCry (Nidorina) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x15: -            #14 = MonCry (Pidgeot) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x16: -            #14 = MonCry (Dewgong) -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x19: -            #19 = play a 'bump' noise -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x1F: -            #1F = play some pokemon's roar, don't know which.. -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x20: -            #20 = oddish roar? -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x3F: -            #3F = some other roar -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x9D: -            #9D = a roar or some other sound, four times in quick succession -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0x76: -            #76 = another roar -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xCA: -            #CA = stop music, start this other song that i can't name -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xF6: -            #F6 = play a 'blurp blurp' noise.. like something is increasing -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xFA: -            #FA = change music to champion song? -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xFE: -            #FE = another roar, kinda glitchy? -            command = {"type": command_byte, "start_address": offset, "end_address": offset} -            offset += 1 -        elif command_byte == 0xFF: -            #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 -        else: -            #if len(commands) > 0: -            #   print "Unknown text command " + hex(command_byte) + " at " + hex(offset) + ", script began with " + hex(commands[0]["type"]) -            if debug: -                print "Unknown text command at " + hex(offset) + " - command: " + hex(ord(extract_maps.rom[offset])) + " on map_id=" + str(map_id) + " text_id=" + str(text_id) -             -            #end at the first unknown command -            end = True -        add_command_byte_to_totals(command_byte) - -        commands[command_counter] = command -        command_counter += 1 -    total_text_commands += len(commands) -    return commands - -def analyze_texts(): -    global should_be_total - -    texts = {} -    for map_id in extract_maps.map_headers: -        if map_id in extract_maps.bad_maps: continue #skip -        map2 = extract_maps.map_headers[map_id] -        map2["texts"] = {} -        referenced_texts = map2["referenced_texts"] -        should_be_total += len(referenced_texts) -        texts_pointer = int(map2["texts_pointer"], 16) -         -        #print "Checking texts on... map_id=" + str(map_id) + " and len(referenced_texts)=" + str(len(referenced_texts)) -        for text_id in referenced_texts: -            text_pointer = get_text_pointer(texts_pointer, text_id) -            if 0x4000 <= text_pointer <= 0x7fff: #only care about bank when it's between 4000-7fff -                text_pointer = extract_maps.calculate_pointer(text_pointer, int(map2["bank"], 16)) -            #print "Working on map id=" + str(map2["id"]) + " and text id=" + str(text_id) -            #print "for map_id=" + str(map_id) + " texts_pointer=" + hex(texts_pointer) + " text_id=" + str(text_id) + " the pointer=" + hex(text_pointer) -            commands = parse_text_script(text_pointer, text_id, map_id) - -            #process TX_FARs -            for command_id in commands: -                #skip commands starting with an unknown command byte -                if len(commands[command_id]) == 0: continue - -                if commands[command_id]["type"] == 0x17: -                    TX_FAR = parse_text_script(commands[command_id]["pointer"], text_id, map_id, txfar=True) -                    if debug: -                        if len(TX_FAR.keys()) > 0: -                            #print "TX_FAR object: " + str(TX_FAR) -                            print "processing a TX_FAR at " + hex(commands[command_id]["pointer"]) + "... first byte is: " + str(ord(extract_maps.rom[commands[command_id]["pointer"]])) + " .. offset: " + hex(commands[command_id]["pointer"]) -                            ##sys.exit(0) - -                    commands[command_id]["TX_FAR"] = TX_FAR -                    #map2["texts"][text_id][command_id]["TX_FAR"] = parse_text_script(command["pointer"], text_id, map_id) -            map2["texts"][text_id] = commands - -        texts[map_id] = map2["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) -    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" -     -    #start with zero please -    byte_count = 0 - -    output = "" -    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(): -            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 + " ; " + hex(command["pointer"]) -                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 -            elif command["type"] == 0x0b: -                if first_line: -                    output = "\n" + label + ": ; " + hex(start_address) -                    first_line = False -                if had_db_last: -                    output += ", $0b" -                else: -                    output += "\n" + spacing + "db $0B" -                byte_count += 1 -                had_db_last = True -            elif command["type"] == 0x11: -                if first_line: -                    output = "\n" + label + ": ; " + hex(start_address) -                    first_line = False -                if had_db_last: -                    output += ", $11" -                else: -                    output += "\n" + spacing + "db $11" -                byte_count += 1 -                had_db_last = True -            elif command["type"] == 0x6: #wait for keypress -                if first_line: -                    output = "\n" + label + ": ; " + hex(start_address) -                    first_line = False -                if had_db_last: -                    output += ", $6" -                else: -                    output += "\n" + spacing + "db $6" -                byte_count += 1 -                had_db_last = True -            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 -        #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: -            line = lines[line_id] -            output += spacing + "db " -            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 += ", \"" -                        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" -    include_newline = "\n" -    if len(output)!=0 and output[-1] == "\n": -        include_newline = "" -    output += include_newline + "; " + hex(start_address) + " + " + str(byte_count) + " bytes = " + hex(start_address + byte_count) -    print output -    return (output, byte_count) - -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]) - -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() -    #print 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" -     -    #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." -    #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" - -    #text_pretty_printer_at(0x800b1) -    #find_undone_texts() - -    scan_rom_for_tx_fars() diff --git a/extras/connection_helper.py b/extras/connection_helper.py deleted file mode 100644 index c15b3582..00000000 --- a/extras/connection_helper.py +++ /dev/null @@ -1,104 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-15 -#help with connection math -import extract_maps -from pretty_map_headers import map_constants, map_name_cleaner, offset_to_pointer - -def print_connections(map_id, in_connection_id=None, do_output=False): -    map1        = extract_maps.map_headers[map_id] -    map1_name   = map1["name"] -    connections = map1["connections"] -    output = "" -     -    if in_connection_id != None: -        connections2 = {} -        connections2[in_connection_id] = connections[in_connection_id] -        connections = connections2 -     -    for connection_id in connections: -        connection          = connections[connection_id] -        direction           = connection["direction"] -        connected_pointer   = int(connection["connected_map_tile_pointer"], 16) -        current_pointer     = int(connection["current_map_tile_pointer"], 16) -        map2_id             = connection["map_id"] -        map2                = extract_maps.map_headers[map2_id] -        map2_name           = map2["name"] -        map2_cname          = map_name_cleaner(map2["name"], None)[:-2] -        map2_bank           = int(map2["bank"], 16) -        map2_blocks_pointer = offset_to_pointer(int(map2["map_pointer"], 16)) -        map2_height         = int(map2["y"], 16) -        map2_width          = int(map2["x"], 16) - -        output +=  map1_name + " (id=" + str(map_id) + ") " + direction + " to " + map2_name + "\n" -        output +=  "map2 blocks pointer: " + hex(map2_blocks_pointer) + "\n" -        output +=  "map2 height: " + str(map2_height) + "\n" -        output +=  "map2 width: " + str(map2_width) + "\n" -        output +=  "map1 connection pointer: " + hex(connected_pointer) + "\n" -         -        shift = 0 -        #not sure about the calculated shift for NORTH or SOUTH -        if  direction == "NORTH": -            calculated = map2_blocks_pointer + (map2_height - 3) * map2_width -            result = connected_pointer - calculated -            if result != 0: -                shift = result #seems to always be 2? -                calculated = map2_blocks_pointer + (map2_height - 3) * map2_width + shift -                output += "shift: " + str(shift) + "\n" -                formula = map2_cname + "Blocks + (" + map2_cname + "Height - 3) * " + map2_cname + "Width + " + str(shift) -            else: -                formula = map2_cname + "Blocks + (" + map2_cname + "Height - 3) * " + map2_cname + "Width" -        elif direction == "SOUTH": -            calculated = map2_blocks_pointer -            result = connected_pointer - calculated -            formula = map2_cname + "Blocks" -            if result != 0: -                shift = result -                calculated = map2_blocks_pointer + shift -                output += "shift: " + str(shift) + "\n" -                formula += " + " + str(shift) -        elif direction == "WEST": -            calculated = map2_blocks_pointer - 3 + (map2_width) -            result = connected_pointer - calculated -            formula = map2_cname + "Blocks - 3 + (" + map2_cname + "Width)" -            if result != 0: -                shift = result / map2_width -                shift += 1 -                calculated = map2_blocks_pointer - 3 + (map2_width * shift) -                output += "shift: " + str(shift) + "\n" -                formula = map2_cname + "Blocks - 3 + (" + map2_cname + "Width * " + str(shift) + ")" -        elif direction == "EAST": -            calculated = map2_blocks_pointer + (map2_width) -            result = connected_pointer - calculated -            output += ".. result is: " + str(result) + "\n" -            formula = map2_cname + "Blocks + (" + map2_cname + "Width)" -            if result != 0: -                shift = result / map2_width -                shift += 1 -                calculated = map2_blocks_pointer + (map2_width * shift) -                output += "shift: " + str(shift) + "\n" -                formula = map2_cname + "Blocks" + " + (" + map2_cname + "Width * " + str(shift) + ")" -         -        output += "formula: " + formula + "\n" - -        result = connected_pointer - calculated -        output += "result: " + str(result) + "\n" - -        output += "\n\n" -     -    if in_connection_id != None: -        return formula -    if do_output == True: -        return output - -if __name__ == "__main__": -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() -     -    #trouble: -    #print_connections(13) -    #print_connections(15) -     -    for map_id in extract_maps.map_headers.keys(): -        if map_id not in extract_maps.bad_maps: -            print print_connections(map_id, do_output=True) diff --git a/extras/extract_maps.py b/extras/extract_maps.py deleted file mode 100644 index bc0a1933..00000000 --- a/extras/extract_maps.py +++ /dev/null @@ -1,702 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-02 -#url: http://hax.iimarck.us/files/rbheaders.txt -import json - -#parse hex values as base 16 (see calculate_pointer) -base = 16 - -#where to load the rom from -rom_filename = "../baserom.gbc" -rom = None #load the rom later - -#map header pointers start at 0x1AE -start_map_header_pointers = 0x1AE - -#bank bytes for each map header start at 0xC23D -start_map_header_pointer_banks = 0xC23D - -#number of maps in this list -map_count = 0xF8 #including the 0th the total is is 248 or 0xF8 - -bad_maps = [0x0b, 0x45, 0x4b, 0x4e, 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x72, 0x73, 0x74, 0x75, 0xad, 0xcc, 0xcd, 0xce, 0xe7, 0xed, 0xee, 0xf1, 0xf2, 0xf3, 0xf4] - -maps = { -         0x00: "Pallet Town", -         0x01: "Viridian City", -         0x02: "Pewter City", -         0x03: "Cerulean City", -         0x04: "Lavender Town", #?? -         0x05: "Vermilion City", #correct -         0x06: "Celadon City", -         0x07: "Fuchsia City", -         0x08: "Cinnabar Island", -         0x09: "Indigo Plateau", -         0x0A: "Saffron City", -         0x0B: "FREEZE", -         0x0C: "Route 1", -         0x0D: "Route 2", -         0x0E: "Route 3", -         0x0F: "Route 4", -         0x10: "Route 5", -         0x11: "Route 6", -         0x12: "Route 7", -         0x13: "Route 8", -         0x14: "Route 9", -         0x15: "Route 10", -         0x16: "Route 11", -         0x17: "Route 12", -         0x18: "Route 13", -         0x19: "Route 14", -         0x1A: "Route 15", -         0x1B: "Route 16", -         0x1C: "Route 17", -         0x1D: "Route 18", -         0x1E: "Route 19", -         0x1F: "Route 20", -         0x20: "Route 21", -         0x21: "Route 22", -         0x22: "Route 23", -         0x23: "Route 24", -         0x24: "Route 25", -         0x25: "Red's House 1F", -         0x26: "Red's House 2F", -         0x27: "Blue's House", -         0x28: "Oak's Lab", -         0x29: "Viridian Poke Center", -         0x2A: "Viridian Mart", -         0x2B: "School", -         0x2C: "Viridian House", -         0x2D: "Viridian Gym", -         0x2E: "Digletts Cave (Route 2)", -         0x2F: "Viridian Forest (exit)", -         0x30: "Route 2 House", -         0x31: "Route 2 Gate", -         0x32: "Viridian Forest (Entrance)", -         0x33: "Viridian Forest", -         0x34: "Museum F1", -         0x35: "Museum F2", -         0x36: "Pewter Gym", -         0x37: "Pewter House (1)", -         0x38: "Pewter Mart", -         0x39: "Pewter House (2)", -         0x3A: "Pewter Pokecenter", -         0x3B: "Mt. Moon (1)", -         0x3C: "Mt. Moon (2)", -         0x3D: "Mt. Moon (3)", -         0x3E: "Cerulean House (Trashed)", -         0x3F: "Cerulean House (2)", -         0x40: "Cerulean Pokecenter", -         0x41: "Cerulean Gym", -         0x42: "Bike Shop", -         0x43: "Cerulean Mart", -         0x44: "Mt. Moon Pokecenter", -         0x45: "COPY OF: Trashed House", -         0x46: "Route 5 Gate", -         0x47: "Underground Tunnel Entrance (Route 5)", -         0x48: "Day Care M", -         0x49: "Route 6 Gate", -         0x4A: "Underground Tunnel Entrance (Route 6)", -         0x4B: "COPY OF: Underground Tunnel Entrance (Route 6)", -         0x4C: "Route 7 Gate", -         0x4D: "Underground Path Entrance (Route 7)", -         0x4E: "COPY OF: Underground Path Entrance (Route 7)", -         0x4F: "Route 8 Gate", -         0x50: "Underground Path Entrance (Route 8)", -         0x51: "Rock Tunnel Pokecenter", -         0x52: "Rock Tunnel (1)", -         0x53: "Power Plant", -         0x54: "Route 11 Gate", -         0x55: "Digletts Cave Entrance (Route 11)", -         0x56: "Route 11 Gate (Upstairs)", -         0x57: "Route 12 Gate", -         0x58: "Bill's House", -         0x59: "Vermilion Pokecenter", -         0x5A: "Fan Club", -         0x5B: "Vermilion Mart", -         0x5C: "Vermilion Gym", -         0x5D: "Vermilion House (1)", -         0x5E: "Vermilion Dock", -         0x5F: "S.S. Anne (1)", -         0x60: "S.S. Anne (2)", -         0x61: "S.S. Anne (3)", -         0x62: "S.S. Anne (4)", -         0x63: "S.S. Anne (5)", -         0x64: "S.S. Anne (6)", -         0x65: "S.S. Anne (7)", -         0x66: "S.S. Anne (8)", -         0x67: "S.S. Anne (9)", -         0x68: "S.S. Anne (10)", -         0x69: "FREEZE", -         0x6A: "FREEZE", -         0x6B: "FREEZE", -         0x6C: "Victory Road (1)", -         0x6D: "FREEZE", -         0x6E: "FREEZE", -         0x6F: "FREEZE", -         0x70: "FREEZE", -         0x71: "Lance", -         0x72: "FREEZE", -         0x73: "FREEZE", -         0x74: "FREEZE", -         0x75: "FREEZE", -         0x76: "Hall of Fame Room", -         0x77: "Underground Path (N/S)", -         0x78: "Gary", -         0x79: "Underground Path (W/E)", -         0x7A: "Celadon Mart (1)", -         0x7B: "Celadon Mart (2)", -         0x7C: "Celadon Mart (3)", -         0x7D: "Celadon Mart (4)", -         0x7E: "Celadon Mart Roof", -         0x7F: "Celadon Mart Elevator", -         0x80: "Celadon Mansion (1)", -         0x81: "Celadon Mansion (2)", -         0x82: "Celadon Mansion (3)", -         0x83: "Celadon Mansion (4)", -         0x84: "Celadon Mansion (5)", -         0x85: "Celadon Pokecenter", -         0x86: "Celadon Gym", -         0x87: "Celadon Game Corner", -         0x88: "Celadon Mart 5", -         0x89: "Celadon Prize Room", -         0x8A: "Celadon Diner", -         0x8B: "Celadon House", -         0x8C: "Celadon Hotel", -         0x8D: "Lavender Pokecenter", -         0x8E: "Pokemon Tower (1)", -         0x8F: "Pokemon Tower (2)", -         0x90: "Pokemon Tower (3)", -         0x91: "Pokemon Tower (4)", -         0x92: "Pokemon Tower (5)", -         0x93: "Pokemon Tower (6) ", -         0x94: "Pokemon Tower (7)", -         0x95: "Lavender House (1)", -         0x96: "Lavender Mart", -         0x97: "Lavender House (2)", -         0x98: "Fuchsia Mart", -         0x99: "Fuchsia House (1)", -         0x9A: "Fuchsia Pokecenter", -         0x9B: "Fuchsia House (2)", -         0x9C: "Safari Zone Entrance", -         0x9D: "Fuchsia Gym", -         0x9E: "Fuchsia Meeting Room", -         0x9F: "Seafoam Islands (2)", -         0xA0: "Seafoam Islands (3)", -         0xA1: "Seafoam Islands (4)", -         0xA2: "Seafoam Islands (5)", -         0xA3: "Vermilion House (2)", -         0xA4: "Fuchsia House (3)", -         0xA5: "Mansion (1)", -         0xA6: "Cinnabar Gym", -         0xA7: "Lab (1)", -         0xA8: "Lab (2)", -         0xA9: "Lab (3)", -         0xAA: "Lab (4)", -         0xAB: "Cinnabar Pokecenter", -         0xAC: "Cinnabar Mart", -         0xAD: "COPY: Cinnabar Mart", -         0xAE: "Indigo Plateau Lobby", -         0xAF: "Copycat's House F1", -         0xB0: "Copycat's House F2", -         0xB1: "Fighting Dojo", -         0xB2: "Saffron Gym", -         0xB3: "Saffron House (1)", -         0xB4: "Saffron Mart", -         0xB5: "Silph Co (1)", -         0xB6: "Saffron Pokecenter", -         0xB7: "Saffron House (2)", -         0xB8: "Route 15 Gate", -         0xBA: "Route 16 Gate Map", -         0xBB: "Route 16 Gate Upstairs", -         0xBC: "Route 16 House", -         0xBD: "Route 12 House", -         0xBE: "Route 18 Gate", -         0xBF: "Route 18 Gate Header", -         0xC0: "Seafoam Islands (1)", -         0xC1: "Route 22 Gate", -         0xC2: "Victory Road (2)", -         0xC3: "Route 12 Gate Upstairs", -         0xC4: "Vermilion House (3)", -         0xC5: "Diglett's Cave", -         0xC6: "Victory Road (3)", -         0xC7: "Rocket Hideout (1)", -         0xC8: "Rocket Hideout (2)", -         0xC9: "Rocket Hideout (3)", -         0xCA: "Rocket Hideout (4) ", -         0xCB: "Rocket Hideout (Elevator)", -         0xCC: "FREEZE", -         0xCD: "FREEZE", -         0xCE: "FREEZE", -         0xCF: "Silph Co (2)", -         0xD0: "Silph Co (3)", -         0xD1: "Silph Co (4)", -         0xD2: "Silph Co (5)", -         0xD3: "Silph Co (6)", -         0xD4: "Silph Co (7)", -         0xD5: "Silph Co (8)", -         0xD6: "Mansion (2)", -         0xD7: "Mansion (3)", -         0xD8: "Mansion (4)", -         0xD9: "Safari Zone East", -         0xDA: "Safari Zone North", -         0xDB: "Safari Zone West", -         0xDC: "Safari Zone Center", -         0xDD: "Safari Zone Rest House (1)", -         0xDE: "Safari Zone Secret House", -         0xDF: "Safari Zone Rest House (2)", -         0xE0: "Safari Zone Rest House (3)", -         0xE1: "Safari Zone Rest House (4)", -         0xE2: "Unknown Dungeon (2)", -         0xE3: "Unknown Dungeon (3)", -         0xE4: "Unknown Dungeon (1)", -         0xE5: "Name Rater", -         0xE6: "Cerulean House (3)", -         0xE7: "FREEZE", -         0xE8: "Rock Tunnel (2)", -         0xE9: "Silph Co (9)", -         0xEA: "Silph Co (10)", -         0xEB: "Silph Co (11)", -         0xEC: "Silph Co (Elevator)", -         0xED: "FREEZE", -         0xEE: "FREEZE", -         0xEF: "Battle Center M", -         0xF0: "Trade Center M", -         0xF1: "FREEZE", -         0xF2: "FREEZE", -         0xF3: "FREEZE", -         0xF4: "FREEZE", -         0xF5: "Lorelei", -         0xF6: "Bruno", -         0xF7: "Agatha" -       } - -map_pointers = { -    #0x00: { -    #       "name": "Pallet Town", -    #       "address": 0x182a1 -    #      }, -               } - -map_headers = { -    #0x00: { -    #       "name": "Pallet Town", -    #       "address": 0x182a1, -    #       "tileset" -    #       "y" -    #       "x" -    #       "map_pointer" -    #       "texts_pointer" -    #       "script_pointer" -    #       "connection_byte" -    #       "num_connections" -    #       "connections": -    #        { "0": -    #          { map_id, connected_map_tile_pointer, current_map_tile_pointer, bigness, width, y, x, window_pointer } -    #        }, -    #       "object_data_pointer" -    #      }, -              } - -#haters gonna hate -def load_rom(filename=None): -    "load the rom into a global (returns True/False)" -    global rom - -    if not filename: -        filename = rom_filename - -    try: -        rom = open(filename, "rb").read() -        return True -    except Exception, exception: -        print "error loading rom" -        return False - -def assert_rom(): -    global rom -    assert rom, "rom must be loaded, see load_rom()" - -def calculate_pointer(short_pointer, bank): -    short_pointer = int(short_pointer) -    bank = int(bank) - -    pointer = short_pointer - 0x4000 + (bank * 0x4000) - -    #result will be an integer -    return pointer - -def get_nth_map_header_pointer_bank_byte_address(map_id): -    "returns the address to the bank byte associated with this map pointer" -    address = start_map_header_pointer_banks + map_id -    return address - -def get_nth_map_header_pointer_bank_byte(map_id): -    "returns the bank number for this map header" -    assert_rom() - -    address = get_nth_map_header_pointer_bank_byte_address(map_id) -    bank_byte = ord(rom[address]) -    return bank_byte - -def get_nth_map_header_pointer(map_id): -    "returns the full pointer to the map header struct for this map" -    assert_rom() - -    #figure out where the bytes for this pointer are located -    byte1_address = start_map_header_pointers + (map_id * 2) -    byte2_address = start_map_header_pointers + (map_id * 2) + 1 - -    #grab the two bytes making up the partial pointer -    byte1 = ord(rom[byte1_address]) -    byte2 = ord(rom[byte2_address]) - -    #swap the bytes (16-bit pointers for z80 are little endian) -    temp = byte1 -    byte1 = byte2 -    byte2 = temp -    del temp - -    #combine these into a single pointer (0x byte1 byte2) -    partial_pointer = (byte2 + (byte1 << 8)) -    #print hex(partial_pointer) - -    #get the bank id -    bank = get_nth_map_header_pointer_bank_byte(map_id) - -    #calculate the full pointer -    pointer = calculate_pointer(partial_pointer, bank) - -    #return it as an integer -    return pointer - -def load_map_pointers(): -    global maps -    global map_pointers - -    for map in maps.keys(): -        pointer = get_nth_map_header_pointer(map) -        #print maps[map] + "\t\t\t" + hex(pointer) - -        entry = { -                "name": maps[map], -                "address": hex(pointer), -                "bank": hex(get_nth_map_header_pointer_bank_byte(map)) -                } -        map_pointers[map] = entry -     -    #print json.dumps(map_pointers) - -def read_connection_bytes(connection_bytes, bank): -    map_id = ord(connection_bytes[0]) -     -    #connection strip -    connected_map_tile_pointer_byte1 = ord(connection_bytes[1]) -    connected_map_tile_pointer_byte2 = ord(connection_bytes[2]) -    connected_map_tile_pointer = (connected_map_tile_pointer_byte1 + (connected_map_tile_pointer_byte2 << 8)) - -    #connection strip -    current_map_tile_pointer_byte1 = ord(connection_bytes[3]) -    current_map_tile_pointer_byte2 = ord(connection_bytes[4]) -    current_map_tile_pointer = (current_map_tile_pointer_byte1 + (current_map_tile_pointer_byte2 << 8)) - -    bigness_byte = ord(connection_bytes[5]) -    width_byte = ord(connection_bytes[6]) -    y = ord(connection_bytes[7]) -    x = ord(connection_bytes[8]) - -    #window -    window_pointer_byte1 = ord(connection_bytes[9]) -    window_pointer_byte2 = ord(connection_bytes[10]) -    window_pointer = (window_pointer_byte1 + (window_pointer_byte2 << 8)) - -    connection_data = { -                      "map_id": map_id, -                      "connected_map_tile_pointer": hex(connected_map_tile_pointer), -                      "current_map_tile_pointer": hex(current_map_tile_pointer), -                      "bigness": hex(bigness_byte), -                      "width": hex(width_byte), -                      "y": y, -                      "x": x, -                      "window_pointer": hex(window_pointer), -                      } -    return connection_data - -def read_warp_data(address, warp_count): -    warps = {} -    for warp_id in range(0, warp_count): -        offset = address + (warp_id*4) #4 bytes per warp -        warp = {} -         -        warp["y"] = ord(rom[offset]) -        warp["x"] = ord(rom[offset+1]) -        warp["warp_to_point"] = ord(rom[offset+2]) -        warp["warp_to_map_id"] = ord(rom[offset+3]) - -        warps[warp_id] = warp -    return warps - -def read_sign_data(address, sign_count): -    signs = {} -    for sign_id in range(0, sign_count): -        offset = address + (sign_id * 3) -        sign = {} -        sign["y"] = ord(rom[offset]) -        sign["x"] = ord(rom[offset+1]) -        sign["text_id"] = ord(rom[offset+2]) -        signs[sign_id] = sign -    return signs - -def read_warp_tos(address, warp_count): -    warp_tos = {} -    for warp_to_id in range(0, warp_count): -        offset = address + (warp_to_id * 4) -        warp_to = {} -        warp_to["event_displacement"] = [ord(rom[offset]),ord(rom[offset+1])] -        warp_to["y"] = ord(rom[offset+2]) -        warp_to["x"] = ord(rom[offset+3]) -        warp_tos[warp_to_id] = warp_to -    return warp_tos - -def get_object_data(address): -    if type(address) == str: address = int(address, base) -    output = {} - -    maps_border_tile = ord(rom[address]) -     -    number_of_warps = ord(rom[address+1]) -    if number_of_warps == 0: warps = {} -    else: -        warps = read_warp_data(address+2, number_of_warps) - -    offset = number_of_warps * 4 -    address = address + 2 + offset - -    number_of_signs = ord(rom[address]) -    if number_of_signs == 0: signs = {} -    else: -        signs = read_sign_data(address+1, number_of_signs) - -    offset = number_of_signs * 3 -    address = address + 1 + offset - -    number_of_things = ord(rom[address]) -    address = address + 1 - -    things = {} -    for thing_id in range(0, number_of_things): -        thing = {} -        picture_number = ord(rom[address]) -        y = ord(rom[address+1]) -        x = ord(rom[address+2]) -        movement1 = ord(rom[address+3]) -        movement2 = ord(rom[address+4]) -        text_string_number = ord(rom[address+5]) - -        address += 5 + 1 - -        if text_string_number & (1 << 6) != 0: #trainer -            thing["type"] = "trainer" -            thing["trainer_type"] = ord(rom[address]) -            thing["pokemon_set"] = ord(rom[address+1]) -            address += 2 -        elif text_string_number & (1 << 7) != 0: #item -            thing["type"] = "item" -            thing["item_number"] = ord(rom[address]) -            address += 1 -        else: #normal person -            thing["type"] = "person" - -        thing["picture_number"] = picture_number -        thing["y"] = y -        thing["x"] = x -        thing["movement1"] = movement1 -        thing["movement2"] = movement2 -        thing["original_text_string_number"] = text_string_number -        thing["text_string_number"] = text_string_number & 0xF -        things[thing_id] = thing - -    warp_tos = read_warp_tos(address, number_of_warps) - -    output["maps_border_tile"] = maps_border_tile -    output["number_of_warps"] = number_of_warps -    output["warps"] = warps -    output["number_of_signs"] = number_of_signs -    output["signs"] = signs -    output["number_of_things"] = number_of_things -    output["things"] = things -    output["warp_tos"] = warp_tos - -    return output - -def compute_object_data_size(object): -    size = 4 -    size += 6 * (int(object["number_of_things"])) -     -    trainer_count = 0 -    item_count = 0 -    for thing in object["things"]: -        thing = object["things"][thing] -        if thing["type"] == "trainer": trainer_count += 1 -        elif thing["type"] == "item": item_count += 1 -     -    size += 2 * trainer_count -    size += item_count - -    size += 8 * object["number_of_warps"] -    size += 3 * object["number_of_signs"] - -    return size - -def get_direction(connection_byte, connection_id): -    """given a connection byte and a connection id, which direction is this connection? -    the 0th connection of $5 is SOUTH and the 1st connection is EAST""" -    connection_options = [0b1000, 0b0100, 0b0010, 0b0001] -    results = ["NORTH", "SOUTH", "WEST", "EAST"] -    for option in connection_options: -        if (option & connection_byte) == 0: -            results[connection_options.index(option)] = "" -    #prune results -    while "" in results: -        results.remove("") -    return results[connection_id] - -def read_map_header(address, bank): -    address = int(address, base) -    bank = int(bank, base) - -    tileset = ord(rom[address]) -    y = ord(rom[address+1]) -    x = ord(rom[address+2]) - -    map_pointer_byte1 = ord(rom[address+3]) -    map_pointer_byte2 = ord(rom[address+4]) -    partial_map_pointer = (map_pointer_byte1 + (map_pointer_byte2 << 8)) -    map_pointer = calculate_pointer(partial_map_pointer, bank) - -    texts_pointer_byte1 = ord(rom[address+5]) -    texts_pointer_byte2 = ord(rom[address+6]) -    partial_texts_pointer = (texts_pointer_byte1 + (texts_pointer_byte2 << 8)) -    texts_pointer = calculate_pointer(partial_texts_pointer, bank) - -    script_pointer_byte1 = ord(rom[address+7]) -    script_pointer_byte2 = ord(rom[address+8]) -    partial_script_pointer = (script_pointer_byte1 + ( script_pointer_byte2 << 8)) -    script_pointer = calculate_pointer(partial_script_pointer, bank) - -    connection_byte = ord(rom[address+9]) #0xc = NORTH | SOUTH -    # <&IIMarckus> the connection byte is a bitmask allowing 0-4 connections -    # <&IIMarckus> each connection is 11 bytes -    # <&IIMarckus> or'd -    # <&IIMarckus> east = 1, west = 2, south = 4, north = 8 -    # <&IIMarckus> so a connection byte of 0xc means north/south -    # <&IIMarckus> which means there are 22 more bytes, 11 for each connection -    # < kanzure> 4 | 8 = c? -    # <&IIMarckus> yes -    # <&IIMarckus> easier to see if you convert to binary -    # <&IIMarckus> 0100 | 1000 = 1100 - -    num_connections = 0 -    connection_value = bin(connection_byte)[2:] -    if connection_value[0] == "1": #NORTH -        num_connections += 1 -    if len(connection_value) > 1 and connection_value[1] == "1": #SOUTH -        num_connections += 1 -    if len(connection_value) > 2 and connection_value[2] == "1": #WEST -        num_connections += 1 -    if len(connection_value) > 3 and connection_value[3] == "1": #EAST -        num_connections += 1 -  -    #quick test for connection data -    #connection0_stuff = rom[(address + 10):(address + 10 + 11)] -    #print "Route: " + hex(ord(connection0_stuff[0])) - -    #setup -    connections = {} - -    #go straight to object data if there are no connections -    if num_connections > 0: -        for connection in range(0, num_connections): -            base_connection_address = address + 10 + (11 * connection) -            connection_bytes = rom[base_connection_address : base_connection_address + 11] -            connection_data = read_connection_bytes(connection_bytes, bank) -            connection_data["direction"] = get_direction(connection_byte, connection) - -            connections[connection] = connection_data - -    #we might have to jump around a bit -    offset = address + 10 + (11 * num_connections) - -    #object data -    object_data_pointer_byte1 = ord(rom[offset]) -    object_data_pointer_byte2 = ord(rom[offset+1]) -    partial_object_data_pointer = (object_data_pointer_byte1 + (object_data_pointer_byte2 << 8)) -    object_data_pointer = calculate_pointer(partial_object_data_pointer, bank) -    object_data = get_object_data(object_data_pointer) - -    texts = set() -    for thing_id in object_data["things"].keys(): -        thing = object_data["things"][thing_id] -        texts.add(thing["text_string_number"]) -    for sign_id in object_data["signs"].keys(): -        sign = object_data["signs"][sign_id] -        texts.add(sign["text_id"]) -    texts = list(texts) -    number_of_referenced_texts = len(texts) - -    map_header = { -                 "tileset": hex(tileset), -                 "y": hex(y), -                 "x": hex(x), -                 "map_pointer": hex(map_pointer), -                 "texts_pointer": hex(texts_pointer), -                 "number_of_referenced_texts": number_of_referenced_texts, -                 "referenced_texts": texts, -                 "script_pointer": hex(script_pointer), -                 "connection_byte": hex(connection_byte), -                 "num_connections": str(num_connections), -                 "connections": connections, #NORTH, SOUTH, WEST, EAST order matters -                 "object_data_pointer": hex(object_data_pointer), -                 "object_data": object_data, -                 } -    return map_header - -def read_all_map_headers(): -    if rom == None: load_rom() -    assert_rom() -    if len(map_pointers) == 0: load_map_pointers() - -    for map_id in map_pointers.keys(): -        if map_id in bad_maps: continue -        map2 = map_pointers[map_id] -        map_header = read_map_header(map2["address"], map2["bank"]) - -        map_header["id"] = map_id -        map_header["name"] = map2["name"] -        map_header["address"] = map2["address"] -        map_header["bank"] = map2["bank"] - -        map_headers[map_id] = map_header -     -    return map_headers - -if __name__ == "__main__": -    #read binary data from file -    load_rom() -     -    #where are the map structs? -    load_map_pointers() -    #print json.dumps(map_pointers) - -    #experimental... -    #print json.dumps(read_map_header(map_pointers[0]["address"], map_pointers[0]["bank"])) - -    read_all_map_headers() -    #print json.dumps(map_headers) - -    #print map_headers[37] - -    for header in map_headers: -        if header in bad_maps: continue -        print "map " + str(header) + " has " + str(map_headers[header]["number_of_referenced_texts"]) + " referenced texts" - diff --git a/extras/extract_tileblocks.py b/extras/extract_tileblocks.py deleted file mode 100644 index 1d01c340..00000000 --- a/extras/extract_tileblocks.py +++ /dev/null @@ -1,94 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-14 -#split out blocksets into binary data files -# There's also code here to spit out asm for each blockset, -# but it's too many lines and will probably crash rgbasm. - -import sys -import extract_maps -extract_maps.load_rom() -spacing = "	" - -tileblocks = { -"Tset00_Block": [0x645E0, 0x64DE0, ""], -"Tset01_Block": [0x65270, 0x653A0, ""], -"Tset02_Block": [0x693BF, 0x6960F, ""], -"Tset03_Block": [0x6A9FF, 0x6B1FF, ""], -"Tset05_Block": [0x6867F, 0x68DBF, ""], -"Tset08_Block": [0x65980, 0x65BB0, ""], -"Tset09_Block": [0x69BFF, 0x6A3FF, ""], -"Tset0B_Block": [0x6FEF0, 0x70000, ""], -"Tset0D_Block": [0x6E930, 0x6ED10, ""], -"Tset0E_Block": [0x66BF0, 0x66D60, ""], -"Tset0F_Block": [0x6C5C0, 0x6CCA0, ""], -"Tset10_Block": [0x67350, 0x676F0, ""], -"Tset13_Block": [0x66190, 0x66610, ""], -"Tset11_Block": [0x6D0C0, 0x6D8C0, ""], -"Tset12_Block": [0x6DEA0, 0x6E390, ""], -"Tset14_Block": [0x6F2D0, 0x6F670, ""], -"Tset15_Block": [0x6FB20, 0x6FD60, ""], -"Tset16_Block": [0x6B7FF, 0x6C000, ""], -"Tset17_Block": [0x67B50, 0x68000, ""], -} - -#10:02 <+sawakita> each block is composed by 4x4 tiles -#10:03 <+sawakita> so you can see a blockset as a list of 16-bytes long arrays -#10:07 <+sawakita> 4 bytes for each row of the block, left-to-right, top-to-down -#10:08 <+sawakita> so first byte is top-left tile -#10:08 <+kanzure> top-left tile byte is a tile id? -#10:08 <+sawakita> exactly -#10:09 <+kanzure> what does a tile id reference -#10:10 <+sawakita> tile ID $00 is the first tile of the tileset's graphics (first 16-bytes, since gfx are 2bpp) - -output = "" -for tileblock_id in tileblocks.keys(): -    tileblock = tileblocks[tileblock_id] -    start_address = tileblock[0] -    end_address = tileblock[1] -    block_count = (end_address - start_address) / 16 -    main_data = extract_maps.rom[start_address:end_address] -     -    blockset_id = int(tileblock_id[4:6], 16) -     -    output = "; " -    output += tileblock_id + " - " + str(block_count) + " blocks (" + hex(start_address) + " to " + hex(end_address) + ")\n" -    #print tileblock_id + " has " + str(block_count) + " block tiles." -    for block_id in range(0, block_count): -        start_address2 = start_address + (16 * block_id) -        end_address2 = start_address + (16 * block_id) + 16 -        data = extract_maps.rom[start_address2:end_address2] -     -        output += spacing + "; block " + str(block_id + 1) + " on " + tileblock_id + "\n" -         -        #output += spacing + spacing + "db $%.2x" % (ord(data[0])) -        #for data_bit in range(1,15): -        #    output += ", $%.2x" % (ord(data[data_bit])) -        #output += ", $%.2x" % (ord(data[15])) -        #output += "\n" - -        for row_id in range(0,4): -            subdata = data[row_id * 4:row_id * 4 + 4] -            subdata2 = [ord(subdata[0]), ord(subdata[1]), ord(subdata[2]), ord(subdata[3])] - -            output += spacing + spacing + " ; row " + str(row_id + 1) + "\n" -            output += spacing + spacing + spacing + "db $%.2x, $%.2x, $%.2x, $%.2x\n" % (subdata2[0], subdata2[1], subdata2[2], subdata2[3]) -     -    fh = open("../gfx/blocksets/%.2x.bst" % (blockset_id), "w") -    fh.write(main_data) -    fh.close() - -    print output - -""" -Tset00_Block: -    ; block 1 -        ; row 1 -            db 0, 0, 0, 0 -        ; row 2 -            db 0, 0, 0, 0 -        ; row 3 -            db 0, 0, 0, 0 -        ; row 4 -            db 0, 0, 0, 0 -""" - diff --git a/extras/extract_tilesets.py b/extras/extract_tilesets.py deleted file mode 100644 index a0eb4773..00000000 --- a/extras/extract_tilesets.py +++ /dev/null @@ -1,37 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-14 -#throw tilesets into separate files -import extract_maps -extract_maps.load_rom() - -locations = { -"Tset00_GFX": [0x64000, 0x645E0, "00"], -"Tset01_GFX": [0x64DE0, 0x65270, "01"], -"Tset08_GFX": [0x653A0, 0x65980, "08"], -"Tset13_GFX": [0x65BB0, 0x66190, "13"], -"Tset0E_GFX": [0x66610, 0x66BF0, "0e"], -"Tset10_GFX": [0x66D60, 0x67350, "10"], -"Tset17_GFX": [0x676F0, 0x67B50, "17"], -"Tset05_GFX": [0x6807F, 0x6867F, "05"], -"Tset02_GFX": [0x68DBF, 0x693BF, "02"], -"Tset09_GFX": [0x6960F, 0x69BFF, "09"], -"Tset03_GFX": [0x6A3FF, 0x6A9FF, "03"], -"Tset16_GFX": [0x6B1FF, 0x6B7FF, "16"], -"Tset0F_GFX": [0x6C000, 0x6C5C0, "0f"], -"Tset11_GFX": [0x6CCA0, 0x6D0C0, "11"], -"Tset12_GFX": [0x6D8C0, 0x6DEA0, "12"], -"Tset0D_GFX": [0x6E390, 0x6E930, "0d"], -"Tset14_GFX": [0x6ED10, 0x6F2D0, "14"], -"Tset15_GFX": [0x6F670, 0x6FB20, "15"], -"Tset0B_GFX": [0x6FD60, 0x6FEF0, "0b"], -} - -for tileset_id in locations.keys(): -    tileset = locations[tileset_id] - -    print "writing ../gfx/tilesets/" + tileset[2] + ".2bpp" -    fh = open("../gfx/tilesets/" + tileset[2] + ".2bpp", "w") -    fh.write(extract_maps.rom[tileset[0]:tileset[1]]) -    fh.close() - -print "Done." diff --git a/extras/fix_labels.py b/extras/fix_labels.py deleted file mode 100644 index 321a18ea..00000000 --- a/extras/fix_labels.py +++ /dev/null @@ -1,82 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-27 -#fix trainer header labels to not suck so much -import analyze_incbins - -def replace_trainer_header_labels(debug=False): -    """trainer header labels could be better""" -    asm = analyze_incbins.asm -    if debug: print str(type(asm)) -    single_asm = "\n".join(asm) -    current_map_name = "asdjkl;" -    line_id = 0 -    trainer_header_counter = 1 - -    for line in asm: -        trainer_header_base = current_map_name + "TrainerHeader" -        trainer_header_name = trainer_header_base + str(trainer_header_counter) - -        #we've found a TrainerHeaders thing -        if "TrainerHeaders:" in line: -            current_map_name = line.split("TrainerHeaders")[0] -            if line[0:len(current_map_name)] == current_map_name: -                trainer_header_counter = 1 - -        #replace a trainer header label -        elif "TrainerHeader_" in line and line[0:14] == "TrainerHeader_": -            temp = line.split("TrainerHeader_")[1] -            temp = temp.split(": ;")[0] -             -            old_label = "TrainerHeader_" + temp -            new_label = current_map_name + "TH" + str(trainer_header_counter) #trainer_header_name -            single_asm = single_asm.replace(old_label + ":", new_label + ":") -            single_asm = single_asm.replace(old_label + "\n", new_label + "\n") -            if debug: print "old_label = " + old_label -            if debug: print "new_label = " + new_label - -            trainer_header_counter += 1 -         -        elif trainer_header_base in line and line[0:len(trainer_header_base)] == trainer_header_base and (line[len(trainer_header_base)+1:len(trainer_header_base)+2] == ":" or line[len(trainer_header_base)+2:len(trainer_header_base)+3] == ":"): -            if line[len(trainer_header_base)+1:len(trainer_header_base)+2] == ":": -                trainer_header_counter = int(line[len(trainer_header_base):len(trainer_header_base)+1]) -            elif line[len(trainer_header_base)+2:len(trainer_header_base)+3] == ":": -                trainer_header_counter = int(line[len(trainer_header_base):len(trainer_header_base)+2]) -            trainer_header_name = trainer_header_base + str(trainer_header_counter) - -        #replace a text label -        elif " TextBeforeBattle" in line and not current_map_name in line: -            old_label = line.split("dw ")[1].split(" ;")[0] -            new_label = current_map_name + "B4BattleTxt" + str(trainer_header_counter) #trainer_header_name + "BeforeBattleText" -            single_asm = single_asm.replace(old_label + ":", new_label + ":") -            single_asm = single_asm.replace(old_label + "\n", new_label + "\n") -            single_asm = single_asm.replace(old_label + " ;", new_label + " ;") -            if debug: print "old_label = " + old_label -            if debug: print "new_label = " + new_label -        #replace a text label -        elif " TextAfterBattle" in line and not current_map_name in line: -            old_label = line.split("dw ")[1].split(" ;")[0] -            new_label = current_map_name + "AfterBattleTxt" + str(trainer_header_counter) #trainer_header_name + "AfterBattleText" -            single_asm = single_asm.replace(old_label + ":", new_label + ":") -            single_asm = single_asm.replace(old_label + "\n", new_label + "\n") -            single_asm = single_asm.replace(old_label + " ;", new_label + " ;") -            if debug: print "old_label = " + old_label -            if debug: print "new_label = " + new_label -        #replace a text label -        elif " TextEndBattle" in line and not current_map_name in line: -            old_label = line.split("dw ")[1].split(" ;")[0] -            new_label = current_map_name + "EndBattleTxt" + str(trainer_header_counter) #trainer_header_name + "EndBattleText" -            single_asm = single_asm.replace(old_label + ":", new_label + ":") -            single_asm = single_asm.replace(old_label + "\n", new_label + "\n") -            single_asm = single_asm.replace(old_label + " ;", new_label + " ;") -            if debug: print "old_label = " + old_label -            if debug: print "new_label = " + new_label - -        line_id += 1 - -    print single_asm - -if __name__ == "__main__": -    analyze_incbins.load_asm() - -    replace_trainer_header_labels() -     diff --git a/extras/gbz80disasm.py b/extras/gbz80disasm.py deleted file mode 100644 index 53198988..00000000 --- a/extras/gbz80disasm.py +++ /dev/null @@ -1,853 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-09 -import extract_maps -import os -import json -from copy import copy, deepcopy -from pretty_map_headers import random_hash, map_name_cleaner -from ctypes import c_int8 -import sys -spacing = "	" - -temp_opt_table = [ -  [ "ADC A", 0x8f, 0 ], -  [ "ADC B", 0x88, 0 ], -  [ "ADC C", 0x89, 0 ], -  [ "ADC D", 0x8a, 0 ], -  [ "ADC E", 0x8b, 0 ], -  [ "ADC H", 0x8c, 0 ], -  [ "ADC [HL]", 0x8e, 0 ], -  [ "ADC L", 0x8d, 0 ], -  [ "ADC x", 0xce, 1 ], -  [ "ADD A", 0x87, 0 ], -  [ "ADD B", 0x80, 0 ], -  [ "ADD C", 0x81, 0 ], -  [ "ADD D", 0x82, 0 ], -  [ "ADD E", 0x83, 0 ], -  [ "ADD H", 0x84, 0 ], -  [ "ADD [HL]", 0x86, 0 ], -  [ "ADD HL, BC", 0x9, 0 ], -  [ "ADD HL, DE", 0x19, 0 ], -  [ "ADD HL, HL", 0x29, 0 ], -  [ "ADD HL, SP", 0x39, 0 ], -  [ "ADD L", 0x85, 0 ], -  [ "ADD SP, x", 0xe8, 1 ], -  [ "ADD x", 0xc6, 1 ], -  [ "AND A", 0xa7, 0 ], -  [ "AND B", 0xa0, 0 ], -  [ "AND C", 0xa1, 0 ], -  [ "AND D", 0xa2, 0 ], -  [ "AND E", 0xa3, 0 ], -  [ "AND H", 0xa4, 0 ], -  [ "AND [HL]", 0xa6, 0 ], -  [ "AND L", 0xa5, 0 ], -  [ "AND x", 0xe6, 1 ], -  [ "BIT 0, A", 0x47cb, 3 ], -  [ "BIT 0, B", 0x40cb, 3 ], -  [ "BIT 0, C", 0x41cb, 3 ], -  [ "BIT 0, D", 0x42cb, 3 ], -  [ "BIT 0, E", 0x43cb, 3 ], -  [ "BIT 0, H", 0x44cb, 3 ], -  [ "BIT 0, [HL]", 0x46cb, 3 ], -  [ "BIT 0, L", 0x45cb, 3 ], -  [ "BIT 1, A", 0x4fcb, 3 ], -  [ "BIT 1, B", 0x48cb, 3 ], -  [ "BIT 1, C", 0x49cb, 3 ], -  [ "BIT 1, D", 0x4acb, 3 ], -  [ "BIT 1, E", 0x4bcb, 3 ], -  [ "BIT 1, H", 0x4ccb, 3 ], -  [ "BIT 1, [HL]", 0x4ecb, 3 ], -  [ "BIT 1, L", 0x4dcb, 3 ], -  [ "BIT 2, A", 0x57cb, 3 ], -  [ "BIT 2, B", 0x50cb, 3 ], -  [ "BIT 2, C", 0x51cb, 3 ], -  [ "BIT 2, D", 0x52cb, 3 ], -  [ "BIT 2, E", 0x53cb, 3 ], -  [ "BIT 2, H", 0x54cb, 3 ], -  [ "BIT 2, [HL]", 0x56cb, 3 ], -  [ "BIT 2, L", 0x55cb, 3 ], -  [ "BIT 3, A", 0x5fcb, 3 ], -  [ "BIT 3, B", 0x58cb, 3 ], -  [ "BIT 3, C", 0x59cb, 3 ], -  [ "BIT 3, D", 0x5acb, 3 ], -  [ "BIT 3, E", 0x5bcb, 3 ], -  [ "BIT 3, H", 0x5ccb, 3 ], -  [ "BIT 3, [HL]", 0x5ecb, 3 ], -  [ "BIT 3, L", 0x5dcb, 3 ], -  [ "BIT 4, A", 0x67cb, 3 ], -  [ "BIT 4, B", 0x60cb, 3 ], -  [ "BIT 4, C", 0x61cb, 3 ], -  [ "BIT 4, D", 0x62cb, 3 ], -  [ "BIT 4, E", 0x63cb, 3 ], -  [ "BIT 4, H", 0x64cb, 3 ], -  [ "BIT 4, [HL]", 0x66cb, 3 ], -  [ "BIT 4, L", 0x65cb, 3 ], -  [ "BIT 5, A", 0x6fcb, 3 ], -  [ "BIT 5, B", 0x68cb, 3 ], -  [ "BIT 5, C", 0x69cb, 3 ], -  [ "BIT 5, D", 0x6acb, 3 ], -  [ "BIT 5, E", 0x6bcb, 3 ], -  [ "BIT 5, H", 0x6ccb, 3 ], -  [ "BIT 5, [HL]", 0x6ecb, 3 ], -  [ "BIT 5, L", 0x6dcb, 3 ], -  [ "BIT 6, A", 0x77cb, 3 ], -  [ "BIT 6, B", 0x70cb, 3 ], -  [ "BIT 6, C", 0x71cb, 3 ], -  [ "BIT 6, D", 0x72cb, 3 ], -  [ "BIT 6, E", 0x73cb, 3 ], -  [ "BIT 6, H", 0x74cb, 3 ], -  [ "BIT 6, [HL]", 0x76cb, 3 ], -  [ "BIT 6, L", 0x75cb, 3 ], -  [ "BIT 7, A", 0x7fcb, 3 ], -  [ "BIT 7, B", 0x78cb, 3 ], -  [ "BIT 7, C", 0x79cb, 3 ], -  [ "BIT 7, D", 0x7acb, 3 ], -  [ "BIT 7, E", 0x7bcb, 3 ], -  [ "BIT 7, H", 0x7ccb, 3 ], -  [ "BIT 7, [HL]", 0x7ecb, 3 ], -  [ "BIT 7, L", 0x7dcb, 3 ], -  [ "CALL C, ?", 0xdc, 2 ], -  [ "CALL NC, ?", 0xd4, 2 ], -  [ "CALL NZ, ?", 0xc4, 2 ], -  [ "CALL Z, ?", 0xcc, 2 ], -  [ "CALL ?", 0xcd, 2 ], -  [ "CCF", 0x3f, 0 ], -  [ "CP A", 0xbf, 0 ], -  [ "CP B", 0xb8, 0 ], -  [ "CP C", 0xb9, 0 ], -  [ "CP D", 0xba, 0 ], -  [ "CP E", 0xbb, 0 ], -  [ "CP H", 0xbc, 0 ], -  [ "CP [HL]", 0xbe, 0 ], -  [ "CPL", 0x2f, 0 ], -  [ "CP L", 0xbd, 0 ], -  [ "CP x", 0xfe, 1 ], -  [ "DAA", 0x27, 0 ], -  [ "DEBUG", 0xed, 0 ], -  [ "DEC A", 0x3d, 0 ], -  [ "DEC B", 0x5, 0 ], -  [ "DEC BC", 0xb, 0 ], -  [ "DEC C", 0xd, 0 ], -  [ "DEC D", 0x15, 0 ], -  [ "DEC DE", 0x1b, 0 ], -  [ "DEC E", 0x1d, 0 ], -  [ "DEC H", 0x25, 0 ], -  [ "DEC HL", 0x2b, 0 ], -  [ "DEC [HL]", 0x35, 0 ], -  [ "DEC L", 0x2d, 0 ], -  [ "DEC SP", 0x3b, 0 ], -  [ "DI", 0xf3, 0 ], -  [ "EI", 0xfb, 0 ], -  [ "HALT", 0x76, 0 ], -  [ "INC A", 0x3c, 0 ], -  [ "INC B", 0x4, 0 ], -  [ "INC BC", 0x3, 0 ], -  [ "INC C", 0xc, 0 ], -  [ "INC D", 0x14, 0 ], -  [ "INC DE", 0x13, 0 ], -  [ "INC E", 0x1c, 0 ], -  [ "INC H", 0x24, 0 ], -  [ "INC HL", 0x23, 0 ], -  [ "INC [HL]", 0x34, 0 ], -  [ "INC L", 0x2c, 0 ], -  [ "INC SP", 0x33, 0 ], -  [ "JP C, ?", 0xda, 2 ], -  [ "JP HL", 0xe9, 0 ], -  [ "JP NC, ?", 0xd2, 2 ], -  [ "JP NZ, ?", 0xc2, 2 ], -  [ "JP Z, ?", 0xca, 2 ], -  [ "JP ?", 0xc3, 2 ], -  [ "JR C, x", 0x38, 1 ], -  [ "JR NC, x", 0x30, 1 ], -  [ "JR NZ, x", 0x20, 1 ], -  [ "JR Z, x", 0x28, 1 ], -  [ "JR x", 0x18, 1 ], -  [ "LD A, A", 0x7f, 0 ], -  [ "LD A, B", 0x78, 0 ], -  [ "LD A, C", 0x79, 0 ], -  [ "LD A, D", 0x7a, 0 ], -  [ "LD A, E", 0x7b, 0 ], -  [ "LD A, H", 0x7c, 0 ], -  [ "LD A, L", 0x7d, 0 ], -  [ "LD A, [$FF00+C]", 0xf2, 0 ], -  [ "LD A, [$FF00+x]", 0xf0, 1 ], -#  [ "LDH A, [x]", 0xf0, 1 ], #rgbds has trouble with this one? -  [ "LD A, [BC]", 0xa, 0 ], -  [ "LD A, [DE]", 0x1a, 0 ], -#  [ "LD A, [HL+]", 0x2a, 0 ], -#  [ "LD A, [HL-]", 0x3a, 0 ], -  [ "LD A, [HL]", 0x7e, 0 ], -  [ "LD A, [HLD]", 0x3a, 0 ], -  [ "LD A, [HLI]", 0x2a, 0 ], -  [ "LD A, [?]", 0xfa, 2 ], -  [ "LD A, x", 0x3e, 1 ], -  [ "LD B, A", 0x47, 0 ], -  [ "LD B, B", 0x40, 0 ], -  [ "LD B, C", 0x41, 0 ], -  [ "LD [BC], A", 0x2, 0 ], -  [ "LD B, D", 0x42, 0 ], -  [ "LD B, E", 0x43, 0 ], -  [ "LD B, H", 0x44, 0 ], -  [ "LD B, [HL]", 0x46, 0 ], -  [ "LD B, L", 0x45, 0 ], -  [ "LD B, x", 0x6, 1 ], -  [ "LD C, A", 0x4f, 0 ], -  [ "LD C, B", 0x48, 0 ], -  [ "LD C, C", 0x49, 0 ], -  [ "LD C, D", 0x4a, 0 ], -  [ "LD C, E", 0x4b, 0 ], -  [ "LD C, H", 0x4c, 0 ], -  [ "LD C, [HL]", 0x4e, 0 ], -  [ "LD C, L", 0x4d, 0 ], -  [ "LD C, x", 0xe, 1 ], -  [ "LD D, A", 0x57, 0 ], -#  [ "LDD A, [HL]", 0x3a, 0 ], -  [ "LD D, B", 0x50, 0 ], -  [ "LD D, C", 0x51, 0 ], -  [ "LD D, D", 0x52, 0 ], -  [ "LD D, E", 0x53, 0 ], -  [ "LD [DE], A", 0x12, 0 ], -  [ "LD D, H", 0x54, 0 ], -  [ "LD D, [HL]", 0x56, 0 ], -#  [ "LDD [HL], A", 0x32, 0 ], -  [ "LD D, L", 0x55, 0 ], -  [ "LD D, x", 0x16, 1 ], -  [ "LD E, A", 0x5f, 0 ], -  [ "LD E, B", 0x58, 0 ], -  [ "LD E, C", 0x59, 0 ], -  [ "LD E, D", 0x5a, 0 ], -  [ "LD E, E", 0x5b, 0 ], -  [ "LD E, H", 0x5c, 0 ], -  [ "LD E, [HL]", 0x5e, 0 ], -  [ "LD E, L", 0x5d, 0 ], -  [ "LD E, x", 0x1e, 1 ], -  [ "LD [$FF00+C], A", 0xe2, 0 ], -  [ "LD [$FF00+x], A", 0xe0, 1 ], -#  [ "LDH [x], A", 0xe0, 1 ], -  [ "LD H, A", 0x67, 0 ], -  [ "LD H, B", 0x60, 0 ], -  [ "LD H, C", 0x61, 0 ], -  [ "LD H, D", 0x62, 0 ], -  [ "LD H, E", 0x63, 0 ], -  [ "LD H, H", 0x64, 0 ], -  [ "LD H, [HL]", 0x66, 0 ], -  [ "LD H, L", 0x65, 0 ], -#  [ "LD [HL+], A", 0x22, 0 ], -#  [ "LD [HL-], A", 0x32, 0 ], -  [ "LD [HL], A", 0x77, 0 ], -  [ "LD [HL], B", 0x70, 0 ], -  [ "LD [HL], C", 0x71, 0 ], -  [ "LD [HL], D", 0x72, 0 ], -  [ "LD [HLD], A", 0x32, 0 ], -  [ "LD [HL], E", 0x73, 0 ], -  [ "LD [HL], H", 0x74, 0 ], -  [ "LD [HLI], A", 0x22, 0 ], -  [ "LD [HL], L", 0x75, 0 ], -  [ "LD HL, SP+x", 0xf8, 1 ], -  [ "LD [HL], x", 0x36, 1 ], -  [ "LD H, x", 0x26, 1 ], -#  [ "LDI A, [HL]", 0x2a, 0 ], -#  [ "LDI [HL], A", 0x22, 0 ], -  [ "LD L, A", 0x6f, 0 ], -  [ "LD L, B", 0x68, 0 ], -  [ "LD L, C", 0x69, 0 ], -  [ "LD L, D", 0x6a, 0 ], -  [ "LD L, E", 0x6b, 0 ], -  [ "LD L, H", 0x6c, 0 ], -  [ "LD L, [HL]", 0x6e, 0 ], -  [ "LD L, L", 0x6d, 0 ], -  [ "LD L, x", 0x2e, 1 ], -#  [ "LD PC, HL", 0xe9, 0 ], #prefer jp [hl] -  [ "LD SP, HL", 0xf9, 0 ], -  [ "LD BC, ?", 0x1, 2 ], -  [ "LD DE, ?", 0x11, 2 ], -  [ "LD HL, ?", 0x21, 2 ], -  [ "LD SP, ?", 0x31, 2 ], -#  [ "LD [?], SP", 0x8, 2 ], -  [ "LD [?], A", 0xea, 2 ], -  [ "NOP", 0x0, 0 ], -  [ "OR A", 0xb7, 0 ], -  [ "OR B", 0xb0, 0 ], -  [ "OR C", 0xb1, 0 ], -  [ "OR D", 0xb2, 0 ], -  [ "OR E", 0xb3, 0 ], -  [ "OR H", 0xb4, 0 ], -  [ "OR [HL]", 0xb6, 0 ], -  [ "OR L", 0xb5, 0 ], -  [ "OR x", 0xf6, 1 ], -  [ "POP AF", 0xf1, 0 ], -  [ "POP BC", 0xc1, 0 ], -  [ "POP DE", 0xd1, 0 ], -  [ "POP HL", 0xe1, 0 ], -  [ "PUSH AF", 0xf5, 0 ], -  [ "PUSH BC", 0xc5, 0 ], -  [ "PUSH DE", 0xd5, 0 ], -  [ "PUSH HL", 0xe5, 0 ], -  [ "RES 0, A", 0x87cb, 3 ], -  [ "RES 0, B", 0x80cb, 3 ], -  [ "RES 0, C", 0x81cb, 3 ], -  [ "RES 0, D", 0x82cb, 3 ], -  [ "RES 0, E", 0x83cb, 3 ], -  [ "RES 0, H", 0x84cb, 3 ], -  [ "RES 0, [HL]", 0x86cb, 3 ], -  [ "RES 0, L", 0x85cb, 3 ], -  [ "RES 1, A", 0x8fcb, 3 ], -  [ "RES 1, B", 0x88cb, 3 ], -  [ "RES 1, C", 0x89cb, 3 ], -  [ "RES 1, D", 0x8acb, 3 ], -  [ "RES 1, E", 0x8bcb, 3 ], -  [ "RES 1, H", 0x8ccb, 3 ], -  [ "RES 1, [HL]", 0x8ecb, 3 ], -  [ "RES 1, L", 0x8dcb, 3 ], -  [ "RES 2, A", 0x97cb, 3 ], -  [ "RES 2, B", 0x90cb, 3 ], -  [ "RES 2, C", 0x91cb, 3 ], -  [ "RES 2, D", 0x92cb, 3 ], -  [ "RES 2, E", 0x93cb, 3 ], -  [ "RES 2, H", 0x94cb, 3 ], -  [ "RES 2, [HL]", 0x96cb, 3 ], -  [ "RES 2, L", 0x95cb, 3 ], -  [ "RES 3, A", 0x9fcb, 3 ], -  [ "RES 3, B", 0x98cb, 3 ], -  [ "RES 3, C", 0x99cb, 3 ], -  [ "RES 3, D", 0x9acb, 3 ], -  [ "RES 3, E", 0x9bcb, 3 ], -  [ "RES 3, H", 0x9ccb, 3 ], -  [ "RES 3, [HL]", 0x9ecb, 3 ], -  [ "RES 3, L", 0x9dcb, 3 ], -  [ "RES 4, A", 0xa7cb, 3 ], -  [ "RES 4, B", 0xa0cb, 3 ], -  [ "RES 4, C", 0xa1cb, 3 ], -  [ "RES 4, D", 0xa2cb, 3 ], -  [ "RES 4, E", 0xa3cb, 3 ], -  [ "RES 4, H", 0xa4cb, 3 ], -  [ "RES 4, [HL]", 0xa6cb, 3 ], -  [ "RES 4, L", 0xa5cb, 3 ], -  [ "RES 5, A", 0xafcb, 3 ], -  [ "RES 5, B", 0xa8cb, 3 ], -  [ "RES 5, C", 0xa9cb, 3 ], -  [ "RES 5, D", 0xaacb, 3 ], -  [ "RES 5, E", 0xabcb, 3 ], -  [ "RES 5, H", 0xaccb, 3 ], -  [ "RES 5, [HL]", 0xaecb, 3 ], -  [ "RES 5, L", 0xadcb, 3 ], -  [ "RES 6, A", 0xb7cb, 3 ], -  [ "RES 6, B", 0xb0cb, 3 ], -  [ "RES 6, C", 0xb1cb, 3 ], -  [ "RES 6, D", 0xb2cb, 3 ], -  [ "RES 6, E", 0xb3cb, 3 ], -  [ "RES 6, H", 0xb4cb, 3 ], -  [ "RES 6, [HL]", 0xb6cb, 3 ], -  [ "RES 6, L", 0xb5cb, 3 ], -  [ "RES 7, A", 0xbfcb, 3 ], -  [ "RES 7, B", 0xb8cb, 3 ], -  [ "RES 7, C", 0xb9cb, 3 ], -  [ "RES 7, D", 0xbacb, 3 ], -  [ "RES 7, E", 0xbbcb, 3 ], -  [ "RES 7, H", 0xbccb, 3 ], -  [ "RES 7, [HL]", 0xbecb, 3 ], -  [ "RES 7, L", 0xbdcb, 3 ], -  [ "RETI", 0xd9, 0 ], -  [ "RET C", 0xd8, 0 ], -  [ "RET NC", 0xd0, 0 ], -  [ "RET NZ", 0xc0, 0 ], -  [ "RET Z", 0xc8, 0 ], -  [ "RET", 0xc9, 0 ], -  [ "RLA", 0x17, 0 ], -  [ "RL A", 0x17cb, 3 ], -  [ "RL B", 0x10cb, 3 ], -  [ "RL C", 0x11cb, 3 ], -  [ "RLCA", 0x7, 0 ], -  [ "RLC A", 0x7cb, 3 ], -  [ "RLC B", 0xcb, 3 ], -  [ "RLC C", 0x1cb, 3 ], -  [ "RLC D", 0x2cb, 3 ], -  [ "RLC E", 0x3cb, 3 ], -  [ "RLC H", 0x4cb, 3 ], -  [ "RLC [HL]", 0x6cb, 3 ], -  [ "RLC L", 0x5cb, 3 ], -  [ "RL D", 0x12cb, 3 ], -  [ "RL E", 0x13cb, 3 ], -  [ "RL H", 0x14cb, 3 ], -  [ "RL [HL]", 0x16cb, 3 ], -  [ "RL L", 0x15cb, 3 ], -  [ "RRA", 0x1f, 0 ], -  [ "RR A", 0x1fcb, 3 ], -  [ "RR B", 0x18cb, 3 ], -  [ "RR C", 0x19cb, 3 ], -  [ "RRCA", 0xf, 0 ], -  [ "RRC A", 0xfcb, 3 ], -  [ "RRC B", 0x8cb, 3 ], -  [ "RRC C", 0x9cb, 3 ], -  [ "RRC D", 0xacb, 3 ], -  [ "RRC E", 0xbcb, 3 ], -  [ "RRC H", 0xccb, 3 ], -  [ "RRC [HL]", 0xecb, 3 ], -  [ "RRC L", 0xdcb, 3 ], -  [ "RR D", 0x1acb, 3 ], -  [ "RR E", 0x1bcb, 3 ], -  [ "RR H", 0x1ccb, 3 ], -  [ "RR [HL]", 0x1ecb, 3 ], -  [ "RR L", 0x1dcb, 3 ], -  [ "RST $0", 0xc7, 0 ], -  [ "RST $10", 0xd7, 0 ], -  [ "RST $18", 0xdf, 0 ], -  [ "RST $20", 0xe7, 0 ], -  [ "RST $28", 0xef, 0 ], -  [ "RST $30", 0xf7, 0 ], -  [ "RST $38", 0xff, 0 ], -  [ "RST $8", 0xcf, 0 ], -  [ "SBC A", 0x9f, 0 ], -  [ "SBC B", 0x98, 0 ], -  [ "SBC C", 0x99, 0 ], -  [ "SBC D", 0x9a, 0 ], -  [ "SBC E", 0x9b, 0 ], -  [ "SBC H", 0x9c, 0 ], -  [ "SBC [HL]", 0x9e, 0 ], -  [ "SBC L", 0x9d, 0 ], -  [ "SBC x", 0xde, 1 ], -  [ "SCF", 0x37, 0 ], -  [ "SET 0, A", 0xc7cb, 3 ], -  [ "SET 0, B", 0xc0cb, 3 ], -  [ "SET 0, C", 0xc1cb, 3 ], -  [ "SET 0, D", 0xc2cb, 3 ], -  [ "SET 0, E", 0xc3cb, 3 ], -  [ "SET 0, H", 0xc4cb, 3 ], -  [ "SET 0, [HL]", 0xc6cb, 3 ], -  [ "SET 0, L", 0xc5cb, 3 ], -  [ "SET 1, A", 0xcfcb, 3 ], -  [ "SET 1, B", 0xc8cb, 3 ], -  [ "SET 1, C", 0xc9cb, 3 ], -  [ "SET 1, D", 0xcacb, 3 ], -  [ "SET 1, E", 0xcbcb, 3 ], -  [ "SET 1, H", 0xcccb, 3 ], -  [ "SET 1, [HL]", 0xcecb, 3 ], -  [ "SET 1, L", 0xcdcb, 3 ], -  [ "SET 2, A", 0xd7cb, 3 ], -  [ "SET 2, B", 0xd0cb, 3 ], -  [ "SET 2, C", 0xd1cb, 3 ], -  [ "SET 2, D", 0xd2cb, 3 ], -  [ "SET 2, E", 0xd3cb, 3 ], -  [ "SET 2, H", 0xd4cb, 3 ], -  [ "SET 2, [HL]", 0xd6cb, 3 ], -  [ "SET 2, L", 0xd5cb, 3 ], -  [ "SET 3, A", 0xdfcb, 3 ], -  [ "SET 3, B", 0xd8cb, 3 ], -  [ "SET 3, C", 0xd9cb, 3 ], -  [ "SET 3, D", 0xdacb, 3 ], -  [ "SET 3, E", 0xdbcb, 3 ], -  [ "SET 3, H", 0xdccb, 3 ], -  [ "SET 3, [HL]", 0xdecb, 3 ], -  [ "SET 3, L", 0xddcb, 3 ], -  [ "SET 4, A", 0xe7cb, 3 ], -  [ "SET 4, B", 0xe0cb, 3 ], -  [ "SET 4, C", 0xe1cb, 3 ], -  [ "SET 4, D", 0xe2cb, 3 ], -  [ "SET 4, E", 0xe3cb, 3 ], -  [ "SET 4, H", 0xe4cb, 3 ], -  [ "SET 4, [HL]", 0xe6cb, 3 ], -  [ "SET 4, L", 0xe5cb, 3 ], -  [ "SET 5, A", 0xefcb, 3 ], -  [ "SET 5, B", 0xe8cb, 3 ], -  [ "SET 5, C", 0xe9cb, 3 ], -  [ "SET 5, D", 0xeacb, 3 ], -  [ "SET 5, E", 0xebcb, 3 ], -  [ "SET 5, H", 0xeccb, 3 ], -  [ "SET 5, [HL]", 0xeecb, 3 ], -  [ "SET 5, L", 0xedcb, 3 ], -  [ "SET 6, A", 0xf7cb, 3 ], -  [ "SET 6, B", 0xf0cb, 3 ], -  [ "SET 6, C", 0xf1cb, 3 ], -  [ "SET 6, D", 0xf2cb, 3 ], -  [ "SET 6, E", 0xf3cb, 3 ], -  [ "SET 6, H", 0xf4cb, 3 ], -  [ "SET 6, [HL]", 0xf6cb, 3 ], -  [ "SET 6, L", 0xf5cb, 3 ], -  [ "SET 7, A", 0xffcb, 3 ], -  [ "SET 7, B", 0xf8cb, 3 ], -  [ "SET 7, C", 0xf9cb, 3 ], -  [ "SET 7, D", 0xfacb, 3 ], -  [ "SET 7, E", 0xfbcb, 3 ], -  [ "SET 7, H", 0xfccb, 3 ], -  [ "SET 7, [HL]", 0xfecb, 3 ], -  [ "SET 7, L", 0xfdcb, 3 ], -  [ "SLA A", 0x27cb, 3 ], -  [ "SLA B", 0x20cb, 3 ], -  [ "SLA C", 0x21cb, 3 ], -  [ "SLA D", 0x22cb, 3 ], -  [ "SLA E", 0x23cb, 3 ], -  [ "SLA H", 0x24cb, 3 ], -  [ "SLA [HL]", 0x26cb, 3 ], -  [ "SLA L", 0x25cb, 3 ], -  [ "SRA A", 0x2fcb, 3 ], -  [ "SRA B", 0x28cb, 3 ], -  [ "SRA C", 0x29cb, 3 ], -  [ "SRA D", 0x2acb, 3 ], -  [ "SRA E", 0x2bcb, 3 ], -  [ "SRA H", 0x2ccb, 3 ], -  [ "SRA [HL]", 0x2ecb, 3 ], -  [ "SRA L", 0x2dcb, 3 ], -  [ "SRL A", 0x3fcb, 3 ], -  [ "SRL B", 0x38cb, 3 ], -  [ "SRL C", 0x39cb, 3 ], -  [ "SRL D", 0x3acb, 3 ], -  [ "SRL E", 0x3bcb, 3 ], -  [ "SRL H", 0x3ccb, 3 ], -  [ "SRL [HL]", 0x3ecb, 3 ], -  [ "SRL L", 0x3dcb, 3 ], -  [ "STOP", 0x10, 0 ], -  [ "SUB A", 0x97, 0 ], -  [ "SUB B", 0x90, 0 ], -  [ "SUB C", 0x91, 0 ], -  [ "SUB D", 0x92, 0 ], -  [ "SUB E", 0x93, 0 ], -  [ "SUB H", 0x94, 0 ], -  [ "SUB [HL]", 0x96, 0 ], -  [ "SUB L", 0x95, 0 ], -  [ "SUB x", 0xd6, 1 ], -  [ "SWAP A", 0x37cb, 3 ], -  [ "SWAP B", 0x30cb, 3 ], -  [ "SWAP C", 0x31cb, 3 ], -  [ "SWAP D", 0x32cb, 3 ], -  [ "SWAP E", 0x33cb, 3 ], -  [ "SWAP H", 0x34cb, 3 ], -  [ "SWAP [HL]", 0x36cb, 3 ], -  [ "SWAP L", 0x35cb, 3 ], -  [ "XOR A", 0xaf, 0 ], -  [ "XOR B", 0xa8, 0 ], -  [ "XOR C", 0xa9, 0 ], -  [ "XOR D", 0xaa, 0 ], -  [ "XOR E", 0xab, 0 ], -  [ "XOR H", 0xac, 0 ], -  [ "XOR [HL]", 0xae, 0 ], -  [ "XOR L", 0xad, 0 ], -  [ "XOR x", 0xee, 1 ], -  [ "E", 0x100, -1 ], -] - -#find conflicts -conflict_table = {} -for line in temp_opt_table: -    if line[1] in conflict_table.keys(): -        print "CONFLICT: " + line[0] + " ($" + hex(line[1])[2:] + ") .... " + conflict_table[line[1]] -    else: -        conflict_table[line[1]] = line[0] - -#construct real opt_table -opt_table = {} -for line in temp_opt_table: -    opt_table[line[1]] = [line[0], line[2]] -del temp_opt_table -del line - -end_08_scripts_with = [ -0xe9, #jp hl -#0xc3, #jp -##0x18, #jr -0xc9, #ret -###0xda, 0xe9, 0xd2, 0xc2, 0xca, 0xc3, 0x38, 0x30, 0x20, 0x28, 0x18, 0xd8, 0xd0, 0xc0, 0xc8, 0xc9 -] -relative_jumps = [0x38, 0x30, 0x20, 0x28, 0x18, 0xc3, 0xda, 0xc2]  -relative_unconditional_jumps = [0xc3, 0x18] - -#TODO: replace call and a pointer with call and a label -call_commands = [0xdc, 0xd4, 0xc4, 0xcc, 0xcd] - - -all_labels = {} - -def load_labels(filename="labels.json"): -    global all_labels -    if os.path.exists(filename): -        all_labels = json.loads(open(filename, "r").read()) -    else: -        print "You must run analyze_incbins.scan_for_predefined_labels() to create \"labels.json\". Trying..." -        import analyze_incbins -        analyze_incbins.scan_for_predefined_labels() -load_labels() - -def find_label(local_address, bank_id=0): -    global all_labels -    #keep an integer -    if type(local_address) == str: -        local_address1 = int(local_address.replace("$", "0x"), 16) -    else: local_address1 = local_address - -    #turn local_address into a string -    if type(local_address) == str: -        if "0x" in local_address: local_address = local_address.replace("0x", "$") -        elif not "$" in local_address: local_address = "$" + local_address -    if type(local_address) == int: -        local_address = "$%.x" % (local_address) -    local_address = local_address.upper() - -    for label_entry in all_labels: -        if label_entry["local_pointer"].upper() == local_address: -            if label_entry["bank_id"] == bank_id or (local_address1 < 0x8000 and (label_entry["bank_id"] == 0 or label_entry["bank_id"] == 1)): -                return label_entry["label"] -    return None - -def random_asm_label(): -    return ".ASM_" + random_hash() - -def asm_label(address): -    # why using a random value when you can use the eff. address? -    return ".ASM_" + hex(address)[2:] - -def output_bank_opcodes(original_offset, max_byte_count=0x4000): -    #fs = current_address -    #b = bank_byte -    #in = input_data  -- extract_maps.rom -    #bank_size = byte_count -    #i = offset -    #ad = end_address -    #a, oa = current_byte_number - -    bank_id = 0 -    if original_offset > 0x8000: -        bank_id = original_offset / 0x4000 -    print "bank id is: " + str(bank_id) - -    last_hl_address = None #for when we're scanning the main map script -    last_a_address = None -    used_3d97 = False - -    rom = extract_maps.rom -    offset = original_offset -    current_byte_number = 0 #start from the beginning - -    #we don't actually have an end address, but we'll just say $4000 -    end_address = original_offset + max_byte_count - -    byte_labels = {} - -    output = "" -    keep_reading = True -    while offset <= end_address and keep_reading: -        current_byte = ord(extract_maps.rom[offset]) -        is_data = False -        maybe_byte = current_byte - -        #first check if this byte already has a label -        #if it does, use the label -        #if not, generate a new label -        if offset in byte_labels.keys(): -            line_label = byte_labels[offset]["name"] -            byte_labels[offset]["usage"] += 1 -        else: -            line_label = asm_label(offset) -            byte_labels[offset] = {} -            byte_labels[offset]["name"] = line_label -            byte_labels[offset]["usage"] = 0 -        byte_labels[offset]["definition"] = True -        output += line_label.lower() + "\n" #" ; " + hex(offset) + "\n" - -        #find out if there's a two byte key like this -        temp_maybe = maybe_byte -        temp_maybe += ( ord(rom[offset+1]) << 8) -        if temp_maybe in opt_table.keys() and ord(rom[offset+1])!=0: -            opstr = opt_table[temp_maybe][0].lower() - -            if "x" in opstr: -                for x in range(0, opstr.count("x")): -                    insertion = ord(rom[offset + 1]) -                    insertion = "$" + hex(insertion)[2:] - -                    opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower() - -                    current_byte += 1 -                    offset += 1 -            if "?" in opstr: -                for y in range(0, opstr.count("?")): -                    byte1 = ord(rom[offset + 1]) -                    byte2 = ord(rom[offset + 2]) - -                    number = byte1 -                    number += byte2 << 8; - -                    insertion = "$%.4x" % (number) - -                    opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower() - -                    current_byte_number += 2 -                    offset += 2 - -            output += spacing + opstr #+ " ; " + hex(offset) -            output += "\n" - -            current_byte_number += 2 -            offset += 2 -        elif maybe_byte in opt_table.keys(): -            op_code = opt_table[maybe_byte] -            op_code_type = op_code[1] -            op_code_byte = maybe_byte - -            #type = -1 when it's the E op -            #if op_code_type != -1: -            if   op_code_type == 0 and ord(rom[offset]) == op_code_byte: -                op_str = op_code[0].lower() - -                output += spacing + op_code[0].lower() #+ " ; " + hex(offset) -                output += "\n" - -                offset += 1 -                current_byte_number += 1 -            elif op_code_type == 1 and ord(rom[offset]) == op_code_byte: -                oplen = len(op_code[0]) -                opstr = copy(op_code[0]) -                xes = op_code[0].count("x") -                include_comment = False -                for x in range(0, xes): -                    insertion = ord(rom[offset + 1]) -                    insertion = "$" + hex(insertion)[2:] - -                    if current_byte == 0x18 or current_byte==0x20 or current_byte in relative_jumps: #jr or jr nz -                        #generate a label for the byte we're jumping to -                        target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value -                        if target_address in byte_labels.keys(): -                            byte_labels[target_address]["usage"] = 1 + byte_labels[target_address]["usage"] -                            line_label2 = byte_labels[target_address]["name"] -                        else: -                            line_label2 = asm_label(target_address) -                            byte_labels[target_address] = {} -                            byte_labels[target_address]["name"] = line_label2 -                            byte_labels[target_address]["usage"] = 1 -                            byte_labels[target_address]["definition"] = False - -                        insertion = line_label2.lower() -                        include_comment = True -                    elif current_byte == 0x3e: -                        last_a_address = ord(rom[offset + 1]) - -                    opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower() -                    output += spacing + opstr -                    if include_comment: -                        output += " ; " + hex(offset) -                        if current_byte in relative_jumps: -                            output += " $" + hex(ord(rom[offset + 1]))[2:] -                    output += "\n" - -                    current_byte_number += 1 -                    offset += 1 -                    insertion = "" - -                current_byte_number += 1 -                offset += 1 -                include_comment = False -            elif op_code_type == 2 and ord(rom[offset]) == op_code_byte: -                oplen = len(op_code[0]) -                opstr = copy(op_code[0]) -                qes = op_code[0].count("?") -                for x in range(0, qes): -                    byte1 = ord(rom[offset + 1]) -                    byte2 = ord(rom[offset + 2]) - -                    number = byte1 -                    number += byte2 << 8; - -                    insertion = "$%.4x" % (number) -                    if maybe_byte in call_commands or current_byte in relative_unconditional_jumps or current_byte in relative_jumps: -                        result = find_label(insertion, bank_id) -                        if result != None: -                            insertion = result - -                    opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower() -                    output += spacing + opstr #+ " ; " + hex(offset) -                    output += "\n" - -                    current_byte_number += 2 -                    offset += 2 - -                current_byte_number += 1 -                offset += 1 - -                if current_byte == 0x21: -                    last_hl_address = byte1 + (byte2 << 8) -                if current_byte == 0xcd: -                    if number == 0x3d97: used_3d97 = True - -                #duck out if this is jp $24d7 -                if current_byte == 0xc3 or current_byte in relative_unconditional_jumps: -                    if current_byte == 0xc3: -                        if number == 0x3d97: used_3d97 = True -                    #if number == 0x24d7: #jp -                    if not has_outstanding_labels(byte_labels) or all_outstanding_labels_are_reverse(byte_labels, offset): -                        keep_reading = False -                        is_data = False -                        break -            else: -                is_data = True - -            #stop reading at a jump, relative jump or return -            if current_byte in end_08_scripts_with: -                if not has_outstanding_labels(byte_labels) and all_outstanding_labels_are_reverse(byte_labels, offset): -                    keep_reading = False -                    is_data = False #cleanup -                    break -                else: -                    is_data = False -                    keep_reading = True -            else: -                is_data = False -                keep_reading = True -        else: -#        if is_data and keep_reading: -            output += spacing + "db $" + hex(ord(rom[offset]))[2:] #+ " ; " + hex(offset) -            output += "\n" -            offset += 1 -            current_byte_number += 1 -        #else the while loop would have spit out the opcode - -        #these two are done prior -        #offset += 1 -        #current_byte_number += 1 - -    #clean up unused labels -    for label_line in byte_labels.keys(): -        address = label_line -        label_line = byte_labels[label_line] -        if label_line["usage"] == 0: -            output = output.replace((label_line["name"] + "\n").lower(), "") - -    #add the offset of the final location -    output += "; " + hex(offset) - -    return (output, offset, last_hl_address, last_a_address, used_3d97) - -def has_outstanding_labels(byte_labels): -    """ -    if a label is used once, it means it has to be called or specified later -    """ -    for label_line in byte_labels.keys(): -        real_line = byte_labels[label_line] -        if real_line["definition"] == False: return True -    return False - -def all_outstanding_labels_are_reverse(byte_labels, offset): -    for label_id in byte_labels.keys(): -        line = byte_labels[label_id] # label_id is also the address -        if line["definition"] == False: -            if not label_id < offset: return False -    return True - -def text_asm_pretty_printer(label, address_of_08, include_08=True): -    """returns (output, end_address)""" -    output = label + ": ; " + hex(address_of_08) + "\n" -    if include_08: -        output += spacing + "db $08 ; asm\n" -        results = output_bank_opcodes(address_of_08 + 1) -    else: -        results = output_bank_opcodes(address_of_08) -    output += results[0] -    end_address = results[1] - -    return (output, end_address) - -if __name__ == "__main__": -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() - -    #0x18f96 is PalletTownText1 -    #0x19B5D is BluesHouseText1 -    print output_bank_opcodes(int(sys.argv[1], 16))[0] diff --git a/extras/generate_sys.py b/extras/generate_sys.py deleted file mode 100644 index 72957038..00000000 --- a/extras/generate_sys.py +++ /dev/null @@ -1,8 +0,0 @@ -import json - -import analyze_incbins -analyze_incbins.scan_for_predefined_labels() - -with open('../pokered.sym', 'w') as sym: -    for label in json.load(open('labels.json')): -        sym.write('{0:x}:{1} {2}\n'.format(label['bank_id'], label['local_pointer'][1:], label['label'])) diff --git a/extras/insert_object_data.py b/extras/insert_object_data.py deleted file mode 100644 index e779c10b..00000000 --- a/extras/insert_object_data.py +++ /dev/null @@ -1,82 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-05 -#insert object data into pokered.asm -import extract_maps -from pretty_map_headers import map_name_cleaner, object_data_pretty_printer, make_object_label_name, make_text_label, map_constants -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 -import analyze_incbins -import os, sys -import subprocess -spacing = "	" - -def insert_object(map_id): -    map = extract_maps.map_headers[map_id] -    object = map["object_data"] -    size = extract_maps.compute_object_data_size(object) -    address = int(map["object_data_pointer"], 16) - -    line_number = find_incbin_to_replace_for(address) -    if line_number == None: -        print "skipping object data for map " + str(map["id"]) + " at " + map["object_data_pointer"] + " for " + str(size) + " bytes." -        return - -    newlines = split_incbin_line_into_three(line_number, address, size) -    object_asm = object_data_pretty_printer(map_id) - -    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] = object_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) - -    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") - -    #confirm it's working -    subprocess.check_call("cd ../; make clean; LC_CTYPE=UTF-8 make", shell=True) - -def insert_all_objects(): -    for map_id in extract_maps.map_headers.keys(): -        if map_id not in extract_maps.bad_maps: -            insert_object(map_id) - -            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() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() - -    #load incbins -    load_asm() -    isolate_incbins() -    process_incbins() - -    #insert_object(1) -    insert_all_objects() - diff --git a/extras/insert_texts.py b/extras/insert_texts.py deleted file mode 100644 index d5a80150..00000000 --- a/extras/insert_texts.py +++ /dev/null @@ -1,891 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-07, 2012-01-17, 2012-01-27 -#insert TX_FAR targets into pokered.asm -#and other insertion tasks -import extract_maps -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 -import analyze_incbins -from gbz80disasm import text_asm_pretty_printer, output_bank_opcodes, load_labels, find_label -import os, sys -import subprocess -spacing = "	" -tx_fars = None -failed_attempts = {} - -pokemons = ["BULBASAUR", "IVYSAUR", "VENUSAUR", "CHARMANDER", "CHARMELEON", "CHARIZARD", "SQUIRTLE", "WARTORTLE", "BLASTOISE", "CATERPIE", "METAPOD", "BUTTERFREE", "WEEDLE", "KAKUNA", "BEEDRILL", "PIDGEY", "PIDGEOTTO", "PIDGEOT", "RATTATA", "RATICATE", "SPEAROW", "FEAROW", "EKANS", "ARBOK", "PIKACHU", "RAICHU", "SANDSHREW", "SANDSLASH", "NIDORANF", "NIDORINA", "NIDOQUEEN", "NIDORANM", "NIDORINO", "NIDOKING", "CLEFAIRY", "CLEFABLE", "VULPIX", "NINETALES", "JIGGLYPUFF", "WIGGLYTUFF", "ZUBAT", "GOLBAT", "ODDISH", "GLOOM", "VILEPLUME", "PARAS", "PARASECT", "VENONAT", "VENOMOTH", "DIGLETT", "DUGTRIO", "MEOWTH", "PERSIAN", "PSYDUCK", "GOLDUCK", "MANKEY", "PRIMEAPE", "GROWLITHE", "ARCANINE", "POLIWAG", "POLIWHIRL", "POLIWRATH", "ABRA", "KADABRA", "ALAKAZAM", "MACHOP", "MACHOKE", "MACHAMP", "BELLSPROUT", "WEEPINBELL", "VICTREEBEL", "TENTACOOL", "TENTACRUEL", "GEODUDE", "GRAVELER", "GOLEM", "PONYTA", "RAPIDASH", "SLOWPOKE", "SLOWBRO", "MAGNEMITE", "MAGNETON", "FARFETCH_D", "DODUO", "DODRIO", "SEEL", "DEWGONG", "GRIMER", "MUK", "SHELLDER", "CLOYSTER", "GASTLY", "HAUNTER", "GENGAR", "ONIX", "DROWZEE", "HYPNO", "KRABBY", "KINGLER", "VOLTORB", "ELECTRODE", "EXEGGCUTE", "EXEGGUTOR", "CUBONE", "MAROWAK", "HITMONLEE", "HITMONCHAN", "LICKITUNG", "KOFFING", "WEEZING", "RHYHORN", "RHYDON", "CHANSEY", "TANGELA", "KANGASKHAN", "HORSEA", "SEADRA", "GOLDEEN", "SEAKING", "STARYU", "STARMIE", "MR_MIME", "SCYTHER", "JYNX", "ELECTABUZZ", "MAGMAR", "PINSIR", "TAUROS", "MAGIKARP", "GYARADOS", "LAPRAS", "DITTO", "EEVEE", "VAPOREON", "JOLTEON", "FLAREON", "PORYGON", "OMANYTE", "OMASTAR", "KABUTO", "KABUTOPS", "AERODACTYL", "SNORLAX", "ARTICUNO", "ZAPDOS", "MOLTRES", "DRATINI", "DRAGONAIR", "DRAGONITE", "MEWTWO", "MEW"] - -moves = [["POUND", 0x01], ["KARATE_CHOP", 0x02], ["DOUBLESLAP", 0x03], ["COMET_PUNCH", 0x04], ["MEGA_PUNCH", 0x05], ["PAY_DAY", 0x06], ["FIRE_PUNCH", 0x07], ["ICE_PUNCH", 0x08], ["THUNDERPUNCH", 0x09], ["SCRATCH", 0x0A], ["VICEGRIP", 0x0B], ["GUILLOTINE", 0x0C], ["RAZOR_WIND", 0x0D], ["SWORDS_DANCE", 0x0E], ["CUT", 0x0F], ["GUST", 0x10], ["WING_ATTACK", 0x11], ["WHIRLWIND", 0x12], ["FLY", 0x13], ["BIND", 0x14], ["SLAM", 0x15], ["VINE_WHIP", 0x16], ["STOMP", 0x17], ["DOUBLE_KICK", 0x18], ["MEGA_KICK", 0x19], ["JUMP_KICK", 0x1A], ["ROLLING_KICK", 0x1B], ["SAND_ATTACK", 0x1C], ["HEADBUTT", 0x1D], ["HORN_ATTACK", 0x1E], ["FURY_ATTACK", 0x1F], ["HORN_DRILL", 0x20], ["TACKLE", 0x21], ["BODY_SLAM", 0x22], ["WRAP", 0x23], ["TAKE_DOWN", 0x24], ["THRASH", 0x25], ["DOUBLE_EDGE", 0x26], ["TAIL_WHIP", 0x27], ["POISON_STING", 0x28], ["TWINEEDLE", 0x29], ["PIN_MISSILE", 0x2A], ["LEER", 0x2B], ["BITE", 0x2C], ["GROWL", 0x2D], ["ROAR", 0x2E], ["SING", 0x2F], ["SUPERSONIC", 0x30], ["SONICBOOM", 0x31], ["DISABLE", 0x32], ["ACID", 0x33], ["EMBER", 0x34], ["FLAMETHROWER", 0x35], ["MIST", 0x36], ["WATER_GUN", 0x37], ["HYDRO_PUMP", 0x38], ["SURF", 0x39], ["ICE_BEAM", 0x3A], ["BLIZZARD", 0x3B], ["PSYBEAM", 0x3C], ["BUBBLEBEAM", 0x3D], ["AURORA_BEAM", 0x3E], ["HYPER_BEAM", 0x3F], ["PECK", 0x40], ["DRILL_PECK", 0x41], ["SUBMISSION", 0x42], ["LOW_KICK", 0x43], ["COUNTER", 0x44], ["SEISMIC_TOSS", 0x45], ["STRENGTH", 0x46], ["ABSORB", 0x47], ["MEGA_DRAIN", 0x48], ["LEECH_SEED", 0x49], ["GROWTH", 0x4A], ["RAZOR_LEAF", 0x4B], ["SOLARBEAM", 0x4C], ["POISONPOWDER", 0x4D], ["STUN_SPORE", 0x4E], ["SLEEP_POWDER", 0x4F], ["PETAL_DANCE", 0x50], ["STRING_SHOT", 0x51], ["DRAGON_RAGE", 0x52], ["FIRE_SPIN", 0x53], ["THUNDERSHOCK", 0x54], ["THUNDERBOLT", 0x55], ["THUNDER_WAVE", 0x56], ["THUNDER", 0x57], ["ROCK_THROW", 0x58], ["EARTHQUAKE", 0x59], ["FISSURE", 0x5A], ["DIG", 0x5B], ["TOXIC", 0x5C], ["CONFUSION", 0x5D], ["PSYCHIC_M", 0x5E], ["HYPNOSIS", 0x5F], ["MEDITATE", 0x60], ["AGILITY", 0x61], ["QUICK_ATTACK", 0x62], ["RAGE", 0x63], ["TELEPORT", 0x64], ["NIGHT_SHADE", 0x65], ["MIMIC", 0x66], ["SCREECH", 0x67], ["DOUBLE_TEAM", 0x68], ["RECOVER", 0x69], ["HARDEN", 0x6A], ["MINIMIZE", 0x6B], ["SMOKESCREEN", 0x6C], ["CONFUSE_RAY", 0x6D], ["WITHDRAW", 0x6E], ["DEFENSE_CURL", 0x6F], ["BARRIER", 0x70], ["LIGHT_SCREEN", 0x71], ["HAZE", 0x72], ["REFLECT", 0x73], ["FOCUS_ENERGY", 0x74], ["BIDE", 0x75], ["METRONOME", 0x76], ["MIRROR_MOVE", 0x77], ["SELFDESTRUCT", 0x78], ["EGG_BOMB", 0x79], ["LICK", 0x7A], ["SMOG", 0x7B], ["SLUDGE", 0x7C], ["BONE_CLUB", 0x7D], ["FIRE_BLAST", 0x7E], ["WATERFALL", 0x7F], ["CLAMP", 0x80], ["SWIFT", 0x81], ["SKULL_BASH", 0x82], ["SPIKE_CANNON", 0x83], ["CONSTRICT", 0x84], ["AMNESIA", 0x85], ["KINESIS", 0x86], ["SOFTBOILED", 0x87], ["HI_JUMP_KICK", 0x88], ["GLARE", 0x89], ["DREAM_EATER", 0x8A], ["POISON_GAS", 0x8B], ["BARRAGE", 0x8C], ["LEECH_LIFE", 0x8D], ["LOVELY_KISS", 0x8E], ["SKY_ATTACK", 0x8F], ["TRANSFORM", 0x90], ["BUBBLE", 0x91], ["DIZZY_PUNCH", 0x92], ["SPORE", 0x93], ["FLASH", 0x94], ["PSYWAVE", 0x95], ["SPLASH", 0x96], ["ACID_ARMOR", 0x97], ["CRABHAMMER", 0x98], ["EXPLOSION", 0x99], ["FURY_SWIPES", 0x9A], ["BONEMERANG", 0x9B], ["REST", 0x9C], ["ROCK_SLIDE", 0x9D], ["HYPER_FANG", 0x9E], ["SHARPEN", 0x9F], ["CONVERSION", 0xA0], ["TRI_ATTACK", 0xA1], ["SUPER_FANG", 0xA2], ["SLASH", 0xA3], ["SUBSTITUTE", 0xA4], ["STRUGGLE", 0xA5]] - -elemental_types = [ -["NORMAL", "EQU", 0x00], -["FIGHTING", "EQU", 0x01], -["FLYING", "EQU", 0x02], -["POISON", "EQU", 0x03], -["GROUND", "EQU", 0x04], -["ROCK", "EQU", 0x05], -["BUG", "EQU", 0x07], -["GHOST", "EQU", 0x08], -["FIRE", "EQU", 0x14], -["WATER", "EQU", 0x15], -["GRASS", "EQU", 0x16], -["ELECTRIC", "EQU", 0x17], -["PSYCHIC", "EQU", 0x18], -["ICE", "EQU", 0x19], -["DRAGON", "EQU", 0x1A]] - -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: -            return tx_far_line - -def insert_tx_far(map_id, text_id, tx_far_line=None): -    "inserts a tx_far" -    global tx_fars -    if tx_far_line == None: -        tx_far_line = find_tx_far_entry(map_id, text_id) -    text_pointer = tx_far_line[2] -    start_address = tx_far_line[3] -    tx_far_object = tx_far_line[4] -    end_address = tx_far_object[1]["end_address"] + 1 #the end byte; +1 because of a bug somewhere :( - -    line_number = find_incbin_to_replace_for(start_address) -    if line_number == None: -        print "skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address) -        return - -    #also do a name check -    label = tx_far_label_maker(extract_maps.map_headers[map_id]["name"], text_id) -    if (label + ":") in "\n".join(analyze_incbins.asm): -        print "skipping tx_far for map_id=" + str(map_id) + " text_id=" + str(text_id) + " text_pointer=" + hex(text_pointer) + " tx_far_start_address=" + hex(start_address) -        return -     -    newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address) -    tx_far_asm = tx_far_pretty_printer(tx_far_line) - -    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", "$") #where does this keep coming from?? - -    #signs are dumb; cluster the labels please -    if "\"needs fulfilled!\", $55" in newlines: -        newlines = "\n" + label + ": " -        line_number += 1 -    if ("STRENGTH to move!" in newlines) or ("it the way it is." in newlines): -        newlines = "\n" + label + ": " -        line_number += 1 -    if "@\"" in newlines and not "@@\"" in newlines: -        newlines = newlines.replace("@", "@@") - -    #Char52 doesn't work yet? oh well -    newlines = newlines.replace("Char52", "$52") - -    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_tx_far_targets(): -    for tx_far in tx_fars: -        map_id = tx_far[0] -        text_id = tx_far[1] -        #if map_id <= 185: continue #i'm just trying to get it going faster - -        insert_tx_far(map_id, text_id, tx_far_line=tx_far) - -        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 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"] -    if 0x4000 <= start_address <= 0x7fff: -        start_address = extract_maps.calculate_pointer(start_address, int(map2["bank"],16)) -    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=" + str(text_id) + " because the address is taken " + hex(start_address) -        return - -    #also do a name check -    if 1 < ("\n".join(analyze_incbins.asm)).count("\n" + label + ":"): -        print "skipping text label that calls TX_FAR for map_id=" + str(map_id) + " text_id" + str(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 <= 100: 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() - -#TODO: if line_id !=0 then don't include the label? -def insert_08_asm(map_id, text_id, line_id=0): -    map2 = extract_maps.map_headers[map_id] -    base_label = map_name_cleaner(map2["name"], None)[:-2] -    label = base_label + "Text" + str(text_id) - -    start_address = all_texts[map_id][text_id][line_id]["start_address"] - -    (text_asm, end_address) = text_asm_pretty_printer(label, start_address) -    print "end address is: " + hex(end_address) - -    #find where to insert the assembly -    line_number = find_incbin_to_replace_for(start_address) -    if line_number == None: -        print "skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the address is taken" -        return - -    #also do a name check -    if 1 <= ("\n".join(analyze_incbins.asm)).count("\n" + label + ":"): -        print "skipping text label for a $08 on map_id=" + str(map_id) + " text_id=" + str(text_id) + " because the label is already taken (" + label + ":)" -        return -     -    newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address ) -     -    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] = text_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 -    result = apply_diff(diff) - -    if result == False: -        failed_attempts[len(failed_attempts.keys())] = {"map_id": map_id, "text_id": text_id} - -def find_all_08s(): -    all_08s = [] -    for map_id in all_texts: -        for text_id in all_texts[map_id].keys(): -            if 0 in all_texts[map_id][text_id].keys(): -                for line_id in all_texts[map_id][text_id].keys(): -                    if all_texts[map_id][text_id][line_id]["type"] == 0x8: -                        all_08s.append([map_id, text_id, line_id]) -    return all_08s - -def insert_all_08s(): -    all_08s = find_all_08s() -    for the_08_line in all_08s: -        map_id = the_08_line[0] -        if map_id <= 86: continue #speed things up -        text_id = the_08_line[1] -        line_id = the_08_line[2] - -        print "processing map_id=" + str(map_id) + " text_id=" + str(text_id) -        insert_08_asm(map_id, text_id, line_id) -         -        #reset everything -        analyze_incbins.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 insert_asm(start_address, label, text_asm=None, end_address=None): -    if text_asm == None and end_address == None: -        (text_asm, end_address) = text_asm_pretty_printer(label, start_address, include_08=False) -        print "end address is: " + hex(end_address) - -    #find where to insert the assembly -    line_number = find_incbin_to_replace_for(start_address) -    if line_number == None: -        print "skipping asm because the address is taken" -        return False - -    #name check -    if (label + ":") in "\n".join(analyze_incbins.asm): -        print "skipping asm because the label is taken" -        return False - -    newlines = split_incbin_line_into_three(line_number, start_address, end_address - start_address ) -     -    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] = text_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 diff -    result = apply_diff(diff, try_fixing=True) -    return True - -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 "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 -    newlines = split_incbin_line_into_three(line_number, start_address, byte_count) - -    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] = text_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", "$") #where does this keep coming from?? - -    #Char52 doesn't work yet -    newlines = newlines.replace("Char52", "$52") - -    diff = generate_diff_insert(line_number, newlines) -    print 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(): -    for map_id in extract_maps.map_headers.keys(): #skip id=0 (Pallet Town) because the naming conventions are wonky -        map2 = extract_maps.map_headers[map_id] -        if map_id in extract_maps.bad_maps or map_id in [0, 39, 37, 38]: continue #skip -        script_pointer = int(map2["script_pointer"], 16) - -        main_asm_output, offset, last_hl_address, last_a_address, used_3d97 = output_bank_opcodes(script_pointer) -        hl_pointer = "None" -         -        first_script_text = "" -        if last_hl_address != None and last_hl_address != "None" and used_3d97==True: -            if last_hl_address > 0x3fff: -                hl_pointer = extract_maps.calculate_pointer(last_hl_address, int(map2["bank"], 16)) -            else: -                hl_pointer = last_hl_address -            byte1 = ord(extract_maps.rom[hl_pointer]) -            byte2 = ord(extract_maps.rom[hl_pointer+1]) -            address = byte1 + (byte2 << 8) - -            if address > 0x3fff: -                first_script_pointer = extract_maps.calculate_pointer(address, int(map2["bank"], 16)) -            else: -                first_script_pointer = address - -            #for later output -            first_script_text = " first_script=" + hex(first_script_pointer) - -            #go ahead and insert this script pointer -            insert_asm(first_script_pointer, map_name_cleaner(map2["name"], None)[:-2] + "Script0") -             -            #reset everything -            #analyze_incbins.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() - -            a_numbers = [0] -            last_a_id = 0 -            script_pointers = [hex(first_script_pointer)] -            latest_script_pointer = first_script_pointer -            while last_a_id == (max(a_numbers)) or last_a_id==0: -                asm_output, offset, last_hl_address2, last_a_id, byte1, byte2, address = None, None, None, None, None, None, None -                asm_output, offset, last_hl_address2, last_a_id, used_3d97_2 = output_bank_opcodes(latest_script_pointer) -                 -                if last_a_id == (max(a_numbers) + 1): -                    a_numbers.append(last_a_id) -                else: -                    break -                 -                byte1 = ord(extract_maps.rom[hl_pointer + (2*last_a_id)]) -                byte2 = ord(extract_maps.rom[hl_pointer + (2*last_a_id) + 1]) -                address2 = byte1 + (byte2 << 8) -                if address2 > 0x3fff: -                    latest_script_pointer = extract_maps.calculate_pointer(address2, int(map2["bank"], 16)) -                else: -                    latest_script_pointer = address2 - -                script_pointers.append(hex(latest_script_pointer)) -                #print "latest script pointer (part 1): " + hex(address2) -                #print "latest script pointer: " + hex(latest_script_pointer) - -                #go ahead and insert the asm for this script -                result = insert_asm(latest_script_pointer, map_name_cleaner(map2["name"], None)[:-2] + "Script" + str(len(script_pointers) - 1)) -                 -                if result: -                    #reset everything -                    #analyze_incbins.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() - -            print "map_id=" + str(map_id) + " scripts are: " + str(script_pointers) -         -        if last_hl_address == None: last_hl_address = "None" -        else: last_hl_address = hex(last_hl_address) - -        if hl_pointer != None and hl_pointer != "None": hl_pointer = hex(hl_pointer) - -        print "map_id=" + str(map_id) + " " + map2["name"] + " script_pointer=" + hex(script_pointer) + " script_pointers=" + hl_pointer + first_script_text -        print main_asm_output -        print "\n\n" - -        #insert asm for the main script -        result = insert_asm(script_pointer, map_name_cleaner(map2["name"], None)[:-2] + "Script") -         -        if result: -            #reset everything -            #analyze_incbins.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() - -        #insert script pointer list asm if there's anything of value -        if hl_pointer != None and hl_pointer != "None" and used_3d97==True: -            start_address = int(hl_pointer, 16) #where to insert this list -            total_size = len(a_numbers) * 2 -             -            script_label = map_name_cleaner(map2["name"], None)[:-2] + "Script" -            scripts_label = script_label  + "s" -            script_asm = scripts_label + ": ; " + hex(start_address) + "\n" -            script_asm += spacing + "dw" - -            first = True -            for id in a_numbers: -                if first: -                    script_asm += " " -                    first = False -                else: -                    script_asm += ", " -                script_asm += script_label + str(id) -            script_asm += "\n" #extra newline? - -            result = insert_asm(start_address, scripts_label, text_asm=script_asm, end_address=start_address + total_size) -            if result: -                #reset everything -                #analyze_incbins.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() -            else: -                print "trouble inserting map script pointer list" -                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 main.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) - -def get_mon_name(id): -    return pokemons[id] - -def get_type_label(id): -    for line in elemental_types: -        if line[2] == id: return line[0] -    return None - -def get_attack_label(id): -    for move in moves: -        if move[1] == id: return move[0] -    return "0" #no move - -def get_pointer_target_at(address): -    rom = extract_maps.rom -    byte1 = ord(rom[address]) -    byte2 = ord(rom[address+1]) -    pointer = (byte1 + (byte2 << 8)) -    return pointer - -def get_frontsprite_label(id): -    return get_mon_name(id).title() + "PicFront" -def get_backsprite_label(id): -    return get_mon_name(id).title() + "PicBack" - -def base_data_pretty_printer(id): -    """returns beautified asm for this pokemon - -    uses 28 bytes - -    pokedex number, base hp, base attack, base defense, base speed, base special -    type 1 (label), type 2 (label), catch rate, base experience yield -    dimensions of frontsprite (byte) -    frontsprite label pointer -    backsprite label pointer -    attacks known at level 1 (4 bytes, 4 constants) -    growth rate (byte) -    incbin - tm/hm flags (7 bytes) -    padding (0) -    """ -    output = "" -    rom = extract_maps.rom -    base_address = 0x383de + (28 * (id)) -     -    pokedex_number = id -    mon_name = get_mon_name(id) -    base_hp = ord(rom[base_address + 1]) -    base_attack = ord(rom[base_address + 2]) -    base_defense = ord(rom[base_address + 3]) -    base_speed = ord(rom[base_address + 4]) -    base_special = ord(rom[base_address + 5]) -     -    type1_id = ord(rom[base_address + 6]) -    type2_id = ord(rom[base_address + 7]) -    type1 = get_type_label(type1_id) -    type2 = get_type_label(type2_id) - -    catch_rate = ord(rom[base_address + 8]) -    base_exp_yield = ord(rom[base_address + 9]) -    frontsprite_dimensions = ord(rom[base_address + 10]) - -    frontsprite = get_frontsprite_label(id) -    backsprite = get_backsprite_label(id) - -    #attacks known at level 0 -    attack1 = get_attack_label(ord(rom[base_address + 15])) -    attack2 = get_attack_label(ord(rom[base_address + 16])) -    attack3 = get_attack_label(ord(rom[base_address + 17])) -    attack4 = get_attack_label(ord(rom[base_address + 18])) - -    growth_rate = ord(rom[base_address + 19]) - -    incbin_start_address = base_address + 20 -    incbin_end_address = base_address + 27 - -    output = mon_name.title() + ("BaseStats: ; 0x%.x" % (base_address)) + "\n" -    output += spacing + "db DEX_" + mon_name.upper() + " ; pokedex id\n" -    output += spacing + ("db " + str(base_hp)) + " ; base hp\n" -    output += spacing + "db " + str(base_attack) + " ; base attack\n" -    output += spacing + "db " + str(base_defense) + " ; base defense\n" -    output += spacing + "db " + str(base_speed) + " ; base speed\n" -    output += spacing + "db " + str(base_special) + " ; base special\n\n" -    output += spacing + "db " + type1 + " ; species type 1\n" -    output += spacing + "db " + type2 + " ; species type 2\n\n" -    output += spacing + "db " + str(catch_rate) + " ; catch rate\n" -    output += spacing + "db " + str(base_exp_yield) + " ; base exp yield\n" -    output += spacing + ("db $%.2x" % (frontsprite_dimensions)) + " ; sprite dimensions\n\n" -    output += spacing + "dw " + frontsprite + "\n" -    output += spacing + "dw " + backsprite + "\n" -    output += spacing + "\n" + spacing + "; attacks known at lvl 0\n" -    output += spacing + "db " + attack1 + "\n" -    output += spacing + "db " + attack2 + "\n" -    output += spacing + "db " + attack3 + "\n" -    output += spacing + "db " + attack4 + "\n\n" -    output += spacing + "db " + str(growth_rate) + " ; growth rate\n" -    output += spacing + "\n" + spacing + "; learnset\n" -     -    #learnset crap -    output += spacing + "db %" + bin(ord(rom[base_address + 20]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 21]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 22]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 23]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 24]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 25]))[2:].zfill(8) + "\n" -    output += spacing + "db %" + bin(ord(rom[base_address + 26]))[2:].zfill(8) + "\n\n" - -    output += spacing + "db 0 ; padding\n" - -    return output - -def insert_base_stats(id): -    insert_asm = base_data_pretty_printer(id) - -    address = 0x383de + (28 * (id)) -    line_number = find_incbin_to_replace_for(address) -    label = get_mon_name(id).title() + "BaseStats" -    if line_number == None: -        print "skipping, already inserted at " + hex(address) -        return - -    #also do a name check -    if (label + ":") in "\n".join(analyze_incbins.asm): -        print "skipping " + label + " because it is already in use.." -        return -     -    newlines = split_incbin_line_into_three(line_number, address, 28 ) - -    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 diff -    apply_diff(diff, try_fixing=False, do_compile=False) - -def insert_all_base_stats(): -    for id in range(0, 151): -        #if id < 62: continue #skip -        insert_base_stats(id) -         -        #reset everything -        reset_incbins() -        analyze_incbins.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() - -if __name__ == "__main__": -    #load map headers and object data -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() -    load_labels() -    #print base_data_pretty_printer(0) -    load_asm() -    isolate_incbins() -    process_incbins() -    #insert_base_stats(1) -    insert_all_base_stats() - -    #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() - -    #load incbins -    #reset_incbins() - -    #scan_for_map_scripts_pointer() -    #scan_rom_for_tx_fars_and_insert() -    #insert_text(0xa586b, "_VermilionCityText14") - -    #insert _ViridianCityText10 -    #insert_tx_far(1, 10) - -    #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_labels() - -    #insert_text_label_tx_far(240, 1) -    #insert_all_text_labels() - -    #insert_08_asm(83, 1) -    #insert_all_08s() - -    #insert_asm(0x1da56, "NameRaterText1") -    #insert_text_label_tx_far(91, 1) - -    #insert_text(0x44276, "ViridianPokeCenterText4") -    #insert_texts_label(4) -    #insert_all_texts_labels() - diff --git a/extras/make_map_size_constants.py b/extras/make_map_size_constants.py deleted file mode 100644 index 4dfb1bee..00000000 --- a/extras/make_map_size_constants.py +++ /dev/null @@ -1,37 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-15 -#dump map height/width constants -import extract_maps -from pretty_map_headers import map_name_cleaner, map_constants - -def get_map_size_constants(do_sed=False): -    output = "" -    sed_lines = "" -    for map_id in extract_maps.map_headers.keys(): -        if map_id in extract_maps.bad_maps: continue #skip - -        map2 = extract_maps.map_headers[map_id] -        base_name = map_name_cleaner(map2["name"], None)[:-2] -        constant_name = map_constants[map_id] - -        height = int(map2["y"], 16) -        width  = int(map2["x"], 16) - -        output += "; " + base_name + "_h map_id=" + str(map_id) + "\n" -        output += constant_name + "_HEIGHT EQU $%.2x\n" % (height) -        output += constant_name + "_WIDTH  EQU $%.2x\n" % (width) -        output += "\n" - -        sed_lines += "sed -i 's/" + base_name + "Height/" + constant_name + "_HEIGHT" + "/g' main.asm" + "\n" -        sed_lines += "sed -i 's/" + base_name + "Width/" + constant_name + "_WIDTH" + "/g' main.asm" + "\n" - -    if do_sed: -        return sed_lines -    else: -        return output - -if __name__ == "__main__": -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() -    print get_map_size_constants(do_sed=True) diff --git a/extras/map_block_dumper.py b/extras/map_block_dumper.py deleted file mode 100644 index 1ffa1e61..00000000 --- a/extras/map_block_dumper.py +++ /dev/null @@ -1,171 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-03 -#purpose: extract .blk files from baserom.gbc -#note: use python2.7 because of subprocess in analyze_incbins -import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers -from pretty_map_headers import map_name_cleaner -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 -import analyze_incbins -import os, sys -import subprocess -spacing = "	" - -used_map_pointers = [] - -def extract_map_block_data(map_id, savefile=False): -    map = extract_maps.map_headers[map_id] -    if map["name"] == "FREEZE": return #skip this one - -    blocksdata_pointer = int(map["map_pointer"], 16) - -    y = int(map["y"], 16) -    x = int(map["x"], 16) -    size = x*y -     -    #fetch the data from the rom -    blocksdata = extract_maps.rom[blocksdata_pointer:blocksdata_pointer+size] - -    #clean up the filename and label (for pokered.asm) -    cleaned_name = map_name_cleaner(map["name"], None) -    label_text = cleaned_name.replace("_h", "Blocks") -    filename = cleaned_name.replace("_h", "").lower() -    full_filepath = "maps/" + filename + ".blk" - -    if savefile: -        print "Saving ../maps/" + filename + ".blk for map id=" + str(map_id) -        fh = open("../maps/" + filename + ".blk", "w") -        fh.write(blocksdata) -        fh.close() - -def make_labels(name): -    cleaned_name = map_name_cleaner(name, None) -    label_text = cleaned_name.replace("_h", "Blocks") -    filename = cleaned_name.replace("_h", "").lower() -    full_filepath = "maps/" + filename + ".blk" -    return cleaned_name, label_text, filename, full_filepath - -def generate_label_asm(name,size=None): -    cleaned_name, label_text, filename, full_filepath = make_labels(name) - -    output = label_text + ":" -    if size: output += " ; " + str(size) + "\n" -    else: output += "\n" -    output += spacing + "INCBIN \"" + full_filepath + "\"" - -    return output - -def insert_map_block_label(map_id): -    map = extract_maps.map_headers[map_id] -    address = int(map["map_pointer"], 16) -    y = int(map["y"], 16) -    x = int(map["x"], 16) -    size = x*y - -    print "map name: " + map["name"] -    print "map address: " + map["map_pointer"] - -    line_number = find_incbin_to_replace_for(address) -    if line_number == None: -        print "skipping map id=" + str(map_id) + " probably because it was already done." -        used_map_pointers.append(map["map_pointer"]) -        return - -    newlines = split_incbin_line_into_three(line_number, address, size) - -    label_asm = generate_label_asm(map["name"], size) - -    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] = label_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) - -    #fix a lame error from somewhere -    newlines = newlines.replace("$x", "$") - -    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") - -    #confirm it's working -    subprocess.check_call("cd ../; make clean; LC_CTYPE=UTF-8 make", shell=True) - -def get_all_map_blockdata(): -    for map in extract_maps.map_headers.keys(): -        extract_map_block_data(map) - -def insert_all_labels(): -    "this is very buggy, don't use it" -    #limit = 200 #0:150 -    for map in extract_maps.map_headers.keys(): -        mapmap = extract_maps.map_headers[map] -        if mapmap["name"] == "FREEZE": continue #skip this one -        if "Ash's" in mapmap["name"]: continue -        if "Gary's" in mapmap["name"]: continue -        if not ("cat" in mapmap["name"]) and "copy" in mapmap["name"].lower(): continue #skip this one - -        #bill's house breaks things? -        #if mapmap["name"] == "Bill's House": continue -        if mapmap["name"] == "Viridian Forest": continue -        #if mapmap["name"] == "Cerulean Mart": continue -        if mapmap["name"] == "Virdian Forest Exit": continue -        #if "copy" in mapmap["name"].lower(): continue #skip this one too.. - -        if mapmap["map_pointer"] in used_map_pointers: continue #skip for sure -     -        #reset asm -        analyze_incbins.asm = None -        analyze_incbins.incbin_lines = [] -        analyze_incbins.processed_incbins = {} - -        #reload asm each time -        load_asm() - -        #check if this label is already in there -        cleaned_name, label_text, filename, full_filepath = make_labels(mapmap["name"]) -        if label_text in "\n".join(line for line in analyze_incbins.asm): -            print "skipping (found label text in asm already)" -            used_map_pointers.append(mapmap["map_pointer"]) -            continue #skip this one - -        isolate_incbins() -        process_incbins() -         -        print "XYZ|" + mapmap["name"] -        insert_map_block_label(map) - -        used_map_pointers.append(mapmap["map_pointer"]) - -if __name__ == "__main__": -    #load map headers -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() - -    #load incbins -    load_asm() -    isolate_incbins() -    process_incbins() - -    #extract_map_block_data(2) -    #get_all_map_blockdata() - -    #insert_map_block_label(49) -    insert_all_labels() diff --git a/extras/pokered_dir.py b/extras/pokered_dir.py deleted file mode 100644 index 69137839..00000000 --- a/extras/pokered_dir.py +++ /dev/null @@ -1,4 +0,0 @@ -import os - -#main dir of repo (simply one level up than here) -pokered_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) diff --git a/extras/pretty_map_headers.py b/extras/pretty_map_headers.py deleted file mode 100644 index ef26be36..00000000 --- a/extras/pretty_map_headers.py +++ /dev/null @@ -1,755 +0,0 @@ -# -*- coding: utf-8 -*- -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-02 -#purpose: dump asm for each map header -import json -import extract_maps -import sprite_helper -import random -import string -import analyze_texts #hopefully not a dependency loop - -base = 16 -spacing = "	" -all_texts = None - -#map constants -map_constants = [ -["PALLET_TOWN", 0x00], -["VIRIDIAN_CITY", 0x01], -["PEWTER_CITY", 0x02], -["CERULEAN_CITY", 0x03], -["LAVENDER_TOWN", 0x04], -["VERMILION_CITY", 0x05], -["CELADON_CITY", 0x06], -["FUCHSIA_CITY", 0x07], -["CINNABAR_ISLAND", 0x08], -["INDIGO_PLATEAU", 0x09], -["SAFFRON_CITY", 0x0A], -["ROUTE_1", 0x0C], -["ROUTE_2", 0x0D], -["ROUTE_3", 0x0E], -["ROUTE_4", 0x0F], -["ROUTE_5", 0x10], -["ROUTE_6", 0x11], -["ROUTE_7", 0x12], -["ROUTE_8", 0x13], -["ROUTE_9", 0x14], -["ROUTE_10", 0x15], -["ROUTE_11", 0x16], -["ROUTE_12", 0x17], -["ROUTE_13", 0x18], -["ROUTE_14", 0x19], -["ROUTE_15", 0x1A], -["ROUTE_16", 0x1B], -["ROUTE_17", 0x1C], -["ROUTE_18", 0x1D], -["ROUTE_19", 0x1E], -["ROUTE_20", 0x1F], -["ROUTE_21", 0x20], -["ROUTE_22", 0x21], -["ROUTE_23", 0x22], -["ROUTE_24", 0x23], -["ROUTE_25", 0x24], -["REDS_HOUSE_1F", 0x25], -["REDS_HOUSE_2F", 0x26], -["BLUES_HOUSE", 0x27], -["OAKS_LAB", 0x28], -["VIRIDIAN_POKECENTER", 0x29], -["VIRIDIAN_MART", 0x2A], -["VIRIDIAN_SCHOOL", 0x2B], -["VIRIDIAN_HOUSE", 0x2C], -["VIRIDIAN_GYM", 0x2D], -["DIGLETTS_CAVE_EXIT", 0x2E], -["VIRIDIAN_FOREST_EXIT", 0x2F], -["ROUTE_2_HOUSE", 0x30], -["ROUTE_2_GATE", 0x31], -["VIRIDIAN_FOREST_ENTRANCE", 0x32], -["VIRIDIAN_FOREST", 0x33], -["MUSEUM_1F", 0x34], -["MUSEUM_2F", 0x35], -["PEWTER_GYM", 0x36], -["PEWTER_HOUSE_1", 0x37], -["PEWTER_MART", 0x38], -["PEWTER_HOUSE_2", 0x39], -["PEWTER_POKECENTER", 0x3A], -["MT_MOON_1", 0x3B], -["MT_MOON_2", 0x3C], -["MT_MOON_3", 0x3D], -["TRASHED_HOUSE", 0x3E], -["CERULEAN_HOUSE", 0x3F], -["CERULEAN_POKECENTER", 0x40], -["CERULEAN_GYM", 0x41], -["BIKE_SHOP", 0x42], -["CERULEAN_MART", 0x43], -["MT_MOON_POKECENTER", 0x44], -["ROUTE_5_GATE", 0x46], -["PATH_ENTRANCE_ROUTE_5", 0x47], -["DAYCAREM", 0x48], -["ROUTE_6_GATE", 0x49], -["PATH_ENTRANCE_ROUTE_6", 0x4A], -["ROUTE_7_GATE", 0x4C], -["PATH_ENTRANCE_ROUTE_7", 0x4D], -["ROUTE_8_GATE", 0x4F], -["PATH_ENTRANCE_ROUTE_8", 0x50], -["ROCK_TUNNEL_POKECENTER", 0x51], -["ROCK_TUNNEL_1", 0x52], -["POWER_PLANT", 0x53], -["ROUTE_11_GATE_1F", 0x54], -["DIGLETTS_CAVE_ENTRANCE", 0x55], -["ROUTE_11_GATE_2F", 0x56], -["ROUTE_12_GATE", 0x57], -["BILLS_HOUSE", 0x58], -["VERMILION_POKECENTER", 0x59], -["POKEMON_FAN_CLUB", 0x5A], -["VERMILION_MART", 0x5B], -["VERMILION_GYM", 0x5C], -["VERMILION_HOUSE_1", 0x5D], -["VERMILION_DOCK", 0x5E], -["SS_ANNE_1", 0x5F], -["SS_ANNE_2", 0x60], -["SS_ANNE_3", 0x61], -["SS_ANNE_4", 0x62], -["SS_ANNE_5", 0x63], -["SS_ANNE_6", 0x64], -["SS_ANNE_7", 0x65], -["SS_ANNE_8", 0x66], -["SS_ANNE_9", 0x67], -["SS_ANNE_10", 0x68], -["VICTORY_ROAD_1", 0x6C], -["LANCES_ROOM", 0x71], -["HALL_OF_FAME", 0x76], -["UNDERGROUND_PATH_NS", 0x77], -["CHAMPIONS_ROOM", 0x78], -["UNDERGROUND_PATH_WE", 0x79], -["CELADON_MART_1", 0x7A], -["CELADON_MART_2", 0x7B], -["CELADON_MART_3", 0x7C], -["CELADON_MART_4", 0x7D], -["CELADON_MART_5", 0x7E], -["CELADON_MART_6", 0x7F], -["CELADON_MANSION_1", 0x80], -["CELADON_MANSION_2", 0x81], -["CELADON_MANSION_3", 0x82], -["CELADON_MANSION_4", 0x83], -["CELADON_MANSION_5", 0x84], -["CELADON_POKECENTER", 0x85], -["CELADON_GYM", 0x86], -["GAME_CORNER", 0x87], -["CELADON_HOUSE", 0x88], -["CELADONPRIZE_ROOM", 0x89], -["CELADON_DINER", 0x8A], -["CELADON_HOUSE_2", 0x8B], -["CELADONHOTEL", 0x8C], -["LAVENDER_POKECENTER", 0x8D], -["POKEMONTOWER_1", 0x8E], -["POKEMONTOWER_2", 0x8F], -["POKEMONTOWER_3", 0x90], -["POKEMONTOWER_4", 0x91], -["POKEMONTOWER_5", 0x92], -["POKEMONTOWER_6", 0x93], -["POKEMONTOWER_7", 0x94], -["LAVENDER_HOUSE_1", 0x95], -["LAVENDER_MART", 0x96], -["LAVENDER_HOUSE_2", 0x97], -["FUCHSIA_MART", 0x98], -["FUCHSIA_HOUSE_1", 0x99], -["FUCHSIA_POKECENTER", 0x9A], -["FUCHSIA_HOUSE_2", 0x9B], -["SAFARIZONEENTRANCE", 0x9C], -["FUCHSIA_GYM", 0x9D], -["FUCHSIAMEETINGROOM", 0x9E], -["SEAFOAM_ISLANDS_2", 0x9F], -["SEAFOAM_ISLANDS_3", 0xA0], -["SEAFOAM_ISLANDS_4", 0xA1], -["SEAFOAM_ISLANDS_5", 0xA2], -["VERMILION_HOUSE_2", 0xA3], -["FUCHSIA_HOUSE_3", 0xA4], -["MANSION_1", 0xA5], -["CINNABAR_GYM", 0xA6], -["CINNABAR_LAB_1", 0xA7], -["CINNABAR_LAB_2", 0xA8], -["CINNABAR_LAB_3", 0xA9], -["CINNABAR_LAB_4", 0xAA], -["CINNABAR_POKECENTER", 0xAB], -["CINNABAR_MART", 0xAC], -["INDIGO_PLATEAU_LOBBY", 0xAE], -["COPYCATS_HOUSE_1F", 0xAF], -["COPYCATS_HOUSE_2F", 0xB0], -["FIGHTINGDOJO", 0xB1], -["SAFFRON_GYM", 0xB2], -["SAFFRON_HOUSE_1", 0xB3], -["SAFFRON_MART", 0xB4], -["SILPH_CO_1F", 0xB5], -["SAFFRON_POKECENTER", 0xB6], -["SAFFRON_HOUSE_2", 0xB7], -["ROUTE_15_GATE", 0xB8], -["ROUTE_16_GATE_1F", 0xBA], -["ROUTE_16_GATE_2F", 0xBB], -["ROUTE_16_HOUSE", 0xBC], -["ROUTE_12_HOUSE", 0xBD], -["ROUTE_18_GATE_1F", 0xBE], -["ROUTE_18_GATE_2F", 0xBF], -["SEAFOAM_ISLANDS_1", 0xC0], -["ROUTE_22_GATE", 0xC1], -["VICTORY_ROAD_2", 0xC2], -["ROUTE_12_GATE_2F", 0xC3], -["VERMILION_HOUSE_3", 0xC4], -["DIGLETTS_CAVE", 0xC5], -["VICTORY_ROAD_3", 0xC6], -["ROCKET_HIDEOUT_1", 0xC7], -["ROCKET_HIDEOUT_2", 0xC8], -["ROCKET_HIDEOUT_3", 0xC9], -["ROCKET_HIDEOUT_4", 0xCA], -["ROCKET_HIDEOUT_ELEVATOR", 0xCB], -["SILPH_CO_2F", 0xCF], -["SILPH_CO_3F", 0xD0], -["SILPH_CO_4F", 0xD1], -["SILPH_CO_5F", 0xD2], -["SILPH_CO_6F", 0xD3], -["SILPH_CO_7F", 0xD4], -["SILPH_CO_8F", 0xD5], -["MANSION_2", 0xD6], -["MANSION_3", 0xD7], -["MANSION_4", 0xD8], -["SAFARI_ZONE_EAST", 0xD9], -["SAFARI_ZONE_NORTH", 0xDA], -["SAFARI_ZONE_WEST", 0xDB], -["SAFARI_ZONE_CENTER", 0xDC], -["SAFARI_ZONE_REST_HOUSE_1", 0xDD], -["SAFARI_ZONE_SECRET_HOUSE", 0xDE], -["SAFARI_ZONE_REST_HOUSE_2", 0xDF], -["SAFARI_ZONE_REST_HOUSE_3", 0xE0], -["SAFARI_ZONE_REST_HOUSE_4", 0xE1], -["UNKNOWN_DUNGEON_2", 0xE2], -["UNKNOWN_DUNGEON_3", 0xE3], -["UNKNOWN_DUNGEON_1", 0xE4], -["NAME_RATERS_HOUSE", 0xE5], -["CERULEAN_HOUSE_3", 0xE6], -["ROCK_TUNNEL_2", 0xE8], -["SILPH_CO_9F", 0xE9], -["SILPH_CO_10F", 0xEA], -["SILPH_CO_11F", 0xEB], -["SILPH_CO_ELEVATOR", 0xEC], -["BATTLE_CENTER", 0xEF], -["TRADE_CENTER", 0xF0], -["LORELEIS_ROOM", 0xF5], -["BRUNOS_ROOM", 0xF6], -["AGATHAS_ROOM", 0xF7], -["BEACH_HOUSE", 0xF8]] - -#i prefer a different data structure -temp = {} -for constant in map_constants: -    value = constant[1] -    name = constant[0] -    temp[value] = name -map_constants = temp -del temp - -#these appear outside of quotes -constant_abbreviation_bytes = { -} - -#these appear in quotes -char_conversion = [ -(" ", 0x7F), -("A", 0x80), -("B", 0x81), -("C", 0x82), -("D", 0x83), -("E", 0x84), -("F", 0x85), -("G", 0x86), -("H", 0x87), -("I", 0x88), -("J", 0x89), -("K", 0x8A), -("L", 0x8B), -("M", 0x8C), -("N", 0x8D), -("O", 0x8E), -("P", 0x8F), -("Q", 0x90), -("R", 0x91), -("S", 0x92), -("T", 0x93), -("U", 0x94), -("V", 0x95), -("W", 0x96), -("X", 0x97), -("Y", 0x98), -("Z", 0x99), -("(", 0x9A), -(")", 0x9B), -(":", 0x9C), -(";", 0x9D), -("[", 0x9E), -("]", 0x9F), -("a", 0xA0), -("b", 0xA1), -("c", 0xA2), -("d", 0xA3), -("e", 0xA4), -("f", 0xA5), -("g", 0xA6), -("h", 0xA7), -("i", 0xA8), -("j", 0xA9), -("k", 0xAA), -("l", 0xAB), -("m", 0xAC), -("n", 0xAD), -("o", 0xAE), -("p", 0xAF), -("q", 0xB0), -("r", 0xB1), -("s", 0xB2), -("t", 0xB3), -("u", 0xB4), -("v", 0xB5), -("w", 0xB6), -("x", 0xB7), -("y", 0xB8), -("z", 0xB9), -("é", 0xBA), -("'d", 0xBB), -("'l", 0xBC), -("'s", 0xBD), -("'t", 0xBE), -("'v", 0xBF), -("'", 0xE0), -("-", 0xE3), -("'r", 0xE4), -("'m", 0xE5), -("?", 0xE6), -("!", 0xE7), -(".", 0xE8), -("♂", 0xEF), -#("¥", 0xF0), -("/", 0xF3), -(",", 0xF4), -("♀", 0xF5), -("0", 0xF6), -("1", 0xF7), -("2", 0xF8), -("3", 0xF9), -("4", 0xFA), -("5", 0xFB), -("6", 0xFC), -("7", 0xFD), -("8", 0xFE), -("9", 0xFF)] -#these appear in quotes -txt_bytes = { -    0x50: "@", -    0x54: "#", -    0x75: "…", -} -for item in char_conversion: -    txt_bytes[item[1]] = item[0] -del char_conversion - -#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 + "dw $" + 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 = map_header["tileset"][2:] -    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) (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" -     -    if len(connections) > 0: -        output += spacing + "; connections data\n\n" -        output += connection_pretty_printer(connections) -        output += spacing + "; end connection data\n\n" - -    #TODO: print out label for object_data_pointer if it's already in the file -    output += spacing + "dw $" + object_data_pointer + " ; objects\n" - -    return output - -def make_object_label_name(name): -    """make a label for the asm file -    like: PalletTownObject""" -    name = map_name_cleaner(name, None) -    return name.replace("_h", "") + "Object" - -def make_text_label(map_name, id): -    """using standard object labels -    for instance, PalletTownText3""" -    label = map_name_cleaner(map_name, None)[:-2] + "Text" + str(id) -    return label - -def object_data_pretty_printer(map_id): -    map = extract_maps.map_headers[map_id] -    output = "" - -    label_name = make_object_label_name(map["name"]) -    object_data_pointer = map["object_data_pointer"] -    object = map["object_data"] -    size = extract_maps.compute_object_data_size(object) -     -    output += label_name + ": ; " + object_data_pointer + " (size=" + str(size) + ")\n" -    output += spacing + "db $" + hex(object["maps_border_tile"])[2:] + " ; border tile\n" -    output += "\n" -    output += spacing + "db $" + hex(int(object["number_of_warps"]))[2:] + " ; warps\n" - -    #warps -    for warp_id in object["warps"]: -        warp = object["warps"][warp_id] -        y = warp["y"] -        x = warp["x"] -        warp_to_point = warp["warp_to_point"] -        warp_to_map_id = warp["warp_to_map_id"] - -        try: -            warp_to_map_constant = map_constants[warp_to_map_id] -        except Exception, exc: -            warp_to_map_constant = "$" + hex(warp_to_map_id)[2:] - -        output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(warp_to_point))[2:] + ", " + warp_to_map_constant + "\n" -     -    output += "\n" -    output += spacing + "db $" + hex(int(object["number_of_signs"]))[2:] + " ; signs\n" - -    #signs -    for sign_id in object["signs"]: -        sign = object["signs"][sign_id] -        y = sign["y"] -        x = sign["x"] -        text_id = sign["text_id"] - -        output += spacing + "db $" + hex(int(y))[2:] + ", $" + hex(int(x))[2:] + ", $" + hex(int(text_id))[2:] + " ; " + make_text_label(map["name"], text_id) + "\n" -     -    output += "\n" -    output += spacing + "db $" + hex(int(object["number_of_things"]))[2:] + " ; people\n" - -    #people -    for thing_id in object["things"]: -        thing = object["things"][thing_id] -         -        ending = "" -        if thing["type"] == "item": -            ending = ", $" + hex(int(thing["item_number"]))[2:] + " ; item\n" -        elif thing["type"] == "trainer": -            ending = ", $" + hex(int(thing["trainer_type"]))[2:] + ", $" + hex(int(thing["pokemon_set"]))[2:] + " ; trainer\n" -        else: -            ending = " ; person\n" - -        picture_number = hex(int(thing["picture_number"]))[2:] -        y = hex(int(thing["y"]) - 4)[2:] -        x = hex(int(thing["x"]) - 4)[2:] -        movement1 = hex(int(thing["movement1"]))[2:] -        movement2 = hex(int(thing["movement2"]))[2:] -        text_id = hex(int(thing["original_text_string_number"]))[2:] - -        output += spacing + "db " + sprite_helper.sprites[thing["picture_number"]] + ", $" + y + " + 4, $" + x + " + 4, $" + movement1 + ", $" + movement2 + ", $" + text_id + ending -     -    output += "\n" - -    if object["number_of_warps"] > 0: -        output += spacing + "; warp-to\n" - -        for warp_to_id in object["warp_tos"]: -            warp_to = object["warp_tos"][warp_to_id] -            map_width = map["x"] -            warp_to_y = hex(int(warp_to["y"]))[2:] -            warp_to_x = hex(int(warp_to["x"]))[2:] - -            try: -                previous_location = map_constants[object["warps"][warp_to_id]["warp_to_map_id"]] -                comment = " ; " + previous_location -            except Exception, exc: -                comment = "" - -            output += spacing + "EVENT_DISP $" + map_width[2:] + ", $" + warp_to_y + ", $" + warp_to_x + comment + "\n" -            #output += spacing + "dw $" + hex(int(warp_to["event_displacement"][1]))[2:] + hex(int(warp_to["event_displacement"][0]))[2:] + "\n" -            #output += spacing + "db $" + hex(int(warp_to["y"]))[2:] + ", $" + hex(int(warp_to["x"]))[2:] + "\n" -            #output += "\n" -     -        output += "\n" - -    while output[-1] == "\n": -        output = output[:-1] - -    output += "\n" -    return output - -def find_all_tx_fars(): -    global all_texts -    tx_fars = [] #[map_id, text_id, text_pointer, tx_far_pointer, TX_FAR] -    for map_id in all_texts: -        map2 = all_texts[map_id] -        for text_id in map2.keys(): -            text = map2[text_id] -            for command_id in text.keys(): -                command = text[command_id] -                if "TX_FAR" in command.keys(): -                    TX_FAR = command["TX_FAR"] -                    if TX_FAR[0]["type"] == 0x0: -                        tx_fars.append([map_id, text_id, analyze_texts.get_text_pointer(int(extract_maps.map_headers[map_id]["texts_pointer"], 16), text_id), command["pointer"], TX_FAR]) -    return tx_fars - -def tx_far_label_maker(map_name, text_id): -    label = "_" + map_name_cleaner(map_name, None)[:-2] + "Text" + str(text_id) -    return label - -def tx_far_pretty_printer(tx_far): -    "pretty output for a tx_far" -    map_id = tx_far[0] -    map2 = extract_maps.map_headers[map_id] -    text_id = tx_far[1] -    text_pointer = tx_far[2] -    tx_far_start_address = tx_far[3] -    text_far = tx_far[4] -    lines = text_far[0]["lines"] -    label = tx_far_label_maker(map2["name"], text_id) - -    #add the ending byte on the next line -    #lines[len(lines.keys())+1] = [text_far[1]["type"]] - -    #add the ending byte to the last line- always seems $57 -    lines[len(lines.keys())-1].append(text_far[1]["type"]) - -    output  = "\n" -    output += label + ": ; " + hex(tx_far_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" -    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() - -    #load texts -    all_texts = analyze_texts.analyze_texts() - -    #print them out -    #print_all_headers() - -    #print out only the object data for pallet town (map 0) -    #print object_data_pretty_printer(0) - -    #prepare to pretty print tx_fars -    #first you must load all_texts -    #tx_fars = find_all_tx_fars() -    #for entry in tx_fars: -    #    print tx_far_pretty_printer(entry) diff --git a/extras/pretty_text.py b/extras/pretty_text.py deleted file mode 100644 index 4933dca2..00000000 --- a/extras/pretty_text.py +++ /dev/null @@ -1,21 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-16 -from optparse import OptionParser -from analyze_texts import text_pretty_printer_at - -def main(): -    usage = "usage: %prog address label" -    parser = OptionParser(usage) -    (options, args) = parser.parse_args() -    if len(args) == 1: -        print "usage: python pretty_text.py address label" -        args.append("UnnamedText_" + (args[0].replace("0x", ""))) -    elif len(args) != 2: -        parser.error("we need both an address and a label") -    address = int(args[0], 16) -    label = args[1] - -    text_pretty_printer_at(address, label) - -if __name__ == "__main__": -    main() diff --git a/extras/pretty_trainer_headers.py b/extras/pretty_trainer_headers.py deleted file mode 100644 index 5bfc2be9..00000000 --- a/extras/pretty_trainer_headers.py +++ /dev/null @@ -1,126 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-24 -from optparse import OptionParser -from gbz80disasm import load_labels, find_label -from extract_maps import calculate_pointer -import sys -spacing = "\t" -rom = None - -def pretty_print_trainer_header(address, label=None): -    """make pretty text for a trainer header""" -    global rom -    output = "" -    bank_id = 0 -    if address > 0x4000: -        bank_id = address / 0x4000 -     -    #convert address to an integer if necessary -    if type(address) == str: -        if "$" in address: address = address.replace("$", "0x") -        address = int(address, 16) - -    #label this section of asm -    if label == None: -        output += "TrainerHeader_" + hex(address)[2:] + ": ; 0x" + hex(address)[2:] + "\n" -    else: -        output += label + ": ; 0x" + hex(address)[2:] + "\n" -     -    #flag's bit -    output += spacing + "db $" + hex(ord(rom[address]))[2:] + " ; flag's bit\n" -     -    #trainer's view range -    view_range = ord(rom[address+1]) >> 4 -    output += spacing + "db ($" + hex(view_range)[2:] + " << 4) ; trainer's view range\n" - -    #flag's byte -    pointer_byte1 = ord(rom[address+2]) -    pointer_byte2 = ord(rom[address+3]) -    partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -    partial_pointer = "$%.2x" % partial_pointer -    output += spacing + "dw " + partial_pointer + " ; flag's byte\n" - -    #TextBeforeBattle -    pointer_byte1 = ord(rom[address+4]) -    pointer_byte2 = ord(rom[address+5]) -    partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -    label = find_label(partial_pointer, bank_id) -    if label == None: -        print "label not found for (TextBeforeBattle) " + hex(calculate_pointer(partial_pointer, bank_id)) -        print "" -        label = "$" + hex(partial_pointer)[2:] -        #sys.exit(0) - -    output += spacing + "dw " + label + " ; " + hex(partial_pointer) + " TextBeforeBattle\n" - -    #TextAfterBattle -    pointer_byte1 = ord(rom[address+6]) -    pointer_byte2 = ord(rom[address+7]) -    partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -    label = find_label(partial_pointer, bank_id) -    if label == None: -        print "label not found for (TextAfterBattle) " + hex(calculate_pointer(partial_pointer, bank_id)) -        print "" -        label = "$" + hex(partial_pointer)[2:] -        #sys.exit(0) - -    output += spacing + "dw " + label + " ; " + hex(partial_pointer) + " TextAfterBattle\n" - -    #TextEndBattle -    pointer_byte1 = ord(rom[address+8]) -    pointer_byte2 = ord(rom[address+9]) -    partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -    label = find_label(partial_pointer, bank_id) -    if label == None: -        print "label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id)) -        print "" -        label = "$" + hex(partial_pointer)[2:] -        #sys.exit(0) - -    output += spacing + "dw " + label + " ; " + hex(partial_pointer) + " TextEndBattle\n" - -    #TextEndBattle -    pointer_byte1 = ord(rom[address+10]) -    pointer_byte2 = ord(rom[address+11]) -    partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -    label = find_label(partial_pointer, bank_id) -    if label == None: -        print "label not found for (TextEndBattle) " + hex(calculate_pointer(partial_pointer, bank_id)) -        print "" -        label = "$" + hex(partial_pointer)[2:] -        #sys.exit(0) - -    output += spacing + "dw " + label + " ; " + hex(partial_pointer) + " TextEndBattle\n" - -    output += "; " + hex(address+12) + "\n" - -    return output - -def all_trainer_headers_at(address): -    i = 0 -    while ord(rom[address + (i*12)]) != 0xff: -        print pretty_print_trainer_header(address + (i*12)) -        i += 1 - -def main(): -    load_labels() - -    usage = "usage: %prog address" -    parser = OptionParser(usage) -    (options, args) = parser.parse_args() -    if len(args) == 1: -        print "usage: python pretty_trainer_headers.py address label\n" -        args.append("TrainerHeader_" + (args[0].replace("0x", ""))) -    elif len(args) != 2: -        parser.error("we need both an address and a label") -    address = int(args[0], 16) -    label = args[1] - -    global rom -    rom = open("../baserom.gbc", "r").read() - -    #print pretty_print_trainer_header(address, label) -    print all_trainer_headers_at(address) - -if __name__ == "__main__": -    main() diff --git a/extras/redrle.c b/extras/redrle.c deleted file mode 100644 index e753b3a1..00000000 --- a/extras/redrle.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright © 2011 IIMarckus <iimarckus@gmail.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This program compresses or decompresses the Town Map tilemap - * from Pokémon Red, Blue, and Yellow. - */ - -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -void -usage() -{ -	fprintf(stderr, "Usage: redrle [-d] infile outfile\n"); -	exit(1); -} - -int -main(int argc, char *argv[]) -{ -	FILE *infile, *outfile; -	bool d = false; /* compress or decompress flag */ - -	if (argc < 3 || argc > 4) -		usage(); - -	if (strcmp(argv[1], "-d") == 0) { -		if (argc != 4) -			usage(); -		d = true; -	} - -	infile = fopen(argv[argc - 2], "rb"); -	if (infile == NULL) { -		fprintf(stderr, "Error opening file '%s': ", argv[argc - 2]); -		perror(NULL); -		exit(1); -	} - -	outfile = fopen(argv[argc - 1], "wb"); -	if (outfile == NULL) { -		fprintf(stderr, "Error opening file '%s': ", argv[argc - 1]); -		perror(NULL); -		exit(1); -	} - -	if (d) { /* decompress */ -		for (;;) { -			int i, count; -			int byte = fgetc(infile); -			if (byte == 0) -				break; -			count = byte & 0xF; -			byte >>= 4; - -			if (feof(infile)) { -				fprintf(stderr, "Decompress error: reached " -				    "end of file without finding terminating " -				    "null byte.\n"); -				exit(1); -			} -			for (i = 0; i < count; -			    ++i) -				fputc(byte, outfile); -		} -	} else { /* compress */ -		int byte, count = 0, lastbyte = 0; -		for (;;) { -			byte = fgetc(infile); - -			if (feof(infile)) { -				while (count > 0xF) { -					count -= 0xF; -					fputc(lastbyte << 4 | 0xF, outfile); -				} -				if (count != 0) { -					fputc(lastbyte << 4 | count, outfile); -				} -				break; -			} - -			if (byte > 0xF) { -				fprintf(stderr, "Compress error: read a byte " -				    "greater than 0xF.\n"); -				exit(1); -			} - -			if (byte == lastbyte) -				++count; -			else { -				while (count > 0xF) { -					count -= 0xF; -					fputc(lastbyte << 4 | 0xF, outfile); -				} -				if (count != 0) { -					fputc(lastbyte << 4 | count, outfile); -					count = 0; -				} - -				lastbyte = byte; -				count = 1; -			} -		} - -		fputc(0, outfile); /* Terminating 0x00 */ -	} - -	fclose(infile); -	fclose(outfile); - -	return 0; -} diff --git a/extras/replace_dimensions.py b/extras/replace_dimensions.py deleted file mode 100644 index fc089f74..00000000 --- a/extras/replace_dimensions.py +++ /dev/null @@ -1,245 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-15 -#replace dimensions with constants -import sys #for non-newline-terminated output :/ -from add_map_labels_to_map_headers import find_with_start_of_line -from pretty_map_headers import map_name_cleaner, spacing, offset_to_pointer, map_constants -from connection_helper import print_connections -from ctypes import c_int8 - -# X/Y_Movement_Of_Connection -#~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# A X movement is how many map blocks there are to the left of one of your north/south connections. -# A Y movement is how many map blocks there are above your west/east connection. - -#=============================================================================== -# #4-#5 : Current Map Position -#=============================================================================== -# -# This points to the part of the current map (further up in RAM) -# that the connection strips upperleft block is placed on the current map. -# -# ____________________ -# Connection | -# Direction  | Formula -# ___________|_______ -# -#     North: C6EB + X_Movement_of_Connection Strip -# -#     South: C6EB + (Height of Map + 3) * (Width of Map + 6) + -#                   X_Movement_of_Connection Strip -# -#      West: C6E8 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 3) -# -#      East: C6E5 + (Width of Map + 6) * (Y_Movement_of_"Connection Strip" + 4) - -asm = None -asm_lines = None -def load_asm(): -    global asm, asm_lines -    asm = open("../main.asm", "r").read() -    asm_lines = asm.split("\n") - -def get_xy_movement_of_connection_strip(map_id, connection_id): -    map1 = extract_maps.map_headers[map_id] -    connections = map1["connections"] -    connection = connections[connection_id] -    direction = connection["direction"] -    current_map_location = int(connection["current_map_tile_pointer"], 16) - -    map2 = extract_maps.map_headers[connection["map_id"]] -    map2_height = int(map2["y"], 16) -    map2_width = int(map2["x"], 16) - -    y_mov = None -    #if   direction == "WEST": -    #    y_mov = ((current_map_location - 0xC6E8) / (map2_width + 6)) - 3 -    #elif direction == "EAST": -    #    y_mov = ((current_map_location - 0xC6E5) / (map2_width + 6)) - 4 -    if direction in ["WEST", "EAST"]: -        y_mov = c_int8(connection["y"]).value / -2 - -    x_mov = None -    #if   direction == "NORTH": -    #    x_mov = current_map_location - 0xC6EB -    #elif direction == "SOUTH": -    #    x_mov = current_map_location - 0xC6EB - ((map2_height + 3) * (map2_width + 6)) -    if direction in ["NORTH", "SOUTH"]: -        x_mov = c_int8(connection["x"]).value / -2 - -    return {"y_mov": y_mov, "x_mov": x_mov} - -def find_line_starting_with(value): -    global asm_lines -    id = 0 -    for line in asm_lines: -        if len(line) < len(value): continue -        if line[:len(value)] == value: -            return asm_lines.index(line) -        id += 1 -    return False #not found - -def current_map_position_formula(map_id, connection_id): -    map1_id     = map_id -    map1        = extract_maps.map_headers[map_id] -    connections = map1["connections"] -    connection  = connections[connection_id] -    map1_height = int(map1["y"], 16) -    map1_width  = int(map1["x"], 16) -    map1_name   = map1["name"] -    map1_name   = map_name_cleaner(map1_name, None)[:-2] -     -    direction            = connection["direction"] -    current_map_location = int(connection["current_map_tile_pointer"], 16) - -    map2_id     = connection["map_id"] -    map2        = extract_maps.map_headers[map2_id] -    map2_name   = map2["name"] -    map2_name   = map_name_cleaner(map2_name, None)[:-2] -    map2_height = int(map2["y"], 16) -    map2_width  = int(map2["x"], 16) -     -    y_mov = None -    if   direction == "WEST": -        y_mov = ((current_map_location - 0xC6E8) / (map1_width + 6)) - 3 -    elif direction == "EAST": -        y_mov = ((current_map_location - 0xC6E5) / (map1_width + 6)) - 4 -     -    x_mov = None -    if   direction == "NORTH": -        x_mov = current_map_location - 0xC6EB -    elif direction == "SOUTH": -        x_mov = current_map_location - 0xC6EB - ((map1_height + 3) * (map1_width + 6)) - -    formula = "" -    if   direction == "NORTH": -        formula = "$C6EB + " + str(x_mov) -    elif direction == "SOUTH": -        formula = "$C6EB + (" + map1_name + "Height + 3) * (" + map1_name + "Width + 6) + " + str(x_mov) -    elif direction == "WEST": -        formula = "$C6E8 + (" + map1_name + "Width + 6) * (" + str(y_mov) + " + 3)" -    elif direction == "EAST": -        formula = "$C6E5 + (" + map1_name + "Width + 6) * (" + str(y_mov) + " + 4)" - -    return formula - -def replace_values(): -    global asm_lines #0-15 ok -    for map_id in [3]: #extract_maps.map_headers.keys(): -        if map_id in extract_maps.bad_maps: continue #skip -        if map_id == 12: continue #skip Route 1 - -        map1 = extract_maps.map_headers[map_id] -        label_name = map_name_cleaner(map1["name"], None) -        clean_name = label_name[:-2] - -        line_number = find_line_starting_with(label_name) -        if line_number == False: continue #skip, not found - -        #replace dimensions if necessary -        if "dimensions" in asm_lines[line_number + 2] and "$" in asm_lines[line_number + 2] and not "\t" in asm_lines[line_number+2]: -            asm_lines[line_number + 2] = spacing + "db " + clean_name + "Height, " + clean_name + "Width ; dimensions (y, x)" - -        #skip the rest of this if there are no connections -        if len(map1["connections"]) == 0: continue -        if not "; connections data" in asm_lines[line_number + 6]: continue - -        connection_offset = line_number + 8 - -        for connection_id in map1["connections"]: -            connection  = map1["connections"][connection_id] -            direction   = connection["direction"] -            map2_id     = connection["map_id"] -            map2        = extract_maps.map_headers[map2_id] -            map2_name   = map_name_cleaner(map2["name"], None)[:-2] -            map2_height = int(map2["y"], 16) -            map2_width  = int(map2["x"], 16) - -            movements   = get_xy_movement_of_connection_strip(map_id, connection_id) -            y_mov       = movements["y_mov"] -            x_mov       = movements["x_mov"] - -            #replace the first two pointers -            if "  dw " in asm_lines[connection_offset + 1]: -                formula = print_connections(map_id, in_connection_id=connection_id) -                formula2 = current_map_position_formula(map_id, connection_id) - -                temp_line = asm_lines[connection_offset + 1] -                temp_line = spacing + "dw " + formula + " ; connection strip location\n" #connection strip location -                temp_line += spacing + "dw " + formula2 + " ; current map position" #current map position - -                asm_lines[connection_offset + 1] = temp_line - -            #bigness, width -            if "bigness, width" in asm_lines[connection_offset + 2]: -                temp_line = spacing + "db " -                 -                if int(connection["bigness"],16) == map2_width: -                    temp_line += map2_name + "Width" -                elif int(connection["bigness"],16) == map2_height: -                    temp_line += map2_name + "Height" -                else: #dunno wtf to do -                    temp_line += "$" + hex(int(connection["bigness"],16))[2:] -                #if   direction in ["NORTH", "SOUTH"]: -                #    temp_line += map2_name + "Width" -                #elif direction in ["WEST", "EAST"]: -                #    temp_line += map2_name + "Height" - -                temp_line += ", " + map2_name + "Width" - -                temp_line += " ; bigness, width" -                asm_lines[connection_offset + 2] = temp_line - -            #alignments (y, x) -            if "alignments (y, x)" in asm_lines[connection_offset + 3]: -                temp_line = spacing + "db " - -                if   direction == "NORTH": -                    temp_line += "(" + map2_name + "Height * 2) - 1" -                elif direction == "SOUTH": -                    temp_line += "0" -                elif direction in ["WEST", "EAST"]: -                    #TODO: this might be y_mov/4 ?? -                    temp_line += "(" + str(y_mov) + " * -2)" - -                temp_line += ", " - -                #Relative X-Position of player after entering connected map. -                if   direction in ["NORTH", "SOUTH"]: -                    temp_line += "(" + str(x_mov) + " * -2)" -                elif direction == "WEST": -                    temp_line += "(" + map2_name + "Width * 2) - 1" -                elif direction == "EAST": -                    temp_line += "0" - -                temp_line += " ; alignments (y, x)" -                asm_lines[connection_offset + 3] = temp_line - -            #window -            if "; window" in asm_lines[connection_offset + 4]: -                temp_line = spacing + "dw " -                 -                if   direction == "NORTH": -                    temp_line += "$C6E9 + " + map2_name + "Height * (" + map2_name + "Width + 6)" -                elif direction in ["SOUTH", "EAST"]: -                    temp_line += "$C6EF + " + map2_name + "Width" -                elif direction == "WEST": -                    temp_line += "$C6EE + 2 * " + map2_name + "Width" - -                temp_line += " ; window" -                asm_lines[connection_offset + 4] = temp_line - -            #jump to the next connection -            connection_offset += 6 - -if __name__ == "__main__": -    import extract_maps -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() - -    load_asm() -    replace_values() -    sys.stdout.write("\n".join(asm_lines)) - diff --git a/extras/romvisualizer.py b/extras/romvisualizer.py deleted file mode 100644 index 516ac91d..00000000 --- a/extras/romvisualizer.py +++ /dev/null @@ -1,28 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-13 -import os - -changeset_numbers = range(1145, 1149) - -def take_snapshot_image(changeset_number): -    "turn main.asm into an image at a certain version" - -    print "reverting main.asm to r" + str(changeset_number) - -    #revert the file (it used to be common.asm) -    os.system("rm ../main.asm; rm ../common.asm; rm ../pokered.asm") -    os.system("hg revert ../main.asm -r" + str(changeset_number)) -    os.system("hg revert ../common.asm -r" + str(changeset_number)) -    os.system("hg revert ../pokered.asm -r" + str(changeset_number)) - -    print "generating the image.." - -    #draw the image -    os.system("python romviz.py") - -    #move the file -    os.system("mv test.png versions/" + str(changeset_number) + ".png") - -for changeset_number in changeset_numbers: -    take_snapshot_image(changeset_number) - diff --git a/extras/romviz.py b/extras/romviz.py deleted file mode 100644 index 3f07d65e..00000000 --- a/extras/romviz.py +++ /dev/null @@ -1,40 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-10 -#show me an image -import Image -from math import floor -import extract_maps -import analyze_incbins - -print "loading rom.." -extract_maps.load_rom() -#extract_maps.load_map_pointers() -#extract_maps.read_all_map_headers() - -print "analyzing incbins.." -analyze_incbins.load_asm() -analyze_incbins.isolate_incbins() -analyze_incbins.process_incbins() - -width = 1024 -height = 1024 - -im = Image.new("P", (width, height), 0) - -im.putpalette([ -    0, 0, 0, -    126, 30, 156, -]) - -print "drawing incbins..." -for incbin_key in analyze_incbins.processed_incbins: -    incbin = analyze_incbins.processed_incbins[incbin_key] -    start = incbin["start"] -    end = incbin["end"] - -    for pos in range(start, end+1): -        widthx = int(pos % width) -        heighty = int(floor(pos / height)) -        im.putpixel((widthx, heighty), 1) - -im.save("test.png") diff --git a/extras/sprite_helper.py b/extras/sprite_helper.py deleted file mode 100644 index ee7a5f47..00000000 --- a/extras/sprite_helper.py +++ /dev/null @@ -1,402 +0,0 @@ -import extract_maps -spacing = "\t" - -#provided by sawakita -#these were originally used for making the initial_icon_constants -#but the label names in constants.asm have since been edited -initial_icon_constants = { -0x01: ["Hiro", ""], -0x02: ["Rival", ""], -0x03: ["Oak", ""], -0x04: ["blonde boy", ""], -0x05: ["machoke/slowbro OW", "machoke slowbro"], -0x06: ["blonde(horse-tail-hair) girl", "blonde ponytail girl"], -0x07: ["black-hair boy 1", "black hair boy 1"], -0x08: ["little kid (F)", "little girl"], -0x09: ["bird", ""], -0x0A: ["fat bald man", "fat bald guy"], -0x0B: ["monk", ""], -0x0C: ["black-hair boy 2/Brock", "black hair boy 2"], -0x0D: ["girl", ""], -0x0E: ["hiker/angry man", "hiker"], -0x0F: ["foulard woman", "foulard woman"], -0x10: ["rich(black-hat) man", "gentleman"], -0x11: ["sister", ""], -0x12: ["motorbiker", "biker"], -0x13: ["sailor", ""], -0x14: ["cook", ""], -0x15: ["sun-glasses guy (bike seller)", "sunglasses guy"], -0x16: ["mr. fuji", ""], -0x17: ["giovanni", ""], -0x18: ["rocket guy", "rocket grunt"], -0x19: ["medium", ""], -0x1A: ["waiter", ""], -0x1B: ["erika", ""], -0x1C: ["mother (geisha)", "mom geisha"], -0x1D: ["brunette girl", ""], -0x1E: ["lance", ""], -0x1F: ["oak's aide/scientist", "oak scientist aide"], -0x20: ["oak's aide", "oak aide"], -0x21: ["punk", ""], -0x22: ["swimmer", ""], -0x23: ["white player", ""], -0x24: ["gym helper", ""], -0x25: ["old (wo)man", "old person"], -0x26: ["mart guy", ""], -0x27: ["fisher", ""], -0x28: ["old woman/medium?", "old medium woman"], -0x29: ["nurse", ""], -0x2A: ["cable-club woman", "cable club woman"], -0x2B: ["Mr. Masterball?", "mr masterball"], -0x2C: ["person that gives Lapras", "lapras giver"], -0x2D: ["semi-bald fat guy", "balding fat guy"], -0x2E: ["black hat white beard man ", ""], -0x2F: ["fat man", ""], -0x30: ["dojo guy", ""], -0x31: ["guard (cop?)", "guard cop"], -0x32: ["cop (guard)", "cop guard"], -0x33: ["mom", ""], -0x34: ["semi-bald man", "balding guy"], -0x35: ["young girl", ""], -0x36: ["gameboy kid", ""], -0x37: ["gameboy kid copy", ""], -0x38: ["clefairy-like", "clefairylike"], -0x39: ["Agatha", ""], -0x3A: ["Bruno", ""], -0x3B: ["Lorelei", ""], -0x3C: ["seel", ""], -0x3D: ["ball", ""], -0x3E: ["omanyte", ""], -0x3F: ["boulder", ""], -0x40: ["paper sheet", ""], -0x41: ["book/map/dex", ""], -0x42: ["clipboard", ""], -0x43: ["snorlax", ""], -0x44: ["old amber copy", ""], -0x45: ["old amber", ""], -0x46: ["lying old man unused 1", ""], -0x47: ["lying old man unused 2", ""], -0x48: ["lying old man", ""], -} - -#somewhat more recent sprite labels -sprite_constants = { -0x01: "SPRITE_RED", -0x02: "SPRITE_BLUE", -0x03: "SPRITE_OAK", -0x04: "SPRITE_BUG_CATCHER", -0x05: "SPRITE_SLOWBRO", -0x06: "SPRITE_LASS", -0x07: "SPRITE_BLACK_HAIR_BOY_1", -0x08: "SPRITE_LITTLE_GIRL", -0x09: "SPRITE_BIRD", -0x0a: "SPRITE_FAT_BALD_GUY", -0x0b: "SPRITE_GAMBLER", -0x0c: "SPRITE_BLACK_HAIR_BOY_2", -0x0d: "SPRITE_GIRL", -0x0e: "SPRITE_HIKER", -0x0f: "SPRITE_FOULARD_WOMAN", -0x10: "SPRITE_GENTLEMAN", -0x11: "SPRITE_DAISY", -0x12: "SPRITE_BIKER", -0x13: "SPRITE_SAILOR", -0x14: "SPRITE_COOK", -0x15: "SPRITE_BIKE_SHOP_GUY", -0x16: "SPRITE_MR_FUJI", -0x17: "SPRITE_GIOVANNI", -0x18: "SPRITE_ROCKET", -0x19: "SPRITE_MEDIUM", -0x1a: "SPRITE_WAITER", -0x1b: "SPRITE_ERIKA", -0x1c: "SPRITE_MOM_GEISHA", -0x1d: "SPRITE_BRUNETTE_GIRL", -0x1e: "SPRITE_LANCE", -0x1f: "SPRITE_OAK_SCIENTIST_AIDE", -0x20: "SPRITE_OAK_AIDE", -0x21: "SPRITE_ROCKER", -0x22: "SPRITE_SWIMMER", -0x23: "SPRITE_WHITE_PLAYER", -0x24: "SPRITE_GYM_HELPER", -0x25: "SPRITE_OLD_PERSON", -0x26: "SPRITE_MART_GUY", -0x27: "SPRITE_FISHER", -0x28: "SPRITE_OLD_MEDIUM_WOMAN", -0x29: "SPRITE_NURSE", -0x2a: "SPRITE_CABLE_CLUB_WOMAN", -0x2b: "SPRITE_MR_MASTERBALL", -0x2c: "SPRITE_LAPRAS_GIVER", -0x2d: "SPRITE_WARDEN", -0x2e: "SPRITE_SS_CAPTAIN", -0x2f: "SPRITE_FISHER2", -0x30: "SPRITE_BLACKBELT", -0x31: "SPRITE_GUARD", -0x32: "SPRITE_____NOT____USED____", -0x33: "SPRITE_MOM", -0x34: "SPRITE_BALDING_GUY", -0x35: "SPRITE_YOUNG_BOY", -0x36: "SPRITE_GAMEBOY_KID", -0x37: "SPRITE_GAMEBOY_KID_COPY", -0x38: "SPRITE_CLEFAIRY", -0x39: "SPRITE_AGATHA", -0x3a: "SPRITE_BRUNO", -0x3b: "SPRITE_LORELEI", -0x3c: "SPRITE_SEEL", -0x3d: "SPRITE_BALL", -0x3e: "SPRITE_OMANYTE", -0x3f: "SPRITE_BOULDER", -0x40: "SPRITE_PAPER_SHEET", -0x41: "SPRITE_BOOK_MAP_DEX", -0x42: "SPRITE_CLIPBOARD", -0x43: "SPRITE_SNORLAX", -0x44: "SPRITE_OLD_AMBER_COPY", -0x45: "SPRITE_OLD_AMBER", -0x46: "SPRITE_LYING_OLD_MAN_UNUSED_1", -0x47: "SPRITE_LYING_OLD_MAN_UNUSED_2", -0x48: "SPRITE_LYING_OLD_MAN", -} -dont_use = [0x32, 0x44, 0x46, 0x47, 0x37] -#sprites after 0x23 have only one image -#SPRITE_BIKE_SHOP_GUY only has 1 - -icons = {} -unique_icons = set() -todo_sprites = {} -sprites = {} - -def load_icons(): -    for map_id in map_headers: -        if map_id in [0x0b, 0x45, 0x4b, 0x4e, 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x72, 0x73, 0x74, 0x75, 0xad, 0xcc, 0xcd, 0xce, 0xe7, 0xed, 0xee, 0xf1, 0xf2, 0xf3, 0xf4]: continue #skip -        map = map_headers[map_id] -        for thing_id in map["object_data"]["things"]: -            thing = map["object_data"]["things"][thing_id] -            pic = thing["picture_number"] -            unique_icons.add(pic) -     -            if not icons.has_key(pic): icons[pic] = [] -             -            alerter = None -            if int(thing["y"])-4 > int(map["y"], 16)*2: alerter = True -            if int(thing["x"])-4 > int(map["x"], 16)*2: alerter = True - -            icons[pic].append((map["name"] + " (id=" + str(map["id"]) + ")", thing["y"], thing["x"], alerter)) - -def print_appearances(): -    """print appearances of each icon -    see: http://diyhpl.us/~bryan/irc/pokered/sprite_appearances.txt -    """ -    output = "" -    for icon_id in icons: -        icon = icons[icon_id] -         -        possible_name = "" -        if icon_id in initial_icon_constants.keys(): -            possible_name = " (sawakita suggests: " + initial_icon_constants[icon_id][0] + ")" -     -        output += "sprite " + hex(icon_id) + possible_name + ":\n" -        for appearance in icon: -            if appearance[3] != None: outside_alert = " !! OUTSIDE BOUNDS" -            else: outside_alert = "" -            output += spacing + ".. in " + appearance[0] + " at (" + str(appearance[1]) + ", " + str(appearance[2]) + ")" + outside_alert + "\n" -        output += "\n" -     -    print output - -def insert_todo_sprites(): -    load_icons() -    counter = 1 -    for icon in unique_icons: -        if icon not in initial_icon_constants: -            todo_sprites[icon] = counter -            initial_icon_constants[icon] = None -            counter += 1 - -def sprite_name_cleaner(badname): -    output = "SPRITE_" + badname -    output = output.replace(" ", "_") -    output = output.replace("/", "_") -    output = output.replace(".", "") - -    output = output.upper() - -    while output[-1] == "_": -        output = output[:-1] -    return output - -def sprite_namer(): -    "makes up better constant names for each sprite" -    insert_todo_sprites() - -    for sprite_id in initial_icon_constants: -        suggestions = initial_icon_constants[sprite_id] -        if suggestions == None: -            sprites[sprite_id] = "SPRITE_TODO_" + str(todo_sprites[sprite_id]) -            continue #next please - -        original = suggestions[0] -        if suggestions[1] != "": original = suggestions[1] -         -        result = sprite_name_cleaner(original) -        sprites[sprite_id] = result - -def sprite_printer(): -    """prints out a list of sprite constants to put into constants.asm -    it's deprecated- use the names from the current file instead.""" -    for key in sprites: -        line_length = len(sprites[key]) + len(" EQU $") + 2 -         -        if line_length < 40: -            extra = (40 - line_length) * " " -        else: extra = "" - -        value = hex(key)[2:] -        if len(value) == 1: value = "0" + value -         -        print sprites[key] + extra + " EQU $" + value - -def parse_sprite_sheet_pointer_table(): -    """parses the bytes making up the pointer table -    first two bytes are the pointer -    third byte is the number of bytes (1 * 4 tiles * 16 bytes each, or 3 * 4 tiles * 16 bytes per tile) -        1 = 1 pose -        3 = 3 poses, possibly 6 immediately after -        $C0 or $40 -    fourth byte is the rom bank -     -    so a quick estimation is that, if it has 3, and there's no other pointer that points to the one after the 3rd & next 3, then assume those next 3 are the 4th, 5th and 6th -    """ -    rom = extract_maps.rom -    ptable_address = 0x17b27 #5:7b27 -    ptable_pointers = [] -    ptable_sheet_data = {} - -    #load up pointers please -    for sprite_id in sprite_constants.keys(): -        pointer_offset = 0x17b27 + ((sprite_id -1) * 4) -        pointer_byte1 = ord(rom[pointer_offset]) -        pointer_byte2 = ord(rom[pointer_offset+1]) -        partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -        bank = ord(rom[pointer_offset+3]) -        pointer = extract_maps.calculate_pointer(partial_pointer, bank) -        ptable_pointers.append(pointer) - -    #72 sprite pointers, we're not using id=$32 -    for sprite_id in sprite_constants.keys(): -        sprite_name = sprite_constants[sprite_id] - -        #some basic information about this sprite first -        data_entry = {"sprite_id": sprite_id, "sprite_name": sprite_name} - -        #calculate where it is in the 0x17b27 pointer table -        pointer_offset = 0x17b27 + ((sprite_id -1) * 4) -        data_entry["sprite_ptr_table_entry_address"] = pointer_offset - -        #actual sprite pointer -        pointer_byte1 = ord(rom[pointer_offset]) -        pointer_byte2 = ord(rom[pointer_offset+1]) -        partial_pointer = (pointer_byte1 + (pointer_byte2 << 8)) -        bank = ord(rom[pointer_offset+3]) -        pointer = extract_maps.calculate_pointer(partial_pointer, bank) -        data_entry["pointer"] = pointer -        data_entry["bank"] = bank - -        byte_count = ord(rom[pointer_offset+2]) -        data_entry["byte_count"] = byte_count - -        has_more_text = "" -        data_entry["poses"] = 1 -        if byte_count == 0xc0: #has at least 3 poses -            setter1, setter2, setter3 = False, False, False -            data_entry["poses"] = 3 -            #let's check if there's possibly more -            if not ((byte_count + pointer) in ptable_pointers): #yep, probably (#4) -                data_entry["poses"] += 1 -                data_entry["byte_count"] += 64 -                setter1 = True -            if setter1 and not ((byte_count + pointer + 64) in ptable_pointers): #has another (#5) -                data_entry["poses"] += 1 -                data_entry["byte_count"] += 64 -                setter2 = True -            if setter2 and not ((byte_count + pointer + 64 + 64) in ptable_pointers): #has a #6 -                data_entry["poses"] += 1 -                data_entry["byte_count"] += 64 -                setter3 = True - -        print ("$%.2x " % (sprite_id)) + sprite_name + " has $%.2x bytes" % (byte_count) + " pointing to 0x%.x" % (pointer) + " bank is $%.2x" % (bank) + " with pose_count=" + str(data_entry["poses"]) - -        ptable_sheet_data[sprite_id] = data_entry -    return ptable_sheet_data - -def pretty_print_sheet_incbins(ptable_sheet_data): -    """make things look less awful""" -    output = "" -    used_addresses = [] - -    for sheet_id in ptable_sheet_data: -        sheet_data = ptable_sheet_data[sheet_id] -        name = sheet_data["sprite_name"].split("SPRITE_")[1].lower().title() -        clean_name = name.replace("_", "") -        address = sheet_data["pointer"] -        byte_count = sheet_data["byte_count"] - -        #if not (0x10000 <= address <= 0x12e7f): continue #skip -        #if not (0x14180 <= address <= 0x17840): continue #skip -        if address in used_addresses: continue #skip -        used_addresses.append(address) - -        output += clean_name + "Sprite: ; 0x%.x" % (address) + "\n" -        #output += spacing + "INCBIN \"baserom.gbc\",$%.x,$%.x - $%.x" % (address, address + byte_count, address) + "\n" -        output += spacing + "INCBIN \"gfx/sprites/" + name.lower() + ".2bpp\" ; was $%.x" % (address) + "\n" - -        filename = "../gfx/sprites/" + name.lower() + ".2bpp" -        #fh = open(filename, "w") -        #fh.write(extract_maps.rom[address : address + byte_count]) -        #fh.close() - -    return output - -def pretty_print_sheet_data(ptable_sheet_data): -    """make the pointer table not suck so much""" -    output = "SpriteSheetPointerTable: ; 0x17b27\n" -    used_addresses = [] - -    for sheet_id in ptable_sheet_data: -        sheet_data = ptable_sheet_data[sheet_id] -        address = sheet_data["pointer"] -        checker = False -        for x in used_addresses: -            if not checker and x[0] == address: -                checker = True -                clean_name = x[1] - -        if not checker: -            name = sheet_data["sprite_name"].split("SPRITE_")[1].lower().title() -            clean_name = name.replace("_", "") -            clean_name += "Sprite" - -        byte_count = sheet_data["byte_count"] -        if byte_count > 0x40: -            byte_count = 0xc0 - -        output += "\n\t; " + sprite_constants[sheet_data["sprite_id"]] + "\n" -        output += spacing + "dw " + clean_name + "\n" -        output += spacing + "db $%.2x ; byte count\n" % (byte_count) -        output += spacing + "db BANK(" + clean_name + ")\n" - -        used_addresses.append((address, clean_name)) - -    output += "; 0x17c47" -    return output - -if __name__ == "__main__": -    extract_maps.load_rom() -    #extract_maps.load_map_pointers() -    #extract_maps.read_all_map_headers() - -    #sprite_namer() -    #load_icons() -    #print_appearances() -    #sprite_printer() -     -    ptable_sheet_data = parse_sprite_sheet_pointer_table() -    print pretty_print_sheet_incbins(ptable_sheet_data) -    print pretty_print_sheet_data(ptable_sheet_data) diff --git a/extras/text_pointers.py b/extras/text_pointers.py deleted file mode 100644 index f0f74da7..00000000 --- a/extras/text_pointers.py +++ /dev/null @@ -1,55 +0,0 @@ -#author: Bryan Bishop <kanzure@gmail.com> -#date: 2012-01-03 -#utilities for working with text pointers -import extract_maps #rom, assert_rom, load_rom, calculate_pointer, load_map_pointers, read_all_map_headers, map_headers -from pretty_map_headers import map_name_cleaner -#import analyze_incbins #asm, offset_to_pointer, find_incbin_to_replace_for, split_incbin_line_into_three, generate_diff_insert, load_asm, isolate_incbins, process_incbins -spacing = "	" - -def test_first_text_pointer_bytes(range=20): #30 for viridian city, 34 for cerulean city, 36 for celadon, 48 for fuchsia city, 50 for safron -    """ -    does the first text pointer byte always point to (end address of text pointer list) + 1? - -    range determines how far is acceptable. -    r=15 means 30 text pointers -    """ - -    for map_id in extract_maps.map_headers: -        map = extract_maps.map_headers[map_id] -        bank = int(map["bank"],16) -        text_list_pointer = int(map["texts_pointer"], 16) - -        bad_names = ["FREEZE", "COPY: Cinnibar Mart", "COPY OF: Underground Tunnel Entrance (Route 6)", "COPY OF: Trashed House", "COPY OF: Underground Path Entrance (Route 7)"] -        if map["name"] in bad_names: continue - -        #extract the bytes making up the first text pointer -        pointer_byte1 = ord(extract_maps.rom[text_list_pointer]) -        pointer_byte2 = ord(extract_maps.rom[text_list_pointer+1]) - -        #swap the bytes -        temp = pointer_byte1 -        pointer_byte1 = pointer_byte2 -        pointer_byte2 = temp -        del temp - -        #combine these into a single pointer -        partial_pointer = (pointer_byte2 + (pointer_byte1 << 8)) - -        #get the full pointer -        first_text_pointer = extract_maps.calculate_pointer(partial_pointer, bank) - -        #if (first_text_pointer <= (text_list_pointer+range)): -        print "map " + map["name"] + " (" + str(map["id"]) + ")" -        print spacing + "text_pointer (list) = " + hex(text_list_pointer) -        print spacing + "first_text_pointer (first text) = " + hex(first_text_pointer) -        print spacing + "difference = " + str(first_text_pointer - text_list_pointer) -        #return False - -    return True - -if __name__ == "__main__": -    extract_maps.load_rom() -    extract_maps.load_map_pointers() -    extract_maps.read_all_map_headers() - -    print test_first_text_pointer_bytes() | 
