def test_rom_interval(self): address = 0x100 interval = 10 correct_strings = ['0x0', '0xc3', '0x6e', '0x1', '0xce', '0xed', '0x66', '0x66', '0xcc', '0xd'] byte_strings = rom_interval(address, interval, strings=True) self.assertEqual(byte_strings, correct_strings) correct_ints = [0, 195, 110, 1, 206, 237, 102, 102, 204, 13] ints = rom_interval(address, interval, strings=False) self.assertEqual(ints, correct_ints)
def old_parse_map_script_header_at(address, map_group=None, map_id=None, rom=None, debug=True): logging.debug("starting to parse the map's script header..") #[[Number1 of pointers] Number1 * [2byte pointer to script][00][00]] ptr_line_size = 4 #[2byte pointer to script][00][00] trigger_ptr_cnt = ord(rom[address]) trigger_pointers = helpers.grouper(rom_interval(address+1, trigger_ptr_cnt * ptr_line_size, rom=rom, strings=False), count=ptr_line_size) triggers = {} for index, trigger_pointer in enumerate(trigger_pointers): logging.debug("parsing a trigger header...") byte1 = trigger_pointer[0] byte2 = trigger_pointer[1] ptr = byte1 + (byte2 << 8) trigger_address = pointers.calculate_pointer(ptr, pointers.calculate_bank(address)) trigger_script = parse_script_engine_script_at(trigger_address, map_group=map_group, map_id=map_id) triggers[index] = { "script": trigger_script, "address": trigger_address, "pointer": {"1": byte1, "2": byte2}, } # bump ahead in the byte stream address += trigger_ptr_cnt * ptr_line_size + 1 #[[Number2 of pointers] Number2 * [hook number][2byte pointer to script]] callback_ptr_line_size = 3 callback_ptr_cnt = ord(rom[address]) callback_ptrs = helpers.grouper(rom_interval(address+1, callback_ptr_cnt * callback_ptr_line_size, rom=rom, strings=False), count=callback_ptr_line_size) callback_pointers = {} callbacks = {} for index, callback_line in enumerate(callback_ptrs): logging.debug("parsing a callback header..") hook_byte = callback_line[0] # 1, 2, 3, 4, 5 callback_byte1 = callback_line[1] callback_byte2 = callback_line[2] callback_ptr = callback_byte1 + (callback_byte2 << 8) callback_address = pointers.calculate_pointer(callback_ptr, pointers.calculate_bank(address)) callback_script = parse_script_engine_script_at(callback_address) callback_pointers[len(callback_pointers.keys())] = [hook_byte, callback_ptr] callbacks[index] = { "script": callback_script, "address": callback_address, "pointer": {"1": callback_byte1, "2": callback_byte2}, } # XXX do these triggers/callbacks call asm or script engine scripts? return { #"trigger_ptr_cnt": trigger_ptr_cnt, "trigger_pointers": trigger_pointers, #"callback_ptr_cnt": callback_ptr_cnt, #"callback_ptr_scripts": callback_ptrs, "callback_pointers": callback_pointers, "trigger_scripts": triggers, "callback_scripts": callbacks, }
def test_rom_interval(self): address = 0x100 interval = 10 correct_strings = [ '0x0', '0xc3', '0x6e', '0x1', '0xce', '0xed', '0x66', '0x66', '0xcc', '0xd' ] byte_strings = rom_interval(address, interval, strings=True) self.assertEqual(byte_strings, correct_strings) correct_ints = [0, 195, 110, 1, 206, 237, 102, 102, 204, 13] ints = rom_interval(address, interval, strings=False) self.assertEqual(ints, correct_ints)
def old_parse_map_header_at(address, map_group=None, map_id=None, all_map_headers=None, rom=None, debug=True): """parses an arbitrary map header at some address""" logging.debug("parsing a map header at {0}".format(hex(address))) bytes = rom_interval(address, map_header_byte_size, rom=rom, strings=False, debug=debug) bank = bytes[0] tileset = bytes[1] permission = bytes[2] second_map_header_address = pointers.calculate_pointer(bytes[3] + (bytes[4] << 8), 0x25) location_on_world_map = bytes[5] # pokegear world map location music = bytes[6] time_of_day = bytes[7] fishing_group = bytes[8] map_header = { "bank": bank, "tileset": tileset, "permission": permission, # map type? "second_map_header_pointer": {"1": bytes[3], "2": bytes[4]}, "second_map_header_address": second_map_header_address, "location_on_world_map": location_on_world_map, # area "music": music, "time_of_day": time_of_day, "fishing": fishing_group, } logging.debug("second map header address is {0}".format(hex(second_map_header_address))) map_header["second_map_header"] = old_parse_second_map_header_at(second_map_header_address, rom=rom, debug=debug) event_header_address = map_header["second_map_header"]["event_address"] script_header_address = map_header["second_map_header"]["script_address"] # maybe event_header and script_header should be put under map_header["second_map_header"] map_header["event_header"] = old_parse_map_event_header_at(event_header_address, map_group=map_group, map_id=map_id, rom=rom, debug=debug) map_header["script_header"] = old_parse_map_script_header_at(script_header_address, map_group=map_group, map_id=map_id, rom=rom, debug=debug) return map_header
def old_parse_second_map_header_at(address, map_group=None, map_id=None, rom=None, debug=True): """each map has a second map header""" bytes = rom_interval(address, second_map_header_byte_size, rom=rom, strings=False) border_block = bytes[0] height = bytes[1] width = bytes[2] blockdata_bank = bytes[3] blockdata_pointer = bytes[4] + (bytes[5] << 8) blockdata_address = pointers.calculate_pointer(blockdata_pointer, blockdata_bank) script_bank = bytes[6] script_pointer = bytes[7] + (bytes[8] << 8) script_address = pointers.calculate_pointer(script_pointer, script_bank) event_bank = script_bank event_pointer = bytes[9] + (bytes[10] << 8) event_address = pointers.calculate_pointer(event_pointer, event_bank) connections = bytes[11] return { "border_block": border_block, "height": height, "width": width, "blockdata_bank": blockdata_bank, "blockdata_pointer": {"1": bytes[4], "2": bytes[5]}, "blockdata_address": blockdata_address, "script_bank": script_bank, "script_pointer": {"1": bytes[7], "2": bytes[8]}, "script_address": script_address, "event_bank": event_bank, "event_pointer": {"1": bytes[9], "2": bytes[10]}, "event_address": event_address, "connections": connections, }
def setup_for(self, somecls, byte_size=2, address=443, **kwargs): self.rom = load_rom() self.cls = somecls(address=address, size=byte_size, **kwargs) self.assertEqual(self.cls.address, address) self.assertEqual( self.cls.bytes, rom_interval(address, byte_size, rom=self.rom, strings=False)) self.assertEqual(self.cls.size, byte_size)
def old_parse_map_header_at(address, map_group=None, map_id=None, all_map_headers=None, rom=None, debug=True): """parses an arbitrary map header at some address""" logging.debug("parsing a map header at {0}".format(hex(address))) bytes = rom_interval(address, map_header_byte_size, rom=rom, strings=False, debug=debug) bank = bytes[0] tileset = bytes[1] permission = bytes[2] second_map_header_address = pointers.calculate_pointer( bytes[3] + (bytes[4] << 8), 0x25) location_on_world_map = bytes[5] # pokegear world map location music = bytes[6] time_of_day = bytes[7] fishing_group = bytes[8] map_header = { "bank": bank, "tileset": tileset, "permission": permission, # map type? "second_map_header_pointer": { "1": bytes[3], "2": bytes[4] }, "second_map_header_address": second_map_header_address, "location_on_world_map": location_on_world_map, # area "music": music, "time_of_day": time_of_day, "fishing": fishing_group, } logging.debug("second map header address is {0}".format( hex(second_map_header_address))) map_header["second_map_header"] = old_parse_second_map_header_at( second_map_header_address, rom=rom, debug=debug) event_header_address = map_header["second_map_header"]["event_address"] script_header_address = map_header["second_map_header"]["script_address"] # maybe event_header and script_header should be put under map_header["second_map_header"] map_header["event_header"] = old_parse_map_event_header_at( event_header_address, map_group=map_group, map_id=map_id, rom=rom, debug=debug) map_header["script_header"] = old_parse_map_script_header_at( script_header_address, map_group=map_group, map_id=map_id, rom=rom, debug=debug) return map_header
def old_parse_map_event_header_at(address, map_group=None, map_id=None, rom=None, debug=True): """parse crystal map event header byte structure thing""" returnable = {} bank = pointers.calculate_bank(address) logging.debug("event header address is {0}".format(hex(address))) filler1 = ord(rom[address]) filler2 = ord(rom[address+1]) returnable.update({"1": filler1, "2": filler2}) # warps warp_count = ord(rom[address+2]) warp_byte_count = warp_byte_size * warp_count warps = rom_interval(address+3, warp_byte_count, rom=rom) after_warps = address + 3 + warp_byte_count returnable.update({"warp_count": warp_count, "warps": old_parse_warp_bytes(warps)}) # triggers (based on xy location) trigger_count = ord(rom[after_warps]) trigger_byte_count = trigger_byte_size * trigger_count triggers = rom_interval(after_warps+1, trigger_byte_count, rom=rom) after_triggers = after_warps + 1 + trigger_byte_count returnable.update({"xy_trigger_count": trigger_count, "xy_triggers": old_parse_xy_trigger_bytes(triggers, bank=bank, map_group=map_group, map_id=map_id)}) # signposts signpost_count = ord(rom[after_triggers]) signpost_byte_count = signpost_byte_size * signpost_count signposts = rom_interval(after_triggers+1, signpost_byte_count, rom=rom) after_signposts = after_triggers + 1 + signpost_byte_count returnable.update({"signpost_count": signpost_count, "signposts": old_parse_signpost_bytes(signposts, bank=bank, map_group=map_group, map_id=map_id, rom=rom)}) # people events people_event_count = ord(rom[after_signposts]) people_event_byte_count = people_event_byte_size * people_event_count people_events_bytes = rom_interval(after_signposts+1, people_event_byte_count, rom=rom) people_events = old_parse_people_event_bytes(people_events_bytes, address=after_signposts+1, map_group=map_group, map_id=map_id, rom=rom) returnable.update({"people_event_count": people_event_count, "people_events": people_events}) return returnable
def old_parse_second_map_header_at(address, map_group=None, map_id=None, rom=None, debug=True): """each map has a second map header""" bytes = rom_interval(address, second_map_header_byte_size, rom=rom, strings=False) border_block = bytes[0] height = bytes[1] width = bytes[2] blockdata_bank = bytes[3] blockdata_pointer = bytes[4] + (bytes[5] << 8) blockdata_address = pointers.calculate_pointer(blockdata_pointer, blockdata_bank) script_bank = bytes[6] script_pointer = bytes[7] + (bytes[8] << 8) script_address = pointers.calculate_pointer(script_pointer, script_bank) event_bank = script_bank event_pointer = bytes[9] + (bytes[10] << 8) event_address = pointers.calculate_pointer(event_pointer, event_bank) connections = bytes[11] return { "border_block": border_block, "height": height, "width": width, "blockdata_bank": blockdata_bank, "blockdata_pointer": { "1": bytes[4], "2": bytes[5] }, "blockdata_address": blockdata_address, "script_bank": script_bank, "script_pointer": { "1": bytes[7], "2": bytes[8] }, "script_address": script_address, "event_bank": event_bank, "event_pointer": { "1": bytes[9], "2": bytes[10] }, "event_address": event_address, "connections": connections, }
def old_parse_trainer_header_at(address, map_group=None, map_id=None, rom=None, debug=True): bank = pointers.calculate_bank(address) bytes = rom_interval(address, 12, rom=rom, strings=False) bit_number = bytes[0] + (bytes[1] << 8) trainer_group = bytes[2] trainer_id = bytes[3] text_when_seen_ptr = calculate_pointer_from_bytes_at(address+4, bank=bank) text_when_seen = parse_text_engine_script_at(text_when_seen_ptr, map_group=map_group, map_id=map_id, debug=debug) text_when_trainer_beaten_ptr = calculate_pointer_from_bytes_at(address+6, bank=bank) text_when_trainer_beaten = parse_text_engine_script_at(text_when_trainer_beaten_ptr, map_group=map_group, map_id=map_id, debug=debug) if [ord(rom[address+8]), ord(rom[address+9])] == [0, 0]: script_when_lost_ptr = 0 script_when_lost = None else: logging.debug("parsing script-when-lost") script_when_lost_ptr = calculate_pointer_from_bytes_at(address+8, bank=bank) script_when_lost = None silver_avoids = [0xfa53] if script_when_lost_ptr > 0x4000 and not script_when_lost_ptr in silver_avoids: script_when_lost = parse_script_engine_script_at(script_when_lost_ptr, map_group=map_group, map_id=map_id, debug=debug) logging.debug("parsing script-talk-again") # or is this a text? script_talk_again_ptr = calculate_pointer_from_bytes_at(address+10, bank=bank) script_talk_again = None if script_talk_again_ptr > 0x4000: script_talk_again = parse_script_engine_script_at(script_talk_again_ptr, map_group=map_group, map_id=map_id, debug=debug) return { "bit_number": bit_number, "trainer_group": trainer_group, "trainer_id": trainer_id, "text_when_seen_ptr": text_when_seen_ptr, "text_when_seen": text_when_seen, "text_when_trainer_beaten_ptr": text_when_trainer_beaten_ptr, "text_when_trainer_beaten": text_when_trainer_beaten, "script_when_lost_ptr": script_when_lost_ptr, "script_when_lost": script_when_lost, "script_talk_again_ptr": script_talk_again_ptr, "script_talk_again": script_talk_again, }
def setup_for(self, somecls, byte_size=2, address=443, **kwargs): self.cls = somecls(address=address, size=byte_size, **kwargs) self.assertEqual(self.cls.address, address) self.assertEqual(self.cls.bytes, rom_interval(address, byte_size, strings=False)) self.assertEqual(self.cls.size, byte_size)
def old_parse_map_event_header_at(address, map_group=None, map_id=None, rom=None, debug=True): """parse crystal map event header byte structure thing""" returnable = {} bank = pointers.calculate_bank(address) logging.debug("event header address is {0}".format(hex(address))) filler1 = ord(rom[address]) filler2 = ord(rom[address + 1]) returnable.update({"1": filler1, "2": filler2}) # warps warp_count = ord(rom[address + 2]) warp_byte_count = warp_byte_size * warp_count warps = rom_interval(address + 3, warp_byte_count, rom=rom) after_warps = address + 3 + warp_byte_count returnable.update({ "warp_count": warp_count, "warps": old_parse_warp_bytes(warps) }) # triggers (based on xy location) trigger_count = ord(rom[after_warps]) trigger_byte_count = trigger_byte_size * trigger_count triggers = rom_interval(after_warps + 1, trigger_byte_count, rom=rom) after_triggers = after_warps + 1 + trigger_byte_count returnable.update({ "xy_trigger_count": trigger_count, "xy_triggers": old_parse_xy_trigger_bytes(triggers, bank=bank, map_group=map_group, map_id=map_id) }) # signposts signpost_count = ord(rom[after_triggers]) signpost_byte_count = signpost_byte_size * signpost_count signposts = rom_interval(after_triggers + 1, signpost_byte_count, rom=rom) after_signposts = after_triggers + 1 + signpost_byte_count returnable.update({ "signpost_count": signpost_count, "signposts": old_parse_signpost_bytes(signposts, bank=bank, map_group=map_group, map_id=map_id, rom=rom) }) # people events people_event_count = ord(rom[after_signposts]) people_event_byte_count = people_event_byte_size * people_event_count people_events_bytes = rom_interval(after_signposts + 1, people_event_byte_count, rom=rom) people_events = old_parse_people_event_bytes(people_events_bytes, address=after_signposts + 1, map_group=map_group, map_id=map_id, rom=rom) returnable.update({ "people_event_count": people_event_count, "people_events": people_events }) return returnable
def old_parse_trainer_header_at(address, map_group=None, map_id=None, rom=None, debug=True): bank = pointers.calculate_bank(address) bytes = rom_interval(address, 12, rom=rom, strings=False) bit_number = bytes[0] + (bytes[1] << 8) trainer_group = bytes[2] trainer_id = bytes[3] text_when_seen_ptr = calculate_pointer_from_bytes_at(address + 4, bank=bank) text_when_seen = parse_text_engine_script_at(text_when_seen_ptr, map_group=map_group, map_id=map_id, debug=debug) text_when_trainer_beaten_ptr = calculate_pointer_from_bytes_at(address + 6, bank=bank) text_when_trainer_beaten = parse_text_engine_script_at( text_when_trainer_beaten_ptr, map_group=map_group, map_id=map_id, debug=debug) if [ord(rom[address + 8]), ord(rom[address + 9])] == [0, 0]: script_when_lost_ptr = 0 script_when_lost = None else: logging.debug("parsing script-when-lost") script_when_lost_ptr = calculate_pointer_from_bytes_at(address + 8, bank=bank) script_when_lost = None silver_avoids = [0xfa53] if script_when_lost_ptr > 0x4000 and not script_when_lost_ptr in silver_avoids: script_when_lost = parse_script_engine_script_at( script_when_lost_ptr, map_group=map_group, map_id=map_id, debug=debug) logging.debug("parsing script-talk-again") # or is this a text? script_talk_again_ptr = calculate_pointer_from_bytes_at(address + 10, bank=bank) script_talk_again = None if script_talk_again_ptr > 0x4000: script_talk_again = parse_script_engine_script_at( script_talk_again_ptr, map_group=map_group, map_id=map_id, debug=debug) return { "bit_number": bit_number, "trainer_group": trainer_group, "trainer_id": trainer_id, "text_when_seen_ptr": text_when_seen_ptr, "text_when_seen": text_when_seen, "text_when_trainer_beaten_ptr": text_when_trainer_beaten_ptr, "text_when_trainer_beaten": text_when_trainer_beaten, "script_when_lost_ptr": script_when_lost_ptr, "script_when_lost": script_when_lost, "script_talk_again_ptr": script_talk_again_ptr, "script_talk_again": script_talk_again, }
def old_parse_map_script_header_at(address, map_group=None, map_id=None, rom=None, debug=True): logging.debug("starting to parse the map's script header..") #[[Number1 of pointers] Number1 * [2byte pointer to script][00][00]] ptr_line_size = 4 #[2byte pointer to script][00][00] trigger_ptr_cnt = ord(rom[address]) trigger_pointers = helpers.grouper(rom_interval(address + 1, trigger_ptr_cnt * ptr_line_size, rom=rom, strings=False), count=ptr_line_size) triggers = {} for index, trigger_pointer in enumerate(trigger_pointers): logging.debug("parsing a trigger header...") byte1 = trigger_pointer[0] byte2 = trigger_pointer[1] ptr = byte1 + (byte2 << 8) trigger_address = pointers.calculate_pointer( ptr, pointers.calculate_bank(address)) trigger_script = parse_script_engine_script_at(trigger_address, map_group=map_group, map_id=map_id) triggers[index] = { "script": trigger_script, "address": trigger_address, "pointer": { "1": byte1, "2": byte2 }, } # bump ahead in the byte stream address += trigger_ptr_cnt * ptr_line_size + 1 #[[Number2 of pointers] Number2 * [hook number][2byte pointer to script]] callback_ptr_line_size = 3 callback_ptr_cnt = ord(rom[address]) callback_ptrs = helpers.grouper(rom_interval(address + 1, callback_ptr_cnt * callback_ptr_line_size, rom=rom, strings=False), count=callback_ptr_line_size) callback_pointers = {} callbacks = {} for index, callback_line in enumerate(callback_ptrs): logging.debug("parsing a callback header..") hook_byte = callback_line[0] # 1, 2, 3, 4, 5 callback_byte1 = callback_line[1] callback_byte2 = callback_line[2] callback_ptr = callback_byte1 + (callback_byte2 << 8) callback_address = pointers.calculate_pointer( callback_ptr, pointers.calculate_bank(address)) callback_script = parse_script_engine_script_at(callback_address) callback_pointers[len( callback_pointers.keys())] = [hook_byte, callback_ptr] callbacks[index] = { "script": callback_script, "address": callback_address, "pointer": { "1": callback_byte1, "2": callback_byte2 }, } # XXX do these triggers/callbacks call asm or script engine scripts? return { #"trigger_ptr_cnt": trigger_ptr_cnt, "trigger_pointers": trigger_pointers, #"callback_ptr_cnt": callback_ptr_cnt, #"callback_ptr_scripts": callback_ptrs, "callback_pointers": callback_pointers, "trigger_scripts": triggers, "callback_scripts": callbacks, }