def read_from_rom(self, rom):
        with EbCompressibleBlock() as block:
            # Read the tileset data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, TILESET_POINTER)
                )
            )
            self.tileset.from_block(block=block, offset=0, bpp=TILESET_BPP)

            # Read the arrangement data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, ARRANGEMENT_POINTER)
                )
            )
            self.arrangement.from_block(block=block, offset=0)

            # Read the palette data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, PALETTE_POINTER)
                )
            )
            self.palette.from_block(block=block, offset=0)
Example #2
0
    def write_to_rom(self, rom):
        self.enemy_config_table.to_block(
            block=rom,
            offset=from_snes_address(ENEMY_CONFIGURATION_TABLE_DEFAULT_OFFSET))
        self.enemy_group_bg_table.to_block(
            block=rom,
            offset=from_snes_address(
                ENEMY_GROUP_BACKGROUND_TABLE_DEFAULT_OFFSET))

        # Write the sprites
        self.graphics_pointer_table.recreate(num_rows=len(self.battle_sprites))
        for i, battle_sprite in enumerate(self.battle_sprites):
            self.graphics_pointer_table[i] = [None, battle_sprite.size()]
            with EbCompressibleBlock(
                    size=battle_sprite.block_size()) as compressed_block:
                battle_sprite.to_block(block=compressed_block, offset=0)
                compressed_block.compress()
                graphics_offset = rom.allocate(data=compressed_block)
                self.graphics_pointer_table[i][0] = to_snes_address(
                    graphics_offset)

        graphics_pointer_table_offset = rom.allocate(
            size=self.graphics_pointer_table.size)
        self.graphics_pointer_table.to_block(
            block=rom, offset=graphics_pointer_table_offset)
        write_asm_pointer(
            block=rom,
            offset=GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSET,
            pointer=to_snes_address(graphics_pointer_table_offset))
        for pointer_offset in GRAPHICS_POINTER_TABLE_POINTER_OFFSETS:
            rom.write_multi(
                pointer_offset,
                item=to_snes_address(graphics_pointer_table_offset),
                size=3)

        # Write the palettes
        if self.palettes:
            palettes_offset = rom.allocate(size=self.palettes[0].block_size() *
                                           len(self.palettes))
            write_asm_pointer(block=rom,
                              offset=PALETTES_ASM_POINTER_OFFSET,
                              pointer=to_snes_address(palettes_offset))
            for palette in self.palettes:
                palette.to_block(block=rom, offset=palettes_offset)
                palettes_offset += palette.block_size()

        # Write the groups
        for i, group in enumerate(self.enemy_groups):
            offset = rom.allocate(
                size=(len(group) * EnemyGroupTableEntry.size + 1))
            self.enemy_group_table[i][0] = to_snes_address(offset)
            for group_entry in group:
                EnemyGroupTableEntry.to_block(block=rom,
                                              offset=offset,
                                              value=group_entry)
                offset += EnemyGroupTableEntry.size
            rom[offset] = 0xff
        self.enemy_group_table.to_block(
            block=rom,
            offset=from_snes_address(ENEMY_GROUP_TABLE_DEFAULT_OFFSET))
    def read_from_rom(self, rom):
        with EbCompressibleBlock() as block:
            # Read the tileset data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, TILESET_POINTER)
                )
            )
            self.tileset.from_block(block=block, offset=0, bpp=TILESET_BPP)

            # Read the arrangement data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, ARRANGEMENT_POINTER)
                )
            )
            self.arrangement.from_block(block=block, offset=0)

            # Read the palette data
            block.from_compressed_block(
                block=rom, offset=from_snes_address(
                    read_asm_pointer(rom, PALETTE_POINTER)
                )
            )
            self.palette.from_block(block=block, offset=0)
Example #4
0
 def write_to_rom(self, rom):
     # Deallocate the range of the ROM in which we will write the door destinations.
     # We deallocate it here instead of specifying it in FREE_RANGES because we want to be sure that this module
     # get first dibs at writing to this range. This is because door destinations needs to be written to the 0x0F
     # bank of the EB ROM, and this is one of the few ranges available in that bank.
     rom.deallocate((0x0F0000, 0x0F58EE))
     destination_offsets = dict()
     empty_area_offset = from_snes_address(
         rom.allocate(data=[0, 0], can_write_to=not_in_destination_bank))
     i = 0
     for door_area in self.door_areas:
         if (door_area is None) or (not door_area):
             self.pointer_table[i] = [empty_area_offset]
         else:
             num_doors = len(door_area)
             area_offset = rom.allocate(
                 size=(2 + num_doors * 5),
                 can_write_to=not_in_destination_bank)
             self.pointer_table[i] = [to_snes_address(area_offset)]
             rom.write_multi(area_offset, num_doors, 2)
             area_offset += 2
             for door in door_area:
                 door.write_to_block(rom, area_offset, destination_offsets)
                 area_offset += 5
         i += 1
     self.pointer_table.to_block(rom, from_snes_address(0xD00000))
Example #5
0
    def read_from_rom(self, rom):
        self.font_pointer_table.from_block(block=rom,
                                           offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))
        for i, font in enumerate(self.fonts):
            log.debug("Reading font #{} from the ROM".format(FONT_FILENAMES[i]))
            font.from_block(block=rom,
                            tileset_offset=from_snes_address(self.font_pointer_table[i][1]),
                            character_widths_offset=from_snes_address(self.font_pointer_table[i][0]))

        self.read_credits_font_from_rom(rom)
Example #6
0
    def read_from_rom(self, rom):
        self.font_pointer_table.from_block(block=rom,
                                           offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))
        for i, font in enumerate(self.fonts):
            log.debug("Reading font #{} from the ROM".format(FONT_FILENAMES[i]))
            font.from_block(block=rom,
                            tileset_offset=from_snes_address(self.font_pointer_table[i][1]),
                            character_widths_offset=from_snes_address(self.font_pointer_table[i][0]))

        self.read_credits_font_from_rom(rom)
 def read_town_map_icons_from_rom(self, rom):
     log.debug("Reading town map icons")
     graphics_offset = from_snes_address(read_asm_pointer(block=rom,
                                                          offset=TOWN_MAP_ICON_GRAPHICS_ASM_POINTER_OFFSET))
     palette_offset = from_snes_address(read_asm_pointer(block=rom,
                                                         offset=TOWN_MAP_ICON_PALETTE_ASM_POINTER_OFFSET))
     self.town_map_icons.from_block(block=rom,
                                    graphics_offset=graphics_offset,
                                    arrangement_offset=0,
                                    palette_offsets=[palette_offset])
    def read_logos_from_rom(self, rom, logos, infos):
        for info, logo in zip(infos, logos):
            graphics_offset = from_snes_address(read_asm_pointer(rom, info.graphics_asm_pointer_offsets[0]))
            arrangement_offset = from_snes_address(read_asm_pointer(rom, info.arrangement_asm_pointer_offsets[0]))
            palette_offsets = [from_snes_address(read_asm_pointer(rom, x)) for x in info.palette_asm_pointer_offsets]

            logo.from_block(block=rom,
                            graphics_offset=graphics_offset,
                            arrangement_offset=arrangement_offset,
                            palette_offsets=palette_offsets)
 def read_town_map_icons_from_rom(self, rom):
     log.debug("Reading town map icons")
     graphics_offset = from_snes_address(read_asm_pointer(block=rom,
                                                          offset=TOWN_MAP_ICON_GRAPHICS_ASM_POINTER_OFFSET))
     palette_offset = from_snes_address(read_asm_pointer(block=rom,
                                                         offset=TOWN_MAP_ICON_PALETTE_ASM_POINTER_OFFSET))
     self.town_map_icons.from_block(block=rom,
                                    graphics_offset=graphics_offset,
                                    arrangement_offset=0,
                                    palette_offsets=[palette_offset])
    def read_logos_from_rom(self, rom, logos, infos):
        for info, logo in zip(infos, logos):
            graphics_offset = from_snes_address(read_asm_pointer(rom, info.graphics_asm_pointer_offsets[0]))
            arrangement_offset = from_snes_address(read_asm_pointer(rom, info.arrangement_asm_pointer_offsets[0]))
            palette_offsets = [from_snes_address(read_asm_pointer(rom, x)) for x in info.palette_asm_pointer_offsets]

            logo.from_block(block=rom,
                            graphics_offset=graphics_offset,
                            arrangement_offset=arrangement_offset,
                            palette_offsets=palette_offsets)
