diff options
Diffstat (limited to 'extras/crystal.py')
-rw-r--r-- | extras/crystal.py | 127 |
1 files changed, 123 insertions, 4 deletions
diff --git a/extras/crystal.py b/extras/crystal.py index b7b29e721..f48d69031 100644 --- a/extras/crystal.py +++ b/extras/crystal.py @@ -2319,10 +2319,17 @@ class MainText(TextCommand): "Write text. Structure: [00][Text][0x50 (ends code)]" id = 0x0 macro_name = "do_text" + use_zero = True def parse(self): offset = self.address + # the code below assumes we're jumping past a $0 byte + if self.use_zero == False: + offset = offset + else: + offset = offset + 1 + # read until $50, $57 or $58 (not sure about $58...) jump57 = how_many_until(chr(0x57), offset) jump50 = how_many_until(chr(0x50), offset) @@ -2330,6 +2337,7 @@ class MainText(TextCommand): # pick whichever one comes first jump = min([jump57, jump50, jump58]) + jump += 1 # if $57 appears first then this command is the last in this text script if jump == jump57 or jump == jump58: @@ -2337,21 +2345,28 @@ class MainText(TextCommand): # we want the address after the $57 # ("last_address" is misnamed everywhere) - end_address = offset + 1 + jump + end_address = offset + jump self.last_address = self.end_address = end_address # read the text bytes into a structure # skip the first offset byte because that's the command byte - self.bytes = rom_interval(offset + 1, jump, strings=False) + self.bytes = rom_interval(offset , jump, strings=False) # include the original command in the size calculation - self.size = jump + 1 + self.size = jump + + # TODO: this is possibly wrong + if self.use_zero: + self.size += 1 def to_asm(self): if self.size < 2 or len(self.bytes) < 1: raise Exception, "$0 text command can't end itself with no follow-on bytes" - output = "db $0" + if self.use_zero: + output = "db $0" + else: + output = "" # db $0, $57 or db $0, $50 or w/e if self.size == 2 and len(self.bytes) == 1: @@ -2371,6 +2386,10 @@ class MainText(TextCommand): # has a $50 or $57 been passed yet? end = False + if not self.use_zero: + new_line = True + was_comma = False + for byte in self.bytes: if end: raise Exception, "the text ended due to a $50 or $57 but there are more bytes?" @@ -2503,6 +2522,9 @@ class MainText(TextCommand): return output +class PokedexText(MainText): + use_zero = False + class WriteTextFromRAM(TextCommand): """ Write text from ram. Structure: [01][Ram address (2byte)] @@ -5520,6 +5542,103 @@ def parse_all_map_headers(debug=True): old_parsed_map = old_parse_map_header_at(map_header_offset, map_group=group_id, map_id=map_id, debug=debug) map_names[group_id][map_id]["header_old"] = old_parsed_map +class PokedexEntryPointerTable: + """ A list of pointers. + """ + + def __init__(self): + self.address = 0x44378 + self.target_bank = calculate_bank(0x181695) + self.label = Label(name="PokedexDataPointerTable", address=self.address, object=self) + self.size = None + self.last_address = None + self.dependencies = None + self.entries = [] + self.parse() + + script_parse_table[self.address : self.last_address] = self + + def get_dependencies(self, recompute=False, global_dependencies=set()): + global_dependencies.update(self.entries) + dependencies = [] + [dependencies.extend(entry.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)) for entry in self.entries] + return dependencies + + def parse(self): + size = 0 + lastpointer = 0 + for i in range(251): + # Those are consecutive in GS! + if i == 0x40: + self.target_bank = 0x6e + elif i == 0x80: + self.target_bank = 0x73 + elif i == 0xc0: + self.target_bank = 0x74 + loc = self.address+(i*2) + pointer = calculate_pointer_from_bytes_at(loc, bank=self.target_bank) + #print(hex(pointer)) + #if pointer < lastpointer: + # self.target_bank += 1 + # pointer += 0x4000 + self.entries.append(PokedexEntry(pointer, i+1)) + + size += 2 + self.size = size + self.last_address = self.address + self.size + + def to_asm(self): + output = "".join([str("dw "+get_label_for(entry.address)+"\n") for entry in self.entries]) + return output + +class PokedexEntry: + """ """ + + def __init__(self, address, pokemon_id): + self.address = address + self.dependencies = None + #label = self.make_label() + if pokemon_id in pokemon_constants: + pokename = string.capwords(pokemon_constants[pokemon_id].replace("__", " ").replace("_", " ")).replace(" ", "") + else: + pokename = "Pokemon{0}".format(pokemon_id) + self.label = Label(name=pokename+"PokedexEntry", address=self.address, object=self) + self.parse() + script_parse_table[address : self.last_address] = self + + def get_dependencies(self, recompute=False, global_dependencies=set()): + return [] + + def parse(self): + # eww. + address = self.address + jump = how_many_until(chr(0x50), address) + self.species = parse_text_at(address, jump+1) + address = address + jump + 1 + + self.weight = ord(rom[address ]) + (ord(rom[address+1]) << 8) + self.height = ord(rom[address+2]) + (ord(rom[address+3]) << 8) + address += 4 + + jump = how_many_until(chr(0x50), address) + self.page1 = PokedexText(address) + address = address + jump + 1 + jump = how_many_until(chr(0x50), address) + self.page2 = PokedexText(address) + + self.last_address = address + jump + 1 + #print(self.to_asm()) + return True + + def to_asm(self): + output = """\ + db "{0}" ; species name + dw {1}, {2} ; height, weight + + {3} + {4}""".format(self.species, self.weight, self.height, self.page1.to_asm(), self.page2.to_asm()) + return output + #map names with no labels will be generated at the end of the structure map_names = { 1: { |