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,
    }
Пример #3
0
 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,
    }
Пример #6
0
 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)
Пример #7
0
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
Пример #9
0
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)
Пример #12
0
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
Пример #13
0
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,
    }
Пример #14
0
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,
    }