Example #11
0
    def read_from_rom(self, rom):
        log.debug("Reading pointer tables")
        self.graphics_pointer_table.from_block(rom, from_snes_address(GRAPHICS_POINTER_TABLE_OFFSET))
        self.arrangements_pointer_table.from_block(rom, from_snes_address(ARRANGEMENTS_POINTER_TABLE_OFFSET))
        self.collisions_pointer_table.from_block(rom, from_snes_address(COLLISIONS_POINTER_TABLE_OFFSET))
        self.map_tileset_table.from_block(rom, from_snes_address(MAP_TILESET_TABLE_OFFSET))
        self.palette_pointer_table.from_block(rom, from_snes_address(PALETTE_POINTER_TABLE_OFFSET))

        for i, tileset in enumerate(self.tilesets):
            log.debug("Reading tileset #{}".format(i))
            tileset.minitiles_from_block(rom, from_snes_address(self.graphics_pointer_table[i][0]))
            tileset.arrangements_from_block(rom, from_snes_address(self.arrangements_pointer_table[i][0]))
            tileset.collisions_from_block(rom, from_snes_address(self.collisions_pointer_table[i][0]))

        # Read palettes
        log.debug("Reading palettes")
        for i in range(self.map_tileset_table.num_rows):
            draw_tileset = self.map_tileset_table[i][0]
            # Estimate the number of palettes for this map tileset, assuming that the palettes are stored contiguously
            if i == 31:
                k = 8
            else:
                k = self.palette_pointer_table[i + 1][0] - self.palette_pointer_table[i][0]
                k /= 0xc0

            # Add the palettes to the tileset
            palette_offset = from_snes_address(self.palette_pointer_table[i][0])
            for j in range(k):
                palette = EbMapPalette()
                palette.from_block(block=rom, offset=palette_offset)
                self.tilesets[draw_tileset].add_palette(i, j, palette)
                palette_offset += 0xc0
Example #12
0
    def write_to_rom(self, rom):
        self.font_pointer_table.from_block(block=rom,
                                           offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))
        for i, font in enumerate(self.fonts):
            log.debug("Writing font #{} to the ROM".format(FONT_FILENAMES[i]))

            graphics_offset, widths_offset = font.to_block(block=rom)
            self.font_pointer_table[i][0] = to_snes_address(widths_offset)
            self.font_pointer_table[i][1] = to_snes_address(graphics_offset)
        self.font_pointer_table.to_block(block=rom,
                                         offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))

        self.write_credits_font_to_rom(rom)
Example #13
0
    def write_to_rom(self, rom):
        self.font_pointer_table.from_block(block=rom,
                                           offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))
        for i, font in enumerate(self.fonts):
            log.debug("Writing font #{} to the ROM".format(FONT_FILENAMES[i]))

            graphics_offset, widths_offset = font.to_block(block=rom)
            self.font_pointer_table[i][0] = to_snes_address(widths_offset)
            self.font_pointer_table[i][1] = to_snes_address(graphics_offset)
        self.font_pointer_table.to_block(block=rom,
                                         offset=from_snes_address(FONT_POINTER_TABLE_OFFSET))

        self.write_credits_font_to_rom(rom)
Example #14
0
    def write_to_rom(self, rom):
        # Write the data table
        self.bg_table.to_block(block=rom, offset=from_snes_address(BACKGROUND_TABLE_OFFSET))
        self.scroll_table.to_block(block=rom, offset=from_snes_address(SCROLL_TABLE_OFFSET))
        self.distortion_table.to_block(block=rom, offset=from_snes_address(DISTORTION_TABLE_OFFSET))

        # Write graphics and arrangements
        self.graphics_pointer_table.recreate(num_rows=len(self.backgrounds))
        self.arrangement_pointer_table.recreate(num_rows=len(self.backgrounds))
        for i, (tileset, color_depth, arrangement) in enumerate(self.backgrounds):
            with EbCompressibleBlock(size=tileset.block_size(bpp=color_depth)) as compressed_block:
                tileset.to_block(block=compressed_block, offset=0, bpp=color_depth)
                compressed_block.compress()
                tileset_offset = rom.allocate(data=compressed_block)
                self.graphics_pointer_table[i] = [to_snes_address(tileset_offset)]

            with EbCompressibleBlock(size=arrangement.block_size()) as compressed_block:
                arrangement.to_block(block=compressed_block, offset=0)
                compressed_block.compress()
                arrangement_offset = rom.allocate(data=compressed_block)
                self.arrangement_pointer_table[i] = [to_snes_address(arrangement_offset)]

        graphics_pointer_table_offset = rom.allocate(size=self.graphics_pointer_table.size)
        self.graphics_pointer_table.to_block(block=rom, offset=graphics_pointer_table_offset)
        for asm_pointer_offset in GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSETS:
            write_asm_pointer(block=rom,
                              offset=asm_pointer_offset,
                              pointer=to_snes_address(graphics_pointer_table_offset))

        arrangement_pointer_table_offset = rom.allocate(size=self.arrangement_pointer_table.size)
        self.arrangement_pointer_table.to_block(block=rom, offset=arrangement_pointer_table_offset)
        for asm_pointer_offset in ARRANGEMENT_POINTER_TABLE_ASM_POINTER_OFFSETS:
            write_asm_pointer(block=rom,
                              offset=asm_pointer_offset,
                              pointer=to_snes_address(arrangement_pointer_table_offset))

        # Write pals
        self.palette_pointer_table.recreate(num_rows=len(self.palettes))
        for i, palette in enumerate(self.palettes):
            with Block(32) as block:
                palette.to_block(block=block, offset=0)
                palette_offset = rom.allocate(data=block)
                self.palette_pointer_table[i] = [to_snes_address(palette_offset)]

        palette_pointer_table_offset = rom.allocate(size=self.palette_pointer_table.size)
        self.palette_pointer_table.to_block(block=rom, offset=palette_pointer_table_offset)
        for asm_pointer_offset in PALETTE_POINTER_TABLE_ASM_POINTER_OFFSETS:
            write_asm_pointer(block=rom,
                              offset=asm_pointer_offset,
                              pointer=to_snes_address(palette_pointer_table_offset))
Example #15
0
    def write_to_rom(self, rom):
        apply_relocation_patch(rom)

        # Write frames and populate swirl table
        frame_hashes = {}
        animation_pointers = []
        animation_pointers_index = 0
        for i, swirl in enumerate(self.swirls):
            num_frames = len(swirl.frames)

            self.swirl_table[i] = [swirl.speed, animation_pointers_index, num_frames]

            frame_offsets = write_swirl_frames(rom, swirl, frame_hashes)
            animation_pointers += frame_offsets
            animation_pointers_index += num_frames

        # Allocate animation pointer table
        animation_pointer_table_offset = rom.allocate(size=4 * len(animation_pointers))
        for offset, pointer_delta in RELOCATED_SWIRL_ANIMATION_POINTER_TABLE_POINTERS:
            rom.write_multi(offset, to_snes_address(animation_pointer_table_offset + pointer_delta), 3)

        # Write animation pointer table
        for animation_pointer in animation_pointers:
            rom.write_multi(animation_pointer_table_offset, to_snes_address(animation_pointer), 4)
            animation_pointer_table_offset += 4

        # Write swirls table
        self.swirl_table.to_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))
    def read_from_rom(self, rom):
        self.group_pointer_table.from_block(rom, from_snes_address(GROUP_POINTER_TABLE_OFFSET))
        self.palette_table.from_block(rom, from_snes_address(PALETTE_TABLE_OFFSET))

        # Load the sprite groups
        self.groups = []
        for i in range(self.group_pointer_table.num_rows):
            # Note: this assumes that the SPT is written contiguously
            num_sprites = 8
            # Assume that the last group only has 8 sprites
            if i < self.group_pointer_table.num_rows - 1:
                num_sprites = (self.group_pointer_table[i + 1][0] - self.group_pointer_table[i][0] - 9) // 2

            group = SpriteGroup(num_sprites)
            group.from_block(rom, from_snes_address(self.group_pointer_table[i][0]))
            self.groups.append(group)
    def test_read_from_project(self):
        with open(os.path.join(TEST_DATA_DIR, 'summary.txt'), 'r') as summary_file:
            def resource_open(a, b):
                return summary_file

            self.module.read_from_project(resource_open)

        assert_equal((from_snes_address(0xf10000), from_snes_address(0xf19430)), self.module.used_range)
        assert_dict_equal(
            {
                'file1.test1': 0xc23456,
                'file1.test2': 0xf18cfb,
                'file1.label_with_a_very_very_very_very_long_name': 0xf18e4f,
                'short_module.entry1': 0xf00d13
            },
            EbPointer.label_address_map)
 def read_from_rom(self, rom):
     graphics_offset = from_snes_address(read_asm_pointer(
         block=rom, offset=GRAPHICS_ASM_POINTER_OFFSET))
     with EbCompressibleBlock() as compressed_block:
         compressed_block.from_compressed_block(block=rom, offset=graphics_offset)
         self.tileset.from_block(block=compressed_block, bpp=4)
     self.palette.from_block(block=rom, offset=PALETTE_OFFSET)
    def write_to_rom(self, rom):
        with Block(size=sum(x.block_size() for x in self.groups)) as block:
            offset = 0
            # Write all the groups to the block, and sprites to rom
            for i, group in enumerate(self.groups):
                group.write_sprites_to_free(rom)
                group.to_block(block, offset)
                self.group_pointer_table[i] = [offset]
                offset += group.block_size()
            # Write the block to rom and correct the group pointers
            address = to_snes_address(rom.allocate(data=block))
            for i in range(self.group_pointer_table.num_rows):
                self.group_pointer_table[i][0] += address

        self.group_pointer_table.to_block(block=rom, offset=from_snes_address(GROUP_POINTER_TABLE_OFFSET))
        self.palette_table.to_block(block=rom, offset=from_snes_address(PALETTE_TABLE_OFFSET))
    def read_chars_layouts_from_rom(self, rom):
        lda_instruction = rom[CHARS_LAYOUT_BANK]
        chars_layout_pointer_offset = CHARS_LAYOUT_POINTER_OFFSET_DEFAULT

        # Check if we are dealing with the modified Rom,
        # If we are, we need to recalculate the offset to the
        # character layouts
        if lda_instruction == 0xA9:
            bank = rom[CHARS_LAYOUT_BANK + 1]
            chars_layout_pointer_offset = from_snes_address(bank << 16)

        self.chars_layouts = [[] for _ in range(NUM_CHARS)]
        for char in range(NUM_CHARS):
            # Get the location of a character's data
            offset = chars_layout_pointer_offset + rom.read_multi(
                CHARS_LAYOUT_TABLE + char*2, 2
            )

            # Read entries until a final entry is encountered
            while True:
                entry = TitleScreenLayoutEntry()
                entry.from_block(rom, offset)
                self.chars_layouts[char].append(entry)
                offset += 5
                if entry.is_final():
                    break
    def read_chars_layouts_from_rom(self, rom):
        lda_instruction = rom[CHARS_LAYOUT_BANK]
        chars_layout_pointer_offset = CHARS_LAYOUT_POINTER_OFFSET_DEFAULT

        # Check if we are dealing with the modified Rom,
        # If we are, we need to recalculate the offset to the
        # character layouts
        if lda_instruction == 0xA9:
            bank = rom[CHARS_LAYOUT_BANK + 1]
            chars_layout_pointer_offset = from_snes_address(bank << 16)

        self.chars_layouts = [[] for _ in range(NUM_CHARS)]
        for char in range(NUM_CHARS):
            # Get the location of a character's data
            offset = chars_layout_pointer_offset + rom.read_multi(
                CHARS_LAYOUT_TABLE + char * 2, 2)

            # Read entries until a final entry is encountered
            while True:
                entry = TitleScreenLayoutEntry()
                entry.from_block(rom, offset)
                self.chars_layouts[char].append(entry)
                offset += 5
                if entry.is_final():
                    break
Example #22
0
 def read_from_rom(self, rom):
     self.pointer_table.from_block(rom, from_snes_address(0xD00000))
     self.door_areas = []
     for i in range(self.pointer_table.num_rows):
         offset = from_snes_address(self.pointer_table[i][0])
         door_area = []
         num_doors = rom.read_multi(offset, 2)
         offset += 2
         for j in range(num_doors):
             door = door_from_block(rom, offset)
             if door is None:
                 # If we've found an invalid door, stop reading from this door group.
                 # This is expected, since a clean ROM contains some invalid doors.
                 break
             door_area.append(door)
             offset += 5
         self.door_areas.append(door_area)
Example #23
0
    def read_from_rom(self, rom):
        bank = rom[POINTER_TABLE_BANK_OFFSET] - 0xc0
        log.debug("Reading data from {:#x} bank".format(bank))
        self.pointer_table_entry_class.bank = bank

        pointer_table_offset = from_snes_address(rom.read_multi(POINTER_TABLE_POINTER_OFFSET, 3))
        log.debug("Reading pointer table from {:#x}".format(pointer_table_offset))
        self.pointer_table.from_block(rom, pointer_table_offset)
Example #24
0
 def read_from_rom(self, rom):
     graphics_offset = from_snes_address(
         read_asm_pointer(block=rom, offset=GRAPHICS_ASM_POINTER_OFFSET))
     with EbCompressibleBlock() as compressed_block:
         compressed_block.from_compressed_block(block=rom,
                                                offset=graphics_offset)
         self.tileset.from_block(block=compressed_block, bpp=4)
     self.palette.from_block(block=rom, offset=PALETTE_OFFSET)
Example #25
0
 def read_from_rom(self, rom):
     self.pointer_table.from_block(rom, from_snes_address(0xD00000))
     self.door_areas = []
     for i in range(self.pointer_table.num_rows):
         offset = from_snes_address(self.pointer_table[i][0])
         door_area = []
         num_doors = rom.read_multi(offset, 2)
         offset += 2
         for j in range(num_doors):
             door = door_from_block(rom, offset)
             if door is None:
                 # If we've found an invalid door, stop reading from this door group.
                 # This is expected, since a clean ROM contains some invalid doors.
                 break
             door_area.append(door)
             offset += 5
         self.door_areas.append(door_area)
Example #26
0
 def from_block(self, block, tileset_asm_pointer_offset, palette_offset):
     with EbCompressibleBlock() as compressed_block:
         compressed_block.from_compressed_block(
             block=block,
             offset=from_snes_address(
                 read_asm_pointer(block=block,
                                  offset=tileset_asm_pointer_offset)))
         self.tileset.from_block(block=compressed_block, bpp=2)
     self.palette.from_block(block=block, offset=palette_offset)
Example #27
0
    def write_to_rom(self, rom):
        with Block(size=sum(x.block_size() for x in self.groups)) as block:
            offset = 0
            # Write all the groups to the block, and sprites to rom
            for i, group in enumerate(self.groups):
                group.write_sprites_to_free(rom)
                group.to_block(block, offset)
                self.group_pointer_table[i] = [offset]
                offset += group.block_size()
            # Write the block to rom and correct the group pointers
            address = to_snes_address(rom.allocate(data=block))
            for i in range(self.group_pointer_table.num_rows):
                self.group_pointer_table[i][0] += address

        self.group_pointer_table.to_block(
            block=rom, offset=from_snes_address(GROUP_POINTER_TABLE_OFFSET))
        self.palette_table.to_block(
            block=rom, offset=from_snes_address(PALETTE_TABLE_OFFSET))
Example #28
0
def test_from_snes_address():
    assert_equal(from_snes_address(0xc00000), 0)
    assert_equal(from_snes_address(0xcf1234), 0xf1234)
    assert_equal(from_snes_address(0xeabc4f), 0x2abc4f)
    assert_equal(from_snes_address(0xffffff), 0x3fffff)
    assert_equal(from_snes_address(0x400000), 0x400000)
    assert_equal(from_snes_address(0x4daa34), 0x4daa34)
    assert_equal(from_snes_address(0x5fffff), 0x5fffff)
Example #29
0
def test_from_snes_address():
    assert_equal(from_snes_address(0xc00000), 0)
    assert_equal(from_snes_address(0xcf1234), 0xf1234)
    assert_equal(from_snes_address(0xeabc4f), 0x2abc4f)
    assert_equal(from_snes_address(0xffffff), 0x3fffff)
    assert_equal(from_snes_address(0x400000), 0x400000)
    assert_equal(from_snes_address(0x4daa34), 0x4daa34)
    assert_equal(from_snes_address(0x5fffff), 0x5fffff)
Example #30
0
    def read_from_rom(self, rom):
        self.text = self.table_entry.from_block(
            rom,
            from_snes_address(
                read_asm_pointer(block=rom, offset=self.asm_pointer_offset)))

        for mode in DYNAMIC_CAST_NAME_MODES:
            if self.get_patch(mode, rom.type).is_applied(rom):
                self.mode = mode
                break
Example #31
0
    def from_block(cls, block, offset):
        data_offset = from_snes_address(super(TownMapIconPlacementPointerTableEntry, cls).from_block(block, offset))
        if not data_offset:
            return []

        value = []
        while block[data_offset] != 0xff:
            value.append(cls.table_entry_class.from_block(block, data_offset))
            data_offset += cls.table_entry_class.size
        return value
Example #32
0
    def read_from_rom(self, rom):
        self.table.from_block(rom,
                              offset=from_snes_address(
                                  read_animation_table_address(rom)))

        for index in range(self.table.num_rows):
            row = self.table[index]
            offset = row[0]
            graphics_data_size = row[1]
            frames = row[2]
            unknown = row[
                3]  # This field appears to be related somewhat to animation speed

            if graphics_data_size > 0:  # Only add animations that have data
                animation = Animation(graphics_data_size=graphics_data_size,
                                      frames=frames,
                                      unknown=unknown)
                animation.from_block(rom, from_snes_address(offset))
                self.animations.append(animation)
    def test_read_from_project(self):
        with open(os.path.join(TEST_DATA_DIR, 'summary.txt'),
                  'r') as summary_file:

            def resource_open(a, b):
                return summary_file

            self.module.read_from_project(resource_open)

        assert_equal(
            (from_snes_address(0xf10000), from_snes_address(0xf19430)),
            self.module.used_range)
        assert_dict_equal(
            {
                'file1.test1': 0xc23456,
                'file1.test2': 0xf18cfb,
                'file1.label_with_a_very_very_very_very_long_name': 0xf18e4f,
                'short_module.entry1': 0xf00d13
            }, EbPointer.label_address_map)
Example #34
0
    def read_from_rom(self, rom):
        bank = rom[POINTER_TABLE_BANK_OFFSET] - 0xc0
        log.debug("Reading data from {:#x} bank".format(bank))
        self.pointer_table_entry_class.bank = bank

        pointer_table_offset = from_snes_address(
            rom.read_multi(POINTER_TABLE_POINTER_OFFSET, 3))
        log.debug(
            "Reading pointer table from {:#x}".format(pointer_table_offset))
        self.pointer_table.from_block(rom, pointer_table_offset)
Example #35
0
    def read_from_rom(self, rom):
        self.swirl_table.from_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))

        if test_swirl_relocated(rom):
            # Calculate total number of animations from the swirl table
            total_animations = 0
            for i in range(self.swirl_table.num_rows):
                total_animations += self.swirl_table[i][2]

            # Read in the offset of the relocated animation table
            offset = rom.read_multi(
                RELOCATED_SWIRL_ANIMATION_POINTER_TABLE_POINTERS[0][0], 3)

            # Pointer size is now 4, so read in 4 bytes at a time
            all_animation_pointers = [
                from_snes_address(
                    rom.read_multi(from_snes_address(offset + (i * 4)), 4))
                for i in range(total_animations)
            ]
        else:
            self.pointer_table.from_block(
                rom,
                offset=from_snes_address(
                    SWIRL_ANIMATION_POINTER_TABLE_DEFAULT_OFFSET))

            all_animation_pointers = [
                from_snes_address(self.pointer_table[i][0]
                                  | SWIRL_ANIMATION_POINTER_TABLE_BASE)
                for i in range(self.pointer_table.num_rows)
            ]

        self.swirls = [None] * self.swirl_table.num_rows
        for i in range(self.swirl_table.num_rows):
            speed = self.swirl_table[i][0]
            first_animation = self.swirl_table[i][1]
            number_of_animations = self.swirl_table[i][2]

            animation_pointers = all_animation_pointers[
                first_animation:first_animation + number_of_animations]
            self.swirls[i] = Swirl(speed=speed)
            self.swirls[i].frames_from_block(rom, animation_pointers)
    def read_from_project(self, resource_open):
        EbPointer.label_address_map.clear()
        # Read and parse the summary file
        with resource_open(CccInterfaceModule.SUMMARY_RESOURCE_NAME, CccInterfaceModule.SUMMARY_RESOURCE_NAME) as \
                summary_file:
            summary_file_lines = summary_file.readlines()
            if summary_file_lines:
                compilation_start_address = int(summary_file_lines[7][30:], 16)
                compilation_end_address = int(summary_file_lines[8][30:], 16)
                if compilation_start_address != 0xffffffff and compilation_end_address != 0xffffffff:
                    self.used_range = (
                        from_snes_address(compilation_start_address),
                        from_snes_address(compilation_end_address))
                    log.debug(
                        "Found range[({:#x},{:#x})] used during compilation".
                        format(self.used_range[0], self.used_range[1]))
                else:
                    log.debug("Found no space used during compilation")

                module_name = None
                in_module_section = False  # False = before section, True = in section
                for line in summary_file_lines:
                    line = line.rstrip()
                    if in_module_section:
                        if line.startswith("-"):
                            in_module_section = False
                        else:
                            label_key = module_name + "." + line.split(' ',
                                                                       1)[0]
                            label_val = int(line[-6:], 16)
                            EbPointer.label_address_map[label_key] = label_val
                            log.debug(
                                "Adding CCScript label[{}] with address[{:#x}] in module[{}]"
                                .format(label_key, label_val, module_name))
                    elif line.startswith("-") and module_name is not None:
                        in_module_section = True
                    elif line.startswith("Labels in module "):
                        module_name = line[17:]
                        log.debug(
                            "Found CCScript module[{}]".format(module_name))
        log.debug("Found a total of {} CCScript labels".format(
            len(EbPointer.label_address_map)))
Example #37
0
    def read_from_rom(self, rom):
        self.swirl_table.from_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))
        self.pointer_table.from_block(
            rom, offset=from_snes_address(SWIRL_ANIMATION_POINTER_TABLE_DEFAULT_OFFSET))

        all_animation_pointers = [
            from_snes_address(self.pointer_table[i][0] | SWIRL_ANIMATION_POINTER_TABLE_BASE)
            for i in xrange(self.pointer_table.num_rows)
        ]

        self.swirls = [None] * self.swirl_table.num_rows
        for i in xrange(self.swirl_table.num_rows):
            speed = self.swirl_table[i][0]
            first_animation = self.swirl_table[i][1]
            number_of_animations = self.swirl_table[i][2]

            animation_pointers = all_animation_pointers[first_animation:first_animation+number_of_animations]
            self.swirls[i] = Swirl(speed=speed)
            self.swirls[i].frames_from_block(rom, animation_pointers)
Example #38
0
    def read_from_rom(self, rom):
        staff_text_offset = from_snes_address(self.read_pointer_from_rom(rom))
        self.read_staff_chars_from_assets()
        log.debug('Reading staff text')
        i = 0
        byte = 0x00

        while byte != CONTROL_END_OF_STAFF:
            byte = rom[staff_text_offset + i]
            self.data.append(byte)
            i += 1
Example #39
0
    def read_from_rom(self, rom):
        self.group_pointer_table.from_block(
            rom, from_snes_address(GROUP_POINTER_TABLE_OFFSET))
        self.palette_table.from_block(rom,
                                      from_snes_address(PALETTE_TABLE_OFFSET))

        # Load the sprite groups
        self.groups = []
        for i in range(self.group_pointer_table.num_rows):
            # Note: this assumes that the SPT is written contiguously
            num_sprites = 8
            # Assume that the last group only has 8 sprites
            if i < self.group_pointer_table.num_rows - 1:
                num_sprites = (self.group_pointer_table[i + 1][0] -
                               self.group_pointer_table[i][0] - 9) / 2

            group = SpriteGroup(num_sprites)
            group.from_block(rom,
                             from_snes_address(self.group_pointer_table[i][0]))
            self.groups.append(group)
Example #40
0
    def from_block(cls, block, offset):
        data_offset = from_snes_address(
            super(TownMapIconPlacementPointerTableEntry,
                  cls).from_block(block, offset))
        if not data_offset:
            return []

        value = []
        while block[data_offset] != 0xff:
            value.append(cls.table_entry_class.from_block(block, data_offset))
            data_offset += cls.table_entry_class.size
        return value
Example #41
0
    def read_from_rom(self, rom):
        # Read map data
        map_ptrs_addr = from_snes_address(rom.read_multi(MAP_POINTERS_OFFSET, 3))
        map_addrs = [from_snes_address(rom.read_multi(map_ptrs_addr + x * 4, 4)) for x in range(8)]

        def read_row_data(row_number):
            offset = map_addrs[row_number % 8] + ((row_number >> 3) << 8)
            return rom[offset:offset + MAP_WIDTH].to_list()

        self.tiles = map(read_row_data, range(MAP_HEIGHT))
        k = LOCAL_TILESETS_OFFSET
        for i in range(MAP_HEIGHT >> 3):
            for j in range(MAP_WIDTH):
                self.tiles[i << 3][j] |= (rom[k] & 3) << 8
                self.tiles[(i << 3) | 1][j] |= ((rom[k] >> 2) & 3) << 8
                self.tiles[(i << 3) | 2][j] |= ((rom[k] >> 4) & 3) << 8
                self.tiles[(i << 3) | 3][j] |= ((rom[k] >> 6) & 3) << 8
                self.tiles[(i << 3) | 4][j] |= (rom[k + 0x3000] & 3) << 8
                self.tiles[(i << 3) | 5][j] |= ((rom[k + 0x3000] >> 2) & 3) << 8
                self.tiles[(i << 3) | 6][j] |= ((rom[k + 0x3000] >> 4) & 3) << 8
                self.tiles[(i << 3) | 7][j] |= ((rom[k + 0x3000] >> 6) & 3) << 8
                k += 1

        # Read sector data
        self.sector_tilesets_palettes_table.from_block(rom, from_snes_address(SECTOR_TILESETS_PALETTES_TABLE_OFFSET))
        self.sector_music_table.from_block(rom, from_snes_address(SECTOR_MUSIC_TABLE_OFFSET))
        self.sector_misc_table.from_block(rom, from_snes_address(SECTOR_MISC_TABLE_OFFSET))
        self.sector_town_map_table.from_block(rom, from_snes_address(SECTOR_TOWN_MAP_TABLE_OFFSET))
Example #42
0
    def write_to_rom(self, rom):
        self.enemy_config_table.to_block(block=rom,
                                         offset=from_snes_address(ENEMY_CONFIGURATION_TABLE_DEFAULT_OFFSET))
        self.enemy_group_bg_table.to_block(block=rom,
                                           offset=from_snes_address(ENEMY_GROUP_BACKGROUND_TABLE_DEFAULT_OFFSET))

        # Write the sprites
        self.graphics_pointer_table.recreate(num_rows=len(self.battle_sprites))
        for i, battle_sprite in enumerate(self.battle_sprites):
            self.graphics_pointer_table[i] = [None, battle_sprite.size()]
            with EbCompressibleBlock(size=battle_sprite.block_size()) as compressed_block:
                battle_sprite.to_block(block=compressed_block, offset=0)
                compressed_block.compress()
                graphics_offset = rom.allocate(data=compressed_block)
                self.graphics_pointer_table[i][0] = to_snes_address(graphics_offset)

        graphics_pointer_table_offset = rom.allocate(size=self.graphics_pointer_table.size)
        self.graphics_pointer_table.to_block(block=rom, offset=graphics_pointer_table_offset)
        write_asm_pointer(block=rom, offset=GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSET,
                          pointer=to_snes_address(graphics_pointer_table_offset))
        for pointer_offset in GRAPHICS_POINTER_TABLE_POINTER_OFFSETS:
            rom.write_multi(pointer_offset, item=to_snes_address(graphics_pointer_table_offset), size=3)

        # Write the palettes
        if self.palettes:
            palettes_offset = rom.allocate(size=self.palettes[0].block_size() * len(self.palettes))
            write_asm_pointer(block=rom, offset=PALETTES_ASM_POINTER_OFFSET, pointer=to_snes_address(palettes_offset))
            for palette in self.palettes:
                palette.to_block(block=rom, offset=palettes_offset)
                palettes_offset += palette.block_size()

        # Write the groups
        for i, group in enumerate(self.enemy_groups):
            offset = rom.allocate(size=(len(group) * EnemyGroupTableEntry.size + 1))
            self.enemy_group_table[i] = [to_snes_address(offset)]
            for group_entry in group:
                EnemyGroupTableEntry.to_block(block=rom, offset=offset, value=group_entry)
                offset += EnemyGroupTableEntry.size
            rom[offset] = 0xff
        self.enemy_group_table.to_block(block=rom, offset=from_snes_address(ENEMY_GROUP_TABLE_DEFAULT_OFFSET))
Example #43
0
    def write_to_rom(self, rom):
        # Write map data
        map_ptrs_addr = from_snes_address(rom.read_multi(MAP_POINTERS_OFFSET, 3))
        map_addrs = [from_snes_address(rom.read_multi(map_ptrs_addr + x * 4, 4)) for x in range(8)]

        for i in range(MAP_HEIGHT):
            offset = map_addrs[i % 8] + ((i >> 3) << 8)
            rom[offset:offset + MAP_WIDTH] = [x & 0xff for x in self.tiles[i]]
        k = LOCAL_TILESETS_OFFSET
        for i in range(MAP_HEIGHT >> 3):
            for j in range(MAP_WIDTH):
                c = ((self.tiles[i << 3][j] >> 8)
                     | ((self.tiles[(i << 3) | 1][j] >> 8) << 2)
                     | ((self.tiles[(i << 3) | 2][j] >> 8) << 4)
                     | ((self.tiles[(i << 3) | 3][j] >> 8) << 6))
                rom[k] = c
                c = ((self.tiles[(i << 3) | 4][j] >> 8)
                     | ((self.tiles[(i << 3) | 5][j] >> 8) << 2)
                     | ((self.tiles[(i << 3) | 6][j] >> 8) << 4)
                     | ((self.tiles[(i << 3) | 7][j] >> 8) << 6))
                rom[k + 0x3000] = c
                k += 1

        # Write sector data
        self.sector_tilesets_palettes_table.to_block(rom, from_snes_address(SECTOR_TILESETS_PALETTES_TABLE_OFFSET))
        self.sector_music_table.to_block(rom, from_snes_address(SECTOR_MUSIC_TABLE_OFFSET))
        self.sector_misc_table.to_block(rom, from_snes_address(SECTOR_MISC_TABLE_OFFSET))
        self.sector_town_map_table.to_block(rom, from_snes_address(SECTOR_TOWN_MAP_TABLE_OFFSET))
Example #44
0
    def read_from_rom(self, rom):
        self.bg_table.from_block(block=rom, offset=from_snes_address(BACKGROUND_TABLE_OFFSET))
        self.scroll_table.from_block(block=rom, offset=from_snes_address(SCROLL_TABLE_OFFSET))
        self.distortion_table.from_block(block=rom, offset=from_snes_address(DISTORTION_TABLE_OFFSET))
        self.graphics_pointer_table.from_block(
            block=rom,
            offset=from_snes_address(read_asm_pointer(block=rom,
                                                      offset=GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSETS[0])))
        self.arrangement_pointer_table.from_block(
            block=rom,
            offset=from_snes_address(read_asm_pointer(block=rom,
                                                      offset=ARRANGEMENT_POINTER_TABLE_ASM_POINTER_OFFSETS[0])))
        self.palette_pointer_table.from_block(
            block=rom,
            offset=from_snes_address(read_asm_pointer(block=rom,
                                                      offset=PALETTE_POINTER_TABLE_ASM_POINTER_OFFSETS[0])))

        self.backgrounds = [None for i in range(self.graphics_pointer_table.num_rows)]
        self.palettes = [None for i in range(self.palette_pointer_table.num_rows)]
        for i in range(self.bg_table.num_rows):
            graphics_id = self.bg_table[i][0]
            color_depth = self.bg_table[i][2]
            if self.backgrounds[graphics_id] is None:
                # Max tiles used in rom: 421 (2bpp) 442 (4bpp)
                tileset = EbGraphicTileset(num_tiles=512, tile_width=8, tile_height=8)
                with EbCompressibleBlock() as compressed_block:
                    compressed_block.from_compressed_block(
                        block=rom,
                        offset=from_snes_address(self.graphics_pointer_table[graphics_id][0]))
                    tileset.from_block(compressed_block, offset=0, bpp=color_depth)

                arrangement = EbTileArrangement(width=32, height=32)
                with EbCompressibleBlock() as compressed_block:
                    compressed_block.from_compressed_block(
                        block=rom,
                        offset=from_snes_address(self.arrangement_pointer_table[graphics_id][0]))
                    arrangement.from_block(block=compressed_block, offset=0)

                self.backgrounds[graphics_id] = (tileset, color_depth, arrangement)
                
            palette_id = self.bg_table[i][1]
            if self.palettes[palette_id] is None:
                palette = EbPalette(num_subpalettes=1, subpalette_length=16)
                palette.from_block(block=rom, offset=from_snes_address(self.palette_pointer_table[palette_id][0]))
                self.palettes[palette_id] = palette
Example #45
0
 def write_to_rom(self, rom):
     # Deallocate the range of the ROM in which we will write the door destinations.
     # We deallocate it here instead of specifying it in FREE_RANGES because we want to be sure that this module
     # get first dibs at writing to this range. This is because door destinations needs to be written to the 0x0F
     # bank of the EB ROM, and this is one of the few ranges available in that bank.
     rom.deallocate((0x0F0000, 0x0F58EE))
     destination_offsets = dict()
     empty_area_offset = from_snes_address(rom.allocate(data=[0, 0], can_write_to=not_in_destination_bank))
     i = 0
     for door_area in self.door_areas:
         if (door_area is None) or (not door_area):
             self.pointer_table[i] = [empty_area_offset]
         else:
             num_doors = len(door_area)
             area_offset = rom.allocate(size=(2 + num_doors * 5), can_write_to=not_in_destination_bank)
             self.pointer_table[i] = [to_snes_address(area_offset)]
             rom.write_multi(area_offset, num_doors, 2)
             area_offset += 2
             for door in door_area:
                 door.write_to_block(rom, area_offset, destination_offsets)
                 area_offset += 5
         i += 1
     self.pointer_table.to_block(rom, from_snes_address(0xD00000))
Example #46
0
    def read_from_rom(self, rom):
        self.swirl_table.from_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))
        self.pointer_table.from_block(
            rom,
            offset=from_snes_address(
                SWIRL_ANIMATION_POINTER_TABLE_DEFAULT_OFFSET))

        all_animation_pointers = [
            from_snes_address(self.pointer_table[i][0]
                              | SWIRL_ANIMATION_POINTER_TABLE_BASE)
            for i in xrange(self.pointer_table.num_rows)
        ]

        self.swirls = [None] * self.swirl_table.num_rows
        for i in xrange(self.swirl_table.num_rows):
            speed = self.swirl_table[i][0]
            first_animation = self.swirl_table[i][1]
            number_of_animations = self.swirl_table[i][2]

            animation_pointers = all_animation_pointers[
                first_animation:first_animation + number_of_animations]
            self.swirls[i] = Swirl(speed=speed)
            self.swirls[i].frames_from_block(rom, animation_pointers)
Example #47
0
    def read_from_rom(self, rom):
        self.swirl_table.from_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))

        if test_swirl_relocated(rom):
            # Calculate total number of animations from the swirl table
            total_animations = 0        
            for i in range(self.swirl_table.num_rows):
                total_animations += self.swirl_table[i][2]

            # Read in the offset of the relocated animation table
            offset = rom.read_multi(RELOCATED_SWIRL_ANIMATION_POINTER_TABLE_POINTERS[0][0], 3)

            # Pointer size is now 4, so read in 4 bytes at a time
            all_animation_pointers = [
                from_snes_address(rom.read_multi(from_snes_address(offset + (i * 4)), 4))
                for i in range(total_animations)
            ]
        else:
            self.pointer_table.from_block(
                rom, offset=from_snes_address(SWIRL_ANIMATION_POINTER_TABLE_DEFAULT_OFFSET))

            all_animation_pointers = [
                from_snes_address(self.pointer_table[i][0] | SWIRL_ANIMATION_POINTER_TABLE_BASE)
                for i in range(self.pointer_table.num_rows)
            ]

        self.swirls = [None] * self.swirl_table.num_rows
        for i in range(self.swirl_table.num_rows):
            speed = self.swirl_table[i][0]
            first_animation = self.swirl_table[i][1]
            number_of_animations = self.swirl_table[i][2]

            animation_pointers = all_animation_pointers[first_animation:first_animation+number_of_animations]
            self.swirls[i] = Swirl(speed=speed)
            self.swirls[i].frames_from_block(rom, animation_pointers)
    def read_from_project(self, resource_open):
        EbPointer.label_address_map.clear()
        # Read and parse the summary file
        with resource_open(CccInterfaceModule.SUMMARY_RESOURCE_NAME, CccInterfaceModule.SUMMARY_RESOURCE_NAME, True) as \
                summary_file:
            summary_file_lines = summary_file.readlines()
            if summary_file_lines:
                compilation_start_address = int(summary_file_lines[7][30:], 16)
                compilation_end_address = int(summary_file_lines[8][30:], 16)
                if compilation_start_address != 0xffffffff and compilation_end_address != 0xffffffff:
                    self.used_range = (from_snes_address(compilation_start_address),
                                       from_snes_address(compilation_end_address))
                    log.debug("Found range[({:#x},{:#x})] used during compilation".format(self.used_range[0],
                                                                                          self.used_range[1]))
                else:
                    log.debug("Found no space used during compilation")

                module_name = None
                in_module_section = False  # False = before section, True = in section
                for line in summary_file_lines:
                    line = line.rstrip()
                    if in_module_section:
                        if line.startswith("-"):
                            in_module_section = False
                        else:
                            label_key = module_name + "." + line.split(' ', 1)[0]
                            label_val = int(line[-6:], 16)
                            EbPointer.label_address_map[label_key] = label_val
                            log.debug("Adding CCScript label[{}] with address[{:#x}] in module[{}]".format(
                                label_key, label_val, module_name))
                    elif line.startswith("-") and module_name is not None:
                        in_module_section = True
                    elif line.startswith("Labels in module "):
                        module_name = line[17:]
                        log.debug("Found CCScript module[{}]".format(module_name))
        log.debug("Found a total of {} CCScript labels".format(len(EbPointer.label_address_map)))
Example #49
0
    def read_from_rom(self, rom):
        with EbCompressibleBlock() as compressed_block:
            compressed_block.from_compressed_block(
                block=rom,
                offset=from_snes_address(read_asm_pointer(rom, GRAPHICS_1_ASM_POINTER_OFFSET)))
            self.graphics_1.from_block(block=compressed_block, bpp=2)

        with EbCompressibleBlock() as compressed_block:
            compressed_block.from_compressed_block(
                block=rom,
                offset=from_snes_address(read_asm_pointer(rom, GRAPHICS_2_ASM_POINTER_OFFSET)))
            self.graphics_2.from_block(block=compressed_block, bpp=2)

        # Read palettes
        offset = FLAVOR_PALETTES_OFFSET
        for palette in self.flavor_palettes:
            palette.from_block(block=rom, offset=offset)
            offset += 64

        # Read names
        for asm_pointer_offset in FLAVOR_NAME_ASM_POINTER_OFFSETS:
            self.flavor_names[asm_pointer_offset] = FLAVOR_NAME_ENTRY.from_block(
                block=rom,
                offset=from_snes_address(read_asm_pointer(block=rom, offset=asm_pointer_offset)))
Example #50
0
    def read_from_rom(self, rom):
        self.enemy_config_table.from_block(block=rom,
                                           offset=from_snes_address(ENEMY_CONFIGURATION_TABLE_DEFAULT_OFFSET))
        self.enemy_group_bg_table.from_block(block=rom,
                                             offset=from_snes_address(ENEMY_GROUP_BACKGROUND_TABLE_DEFAULT_OFFSET))

        # Read the sprites
        log.debug("Reading battle sprites")
        self.graphics_pointer_table.from_block(
            rom, from_snes_address(read_asm_pointer(block=rom, offset=GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSET)))
        self.battle_sprites = []
        for i in range(self.graphics_pointer_table.num_rows):
            with EbCompressibleBlock() as compressed_block:
                compressed_block.from_compressed_block(
                    block=rom,
                    offset=from_snes_address(self.graphics_pointer_table[i][0]))
                sprite = EbBattleSprite()
                sprite.from_block(block=compressed_block, offset=0, size=self.graphics_pointer_table[i][1])
                self.battle_sprites.append(sprite)

        # Determine how many palettes there are
        num_palettes = 0
        for i in range(self.enemy_config_table.num_rows):
            num_palettes = max(num_palettes, self.enemy_config_table[i][14])
        num_palettes += 1

        # Read the palettes
        log.debug("Reading palettes")
        palettes_offset = from_snes_address(read_asm_pointer(block=rom, offset=PALETTES_ASM_POINTER_OFFSET))
        self.palettes = []
        for i in range(num_palettes):
            palette = EbPalette(num_subpalettes=1, subpalette_length=16)
            palette.from_block(block=rom, offset=palettes_offset)
            self.palettes.append(palette)
            palettes_offset += palette.block_size()

        # Read the groups
        log.debug("Reading enemy groups")
        self.enemy_group_table.from_block(rom, from_snes_address(ENEMY_GROUP_TABLE_DEFAULT_OFFSET))
        self.enemy_groups = []
        for i in range(self.enemy_group_table.num_rows):
            group = []
            group_offset = from_snes_address(self.enemy_group_table[i][0])
            while rom[group_offset] != 0xff:
                group.append(EnemyGroupTableEntry.from_block(block=rom, offset=group_offset))
                group_offset += EnemyGroupTableEntry.size
            self.enemy_groups.append(group)
Example #51
0
    def read_from_rom(self, rom):
        self.enemy_config_table.from_block(block=rom,
                                           offset=from_snes_address(ENEMY_CONFIGURATION_TABLE_DEFAULT_OFFSET))
        self.enemy_group_bg_table.from_block(block=rom,
                                             offset=from_snes_address(ENEMY_GROUP_BACKGROUND_TABLE_DEFAULT_OFFSET))

        # Read the sprites
        log.debug("Reading battle sprites")
        self.graphics_pointer_table.from_block(
            rom, from_snes_address(read_asm_pointer(block=rom, offset=GRAPHICS_POINTER_TABLE_ASM_POINTER_OFFSET)))
        self.battle_sprites = []
        for i in range(self.graphics_pointer_table.num_rows):
            with EbCompressibleBlock() as compressed_block:
                compressed_block.from_compressed_block(
                    block=rom,
                    offset=from_snes_address(self.graphics_pointer_table[i][0]))
                sprite = EbBattleSprite()
                sprite.from_block(block=compressed_block, offset=0, size=self.graphics_pointer_table[i][1])
                self.battle_sprites.append(sprite)

        # Determine how many palettes there are
        num_palettes = 0
        for i in range(self.enemy_config_table.num_rows):
            num_palettes = max(num_palettes, self.enemy_config_table[i][14])
        num_palettes += 1

        # Read the palettes
        log.debug("Reading palettes")
        palettes_offset = from_snes_address(read_asm_pointer(block=rom, offset=PALETTES_ASM_POINTER_OFFSET))
        self.palettes = []
        for i in range(num_palettes):
            palette = EbPalette(num_subpalettes=1, subpalette_length=16)
            palette.from_block(block=rom, offset=palettes_offset)
            self.palettes.append(palette)
            palettes_offset += palette.block_size()

        # Read the groups
        log.debug("Reading enemy groups")
        self.enemy_group_table.from_block(rom, from_snes_address(ENEMY_GROUP_TABLE_DEFAULT_OFFSET))
        self.enemy_groups = []
        for i in range(self.enemy_group_table.num_rows):
            group = []
            group_offset = from_snes_address(self.enemy_group_table[i][0])
            while rom[group_offset] != 0xff:
                group.append(EnemyGroupTableEntry.from_block(block=rom, offset=group_offset))
                group_offset += EnemyGroupTableEntry.size
            self.enemy_groups.append(group)
Example #52
0
    def from_block(self, rom, offset):
        header_data = SpriteGroupHeaderTableEntry.from_block(rom, offset)
        self.height = header_data[0]
        self.width = header_data[1] >> 4
        self.size = header_data[2]
        self.palette = (header_data[3] >> 1) & 0x7
        self.collision_ns_w = header_data[4]
        self.collision_ns_h = header_data[5]
        self.collision_ew_w = header_data[6]
        self.collision_ew_h = header_data[7]
        bank = header_data[8] << 16

        self.sprites = [[EbRegularSprite(), False] for i in range(self.num_sprites)]
        i = offset + 9
        for spff in self.sprites:
            ptr = bank | rom.read_multi(i, 2)
            spff[1] = (ptr & 2) != 0
            spff[0].from_block(rom, self.width * 8, self.height * 8, from_snes_address(ptr & 0xfffffc))
            if (ptr & 1) != 0:
                spff[0].flip_horizontally()
            i += 2
Example #53
0
    def write_to_rom(self, rom):
        if not test_swirl_relocated(rom):
            apply_relocation_patch(rom)

        # Write frames and populate swirl table
        frame_hashes = {}
        animation_pointers = []
        animation_pointers_index = 0
        for i, swirl in enumerate(self.swirls):
            num_frames = len(swirl.frames)

            self.swirl_table[i] = [
                swirl.speed, animation_pointers_index, num_frames
            ]

            frame_offsets = write_swirl_frames(rom, swirl, frame_hashes)
            animation_pointers += frame_offsets
            animation_pointers_index += num_frames

        # Allocate animation pointer table
        animation_pointer_table_offset = rom.allocate(size=4 *
                                                      len(animation_pointers))
        for offset, pointer_delta in RELOCATED_SWIRL_ANIMATION_POINTER_TABLE_POINTERS:
            rom.write_multi(
                offset,
                to_snes_address(animation_pointer_table_offset +
                                pointer_delta), 3)

        # Write animation pointer table
        for animation_pointer in animation_pointers:
            rom.write_multi(animation_pointer_table_offset,
                            to_snes_address(animation_pointer), 4)
            animation_pointer_table_offset += 4

        # Write swirls table
        self.swirl_table.to_block(
            rom, offset=from_snes_address(SWIRL_TABLE_DEFAULT_OFFSET))
 def read_from_rom(self, rom):
     for offset, table in self.tables.iteritems():
         table.from_block(rom, from_snes_address(offset))
Example #55
0
 def write_to_rom(self, rom):
     self.group_pointer_table.to_block(rom, from_snes_address(GROUP_POINTER_TABLE_OFFSET))
     self.group_placement_table.to_block(rom, from_snes_address(GROUP_PLACEMENT_TABLE_OFFSET))