Exemplo n.º 1
0
    def test_from_block(self):
        block = Block()
        block.from_list([1] * 5)
        block.write_multi(1, 0x8000 | 0x2000 | (7 << 10) | 0x120, 2)
        block.write_multi(3, 0x4000 | (2 << 10) | 0x3f5, 2)

        arrangement = EbTileArrangement(2, 1)
        arrangement.from_block(block, 1)

        assert_true(arrangement[0, 0].is_vertically_flipped)
        assert_false(arrangement[0, 0].is_horizontally_flipped)
        assert_true(arrangement[0, 0].is_priority, True)
        assert_equal(arrangement[0, 0].subpalette, 7)
        assert_equal(arrangement[0, 0].tile, 0x120)

        assert_false(arrangement[1, 0].is_vertically_flipped)
        assert_true(arrangement[1, 0].is_horizontally_flipped)
        assert_false(arrangement[1, 0].is_priority)
        assert_equal(arrangement[1, 0].subpalette, 2)
        assert_equal(arrangement[1, 0].tile, 0x3f5)

        arrangement = EbTileArrangement(1, 2)
        arrangement.from_block(block, 1)

        assert_true(arrangement[0, 0].is_vertically_flipped)
        assert_false(arrangement[0, 0].is_horizontally_flipped)
        assert_true(arrangement[0, 0].is_priority, True)
        assert_equal(arrangement[0, 0].subpalette, 7)
        assert_equal(arrangement[0, 0].tile, 0x120)

        assert_false(arrangement[0, 1].is_vertically_flipped)
        assert_true(arrangement[0, 1].is_horizontally_flipped)
        assert_false(arrangement[0, 1].is_priority)
        assert_equal(arrangement[0, 1].subpalette, 2)
        assert_equal(arrangement[0, 1].tile, 0x3f5)
Exemplo n.º 2
0
    def test_from_image_8x8_1bpp(self):
        palette = EbPalette(1, 2)
        palette[0, 0].from_tuple((0xff, 0xff, 0xff))
        palette[0, 1].from_tuple((0x0, 0x0, 0x0))

        arrangement = EbTileArrangement(width=2, height=2)
        arrangement[0, 0].tile = 0
        arrangement[1, 0].tile = 2
        arrangement[0, 1].tile = 1
        arrangement[1, 1].tile = 3

        tileset = EbGraphicTileset(num_tiles=4, tile_width=8, tile_height=8)
        tileset.from_image(self.tile_8x8_2bpp_img,
                           arrangement=arrangement,
                           palette=palette)
        assert_list_equal(tileset[0], [[0] * 8] * 8)
        assert_list_equal(tileset[2], [[1] * 8] * 8)
        assert_list_equal(tileset[1],
                          [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0],
                           [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]])
        assert_list_equal(tileset[3],
                          [[0, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1],
                           [0, 1, 0, 0, 0, 0, 1, 1], [1, 1, 0, 0, 1, 0, 1, 1],
                           [1, 1, 0, 1, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0, 1, 1],
                           [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0]])
Exemplo n.º 3
0
    def __init__(self):
        super(TitleScreenModule, self).__init__()

        # Background data (includes the central "B", the copyright
        # notice and the glow around the letters)
        self.bg_tileset = EbGraphicTileset(num_tiles=BG_NUM_TILES,
                                           tile_width=TILE_WIDTH,
                                           tile_height=TILE_HEIGHT)
        self.bg_arrangement = EbTileArrangement(width=BG_ARRANGEMENT_WIDTH,
                                                height=BG_ARRANGEMENT_HEIGHT)
        self.bg_anim_palette = EbPalette(
            num_subpalettes=BG_NUM_ANIM_SUBPALETTES,
            subpalette_length=ANIM_SUBPALETTE_LENGTH)
        self.bg_palette = EbPalette(num_subpalettes=NUM_SUBPALETTES,
                                    subpalette_length=BG_SUBPALETTE_LENGTH)

        # Characters data (the title screen's animated letters)
        self.chars_tileset = EbGraphicTileset(num_tiles=CHARS_NUM_TILES,
                                              tile_width=TILE_WIDTH,
                                              tile_height=TILE_HEIGHT)
        self.chars_anim_palette = EbPalette(
            num_subpalettes=CHARS_NUM_ANIM_SUBPALETTES,
            subpalette_length=ANIM_SUBPALETTE_LENGTH)
        self.chars_palette = EbPalette(
            num_subpalettes=NUM_SUBPALETTES,
            subpalette_length=CHARS_SUBPALETTE_LENGTH)
        self.chars_layouts = [[] for _ in xrange(NUM_CHARS)]
Exemplo n.º 4
0
    def test_to_image_single_subpalette(self):
        palette = EbPalette(1, 2)
        tileset = EbGraphicTileset(num_tiles=6, tile_width=8, tile_height=8)
        arrangement = EbTileArrangement(width=6, height=1)
        arrangement.from_image(self.tile_8x8_2bpp_2_img,
                               tileset=tileset,
                               palette=palette)

        new_image = arrangement.image(tileset, palette)
        assert_images_equal(self.tile_8x8_2bpp_2_img, new_image)
Exemplo n.º 5
0
    def __init__(self):
        super(DeathScreenModule, self).__init__()

        self.tileset = EbGraphicTileset(num_tiles=NUM_TILES,
                                        tile_width=TILE_WIDTH,
                                        tile_height=TILE_HEIGHT)
        self.arrangement = EbTileArrangement(width=ARRANGEMENT_WIDTH,
                                             height=ARRANGEMENT_HEIGHT)
        self.palette = EbPalette(num_subpalettes=NUM_SUBPALETTES,
                                 subpalette_length=SUBPALETTE_LENGTH)
Exemplo n.º 6
0
    def test_init(self):
        arrangement = EbTileArrangement(32, 28)
        assert_equal(arrangement.width, 32)
        assert_equal(arrangement.height, 28)

        assert_raises(InvalidArgumentError, EbTileArrangement, 0, 32)
        assert_raises(InvalidArgumentError, EbTileArrangement, -1, 32)
        assert_raises(InvalidArgumentError, EbTileArrangement, 32, 0)
        assert_raises(InvalidArgumentError, EbTileArrangement, 32, -1)
        assert_raises(InvalidArgumentError, EbTileArrangement, 0, 0)
        assert_raises(InvalidArgumentError, EbTileArrangement, -1, -1)
Exemplo n.º 7
0
    def read_background_data_from_project(self, resource_open):
        # Load the background reference image
        # The image's arrangement, tileset and palette will be used for the
        # animation frames
        with resource_open(BG_REFERENCE_PATH, "png") as f:
            image = open_indexed_image(f)
            self.bg_arrangement.from_image(
                image, self.bg_tileset, self.bg_palette
            )

        # Read the background animated frames
        for frame in range(NUM_ANIM_FRAMES):
            # Create temporary structures used to check consistency between
            # frames
            tileset = EbGraphicTileset(BG_NUM_TILES, TILE_WIDTH, TILE_HEIGHT)
            arrangement = EbTileArrangement(
                BG_ARRANGEMENT_WIDTH, BG_ARRANGEMENT_HEIGHT
            )
            palette = EbPalette(NUM_SUBPALETTES, BG_SUBPALETTE_LENGTH)

            # Read one frame's image data
            with resource_open(BG_FRAMES_PATH.format(frame), "png") as f:
                image = open_indexed_image(f)
                arrangement.from_image(image, tileset, palette)

            # Make sure each frame's tileset and arrangement is identical
            # The background palette is checked only if it isn't the fake
            # palette used for the first few frames
            if frame >= CHARS_NUM_ANIM_SUBPALETTES:
                # Get the background animated subpalette from the background
                # palette
                colors = palette[0, BG_ANIM_SLICE]
                self.bg_anim_palette.subpalettes[
                    frame - CHARS_NUM_ANIM_SUBPALETTES
                ] = colors
                palette[0, BG_ANIM_SLICE] = self.bg_palette[
                    0, BG_ANIM_SLICE
                ]
                if self.bg_palette != palette:
                    log.warn(
                        "Palette from background frame {} does not match "
                        "reference.".format(frame)
                    )
            if self.bg_tileset != tileset:
                log.warn(
                    "Tileset from background frame {} does not match "
                    "reference.".format(frame)
                )
            if self.bg_arrangement != arrangement:
                log.warn(
                    "Arrangement from background frame {} does not match "
                    "reference.".format(frame)
                )
Exemplo n.º 8
0
    def test_getitem(self):
        arrangement = EbTileArrangement(2, 1)
        assert_is_instance(arrangement[0, 0], EbTileArrangementItem)
        assert_is_instance(arrangement[1, 0], EbTileArrangementItem)

        assert_raises(InvalidArgumentError, arrangement.__getitem__, (-1, 0))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (0, -1))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (-1, -1))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (0, 1))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (0, 2))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (1, 2))
        assert_raises(InvalidArgumentError, arrangement.__getitem__, (3, 0))
Exemplo n.º 9
0
    def write_chars_data_to_project(self, resource_open):
        # Build an arrangement combining every character for convenience
        chars_positions = {}
        arrangement = EbTileArrangement(3*9, 6)
        for c, layout in enumerate(self.chars_layouts):
            top_left = {'x': 128, 'y': 128}
            for e, entry in enumerate(layout):
                tile = entry.tile & (CHARS_NUM_TILES - 1)
                top_left['x'] = min(top_left['x'], int(entry.x))
                top_left['y'] = min(top_left['y'], int(entry.y))
                x = c*3 + (entry.x + 16) // 8
                y = (entry.y + 24) // 8
                arrangement[x, y].tile = tile
                if not entry.is_single():
                    arrangement[x+1, y].tile = tile + 1
                    arrangement[x, y+1].tile = tile + 16
                    arrangement[x+1, y+1].tile = tile + 17
            chars_positions[c] = {
                'x': c*3*8,
                'y': 0,
                'width': 3*8,
                'height': 6*8,
                'top_left_offset': top_left,
                'unknown': layout[0].unknown
            }

        # Write the characters animation frames
        for p in range(CHARS_NUM_ANIM_SUBPALETTES):
            with resource_open(CHARS_FRAMES_PATH.format(p), "png") as f:
                image = arrangement.image(
                    self.chars_tileset,
                    self.chars_anim_palette.get_subpalette(p)
                )
                image.save(f)

        # Write out the initial characters palette
        with resource_open(CHARS_INITIAL_PATH, "png") as f:
            image = arrangement.image(
                self.chars_tileset,
                self.chars_palette
            )
            image.save(f)

        # Write out the positions of the characters
        with resource_open(CHARS_POSITIONS_PATH, "yml", True) as f:
            yml_dump(chars_positions, f, False)
Exemplo n.º 10
0
    def test_from_image_2_subpalettes(self):
        palette = EbPalette(2, 4)
        tileset = EbGraphicTileset(num_tiles=4, tile_width=8, tile_height=8)
        arrangement = EbTileArrangement(width=4, height=1)
        arrangement.from_image(image=self.tile_8x8_2bpp_3_img,
                               tileset=tileset,
                               palette=palette)

        img_palette = self.tile_8x8_2bpp_3_img.getpalette()
        self.tile_8x8_2bpp_3_img.putpalette([x & 0xf8 for x in img_palette])
        before_image_rgb = self.tile_8x8_2bpp_3_img.convert("RGB")
        after_image_rgb = arrangement.image(tileset, palette).convert("RGB")
        assert_images_equal(before_image_rgb, after_image_rgb)

        assert_set_equal({palette[1, i]
                          for i in range(4)}, {
                              EbColor(24, 0, 248),
                              EbColor(0, 248, 24),
                              EbColor(152, 0, 248),
                              EbColor(248, 144, 0)
                          })
        assert_set_equal({palette[0, i]
                          for i in range(4)}, {
                              EbColor(24, 0, 248),
                              EbColor(0, 248, 24),
                              EbColor(216, 248, 0),
                              EbColor(152, 0, 248)
                          })

        assert_equal(arrangement[0, 0].tile, 0)
        assert_equal(arrangement[0, 0].subpalette, 0)
        assert_equal({tileset[0][0][i]
                      for i in [-1, -2, -3, -4]}, {0, 1, 2, 3})

        assert_equal(arrangement[1, 0].tile, 1)
        assert_equal(arrangement[1, 0].subpalette, 1)
        assert_equal({tileset[1][0][i]
                      for i in [-1, -2, -3, -4]}, {0, 1, 2, 3})

        assert_equal(arrangement[2, 0].tile, 2)
        assert_equal(arrangement[2, 0].subpalette, 0)

        assert_equal(arrangement[3, 0].tile, 3)
        assert_equal(arrangement[3, 0].subpalette, 1)
Exemplo n.º 11
0
    def test_from_image_8x16_2bpp(self):
        palette = EbPalette(1, 4)
        palette[0, 0].from_tuple((0xff, 0xff, 0xff))
        palette[0, 1].from_tuple((0x30, 0x00, 0xff))
        palette[0, 2].from_tuple((0xff, 0x00, 0x00))
        palette[0, 3].from_tuple((0x00, 0xff, 0x48))

        arrangement = EbTileArrangement(width=2, height=3)
        arrangement[0, 0].tile = 1
        arrangement[1, 0].tile = 1
        arrangement[0, 1].tile = 3
        arrangement[1, 1].tile = 2
        arrangement[0, 2].tile = 0
        arrangement[1, 2].tile = 4

        tileset = EbGraphicTileset(num_tiles=5, tile_width=8, tile_height=16)
        tileset.from_image(self.tile_8x16_4bpp_img,
                           arrangement=arrangement,
                           palette=palette)

        assert_list_equal(tileset[1], [[2] * 8] * 16)
        assert_list_equal(tileset[3], [[3] * 8] * 16)
        assert_list_equal(tileset[2],
                          [[3] * 8, [3] * 8, [3] * 8, [3] * 8, [3] * 8,
                           [3, 3, 1, 3, 3, 3, 3, 3], [3, 3, 1, 3, 3, 1, 3, 3],
                           [1] * 8, [1, 1, 2, 2, 1, 1, 1, 1],
                           [1, 2, 2, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 2, 1, 1],
                           [1, 1, 1, 1, 2, 2, 1, 1], [1, 1, 2, 2, 2, 1, 1, 1],
                           [1] * 8, [1] * 8, [1, 1, 1, 3, 1, 1, 1, 1]])
        assert_list_equal(tileset[0],
                          [[2, 1, 1, 1, 1, 1, 1, 1], [2, 3, 3, 3, 3, 3, 3, 1],
                           [0, 2, 3, 3, 3, 3, 1, 3], [0, 2, 3, 3, 3, 3, 1, 3],
                           [0, 0, 2, 3, 3, 1, 3, 3], [0, 0, 2, 3, 3, 1, 3, 3],
                           [0, 0, 0, 2, 1, 3, 3, 3], [0, 0, 0, 2, 1, 3, 3, 3],
                           [0, 0, 0, 1, 2, 3, 3, 3], [0, 0, 0, 1, 2, 3, 3, 3],
                           [0, 0, 1, 0, 0, 2, 3, 3], [0, 0, 1, 0, 0, 2, 3, 3],
                           [0, 1, 0, 0, 0, 0, 2, 3], [0, 1, 0, 0, 0, 0, 2, 3],
                           [1, 0, 0, 0, 0, 0, 0, 2], [1, 0, 0, 0, 0, 0, 0, 2]])
        assert_list_equal(tileset[4],
                          [[3] * 8, [3] * 8, [3] * 8, [3] * 8, [3] * 8,
                           [3, 2, 3, 3, 3, 2, 3, 3], [3] * 8, [3] * 8,
                           [3, 3, 3, 3, 3, 3, 3, 2], [2, 3, 3, 3, 3, 3, 2, 3],
                           [3, 2, 3, 3, 3, 2, 2, 3], [3, 2, 2, 2, 2, 2, 3, 3],
                           [3] * 8, [3] * 8, [3] * 8, [3] * 8])
Exemplo n.º 12
0
    def test_from_image_single_subpalette(self):
        palette = EbPalette(1, 2)
        tileset = EbGraphicTileset(num_tiles=6, tile_width=8, tile_height=8)
        arrangement = EbTileArrangement(width=6, height=1)
        arrangement.from_image(self.tile_8x8_2bpp_2_img,
                               tileset=tileset,
                               palette=palette)

        assert_equal(palette[0, 0], EbColor(0, 0, 0))
        assert_equal(palette[0, 1], EbColor(0xf8, 0xf8, 0xf8))

        item = arrangement[0, 0]
        assert_equal(item.subpalette, 0)

        assert_equal(arrangement[1, 0].tile, item.tile)
        assert_equal(arrangement[1, 0].is_horizontally_flipped,
                     not item.is_horizontally_flipped)
        assert_equal(arrangement[1, 0].is_vertically_flipped,
                     item.is_vertically_flipped)
        assert_equal(arrangement[1, 0].subpalette, 0)

        assert_equal(arrangement[2, 0].tile, item.tile)
        assert_equal(arrangement[2, 0].is_horizontally_flipped,
                     item.is_horizontally_flipped)
        assert_equal(arrangement[2, 0].is_vertically_flipped,
                     not item.is_vertically_flipped)
        assert_equal(arrangement[2, 0].subpalette, 0)

        assert_equal(arrangement[3, 0].tile, item.tile)
        assert_equal(arrangement[3, 0].is_horizontally_flipped,
                     not item.is_horizontally_flipped)
        assert_equal(arrangement[2, 0].is_vertically_flipped,
                     not item.is_vertically_flipped)
        assert_equal(arrangement[3, 0].subpalette, 0)

        assert_not_equal(arrangement[4, 0].tile, item.tile)
        assert_equal(arrangement[4, 0].subpalette, 0)

        assert_equal(arrangement[5, 0].tile, item.tile)
        assert_equal(arrangement[5, 0].is_horizontally_flipped,
                     item.is_horizontally_flipped)
        assert_equal(arrangement[5, 0].is_vertically_flipped,
                     item.is_vertically_flipped)
        assert_equal(arrangement[5, 0].subpalette, 0)
Exemplo n.º 13
0
    def read_from_project(self, resource_open):
        with resource_open("bg_data_table", "yml", True) as f:
            self.bg_table.from_yml_file(f)
        with resource_open("bg_scrolling_table", "yml", True) as f:
            self.scroll_table.from_yml_file(f)
        with resource_open("bg_distortion_table", "yml", True) as f:
            self.distortion_table.from_yml_file(f)

        self.backgrounds = []
        self.palettes = []
        for i in range(self.bg_table.num_rows):
            new_color_depth = self.bg_table[i][2]
            with resource_open("BattleBGs/" + str(i).zfill(3), "png") as f:
                image = open_indexed_image(f)

                new_palette = EbPalette(num_subpalettes=1,
                                        subpalette_length=16)
                new_tileset = EbGraphicTileset(num_tiles=512,
                                               tile_width=8,
                                               tile_height=8)
                new_arrangement = EbTileArrangement(width=32, height=32)

                new_arrangement.from_image(image, new_tileset, new_palette)

                for j, (tileset, color_depth,
                        arrangement) in enumerate(self.backgrounds):
                    if (color_depth == new_color_depth) \
                            and (tileset == new_tileset) \
                            and (arrangement == new_arrangement):
                        self.bg_table[i][0] = j
                        break
                else:
                    self.bg_table[i][0] = len(self.backgrounds)
                    self.backgrounds.append(
                        (new_tileset, new_color_depth, new_arrangement))

                for j, palette in enumerate(self.palettes):
                    if palette == new_palette:
                        self.bg_table[i][1] = j
                        break
                else:
                    self.bg_table[i][1] = len(self.palettes)
                    self.palettes.append(new_palette)
Exemplo n.º 14
0
    def __init__(self, frames, unknown, graphics_data_size=None):
        self.graphics_data_size = graphics_data_size
        self.frames = frames
        self.unknown = unknown

        if graphics_data_size:
            num_tiles = EbGraphicTileset.tiles_from_parameters(
                graphics_data_size, TILE_WIDTH, TILE_HEIGHT, TILE_BPP)
        else:  # Make tileset with maximum number of tiles possible for each frame of animation
            num_tiles = SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES * frames

        # Animations are 2 bpp, so the palette will have 4 colors
        self.palette = EbPalette(num_subpalettes=1, subpalette_length=4)
        self.graphics = EbGraphicTileset(num_tiles=num_tiles,
                                         tile_width=TILE_WIDTH,
                                         tile_height=TILE_HEIGHT)
        self.arrangements = [
            EbTileArrangement(width=SCREEN_WIDTH_TILES,
                              height=SCREEN_HEIGHT_TILES)
            for i in range(self.frames)
        ]
Exemplo n.º 15
0
    def read_chars_data_from_project(self, resource_open):
        # Read the characters positions
        with resource_open(CHARS_POSITIONS_PATH, "yml") as f:
            chars_positions = yml_load(f)

        # Read the characters animated frames
        self.chars_tileset = None
        self.chars_anim_palette = EbPalette(CHARS_NUM_ANIM_SUBPALETTES,
                                            ANIM_SUBPALETTE_LENGTH)
        original_tileset = None
        for p in xrange(CHARS_NUM_ANIM_SUBPALETTES):
            # Read one of the animation frames
            with resource_open(CHARS_FRAMES_PATH.format(p), "png") as f:
                # Create temporary structures to hold the data
                image = open_indexed_image(f)
                arrangement = EbTileArrangement(image.width / TILE_WIDTH,
                                                image.height / TILE_HEIGHT)
                tileset = EbGraphicTileset(CHARS_NUM_TILES, TILE_WIDTH,
                                           TILE_HEIGHT)
                anim_subpalette = EbPalette(NUM_SUBPALETTES,
                                            ANIM_SUBPALETTE_LENGTH)
                arrangement.from_image(image, tileset, anim_subpalette, True)

            # Add the characters animation subpalette
            for i in xrange(ANIM_SUBPALETTE_LENGTH):
                self.chars_anim_palette[p, i] = anim_subpalette[0, i]

            # Add the characters tileset if not already set, otherwise
            # ensure that it the current tileset is identical
            if not self.chars_tileset:
                original_tileset = tileset
                self.chars_tileset = EbGraphicTileset(CHARS_NUM_TILES,
                                                      TILE_WIDTH, TILE_HEIGHT)
                self.chars_tileset.tiles = [[[0 for _ in xrange(TILE_HEIGHT)]
                                             for _ in xrange(TILE_WIDTH)]
                                            for _ in xrange(CHARS_NUM_TILES)]
                unused_tiles = set(xrange(CHARS_NUM_TILES))

                # Set the new character layouts
                self.chars_layouts = [[] for _ in xrange(NUM_CHARS)]
                for c, data in chars_positions.items():
                    # Get the data from the YAML file
                    x = int(data['x'] / TILE_WIDTH)
                    y = int(data['y'] / TILE_HEIGHT)
                    width = int(data['width'] / TILE_WIDTH)
                    height = int(data['height'] / TILE_HEIGHT)
                    x_offset = data['top_left_offset']['x']
                    y_offset = data['top_left_offset']['y']
                    unknown = data['unknown']

                    # Generate a list of all tiles must be visited
                    # Where possible, we try to generate a multi tile (4 tiles
                    # stored as one); otherwise, bordering tiles that are
                    # visited will all be single tiles.
                    l = [(i, j) for i in xrange(0, width, 2)
                         for j in xrange(0, height, 2)]
                    if width % 2 == 1:
                        l.extend([(width - 1, j)
                                  for j in xrange(1, height, 2)])
                    if height % 2 == 1:
                        l.extend([(i, height - 1)
                                  for i in xrange(1, width, 2)])

                    # Generate the new reduced tileset
                    for i, j in l:
                        # Put the tile in the new tileset
                        o_tile = arrangement[x + i, y + j].tile
                        n_tile = unused_tiles.pop()
                        self.chars_tileset.tiles[n_tile] = tileset[o_tile]

                        entry = TitleScreenLayoutEntry(i * 8 + x_offset,
                                                       j * 8 + y_offset,
                                                       n_tile, 0, unknown)

                        # Create a multi entry if possible to save space
                        if i < width - 1 and j < height - 1:
                            entry.set_single(True)
                            o_tile_r = arrangement[x + i + 1, y + j].tile
                            o_tile_d = arrangement[x + i, y + j + 1].tile
                            o_tile_dr = arrangement[x + i + 1, y + j + 1].tile
                            n_tile_r = n_tile + 1
                            n_tile_d = n_tile + 16
                            n_tile_dr = n_tile + 17
                            unused_tiles.difference_update(
                                (n_tile_r, n_tile_d, n_tile_dr))
                            self.chars_tileset.tiles[n_tile_r] = \
                                tileset[o_tile_r]
                            self.chars_tileset.tiles[n_tile_d] = \
                                tileset[o_tile_d]
                            self.chars_tileset.tiles[n_tile_dr] = \
                                tileset[o_tile_dr]

                        self.chars_layouts[c].append(entry)
                    self.chars_layouts[c][-1].set_final(True)

            elif original_tileset != tileset:
                log.warn("Tileset from characters frame {} does not match "
                         "tileset from characters frame 0.".format(p))

        # Read the initial characters palette
        with resource_open(CHARS_INITIAL_PATH, "png") as f:
            image = open_indexed_image(f)
            arrangement = EbTileArrangement(image.width / TILE_WIDTH,
                                            image.height / TILE_HEIGHT)
            tileset = EbGraphicTileset(CHARS_NUM_TILES, TILE_WIDTH,
                                       TILE_HEIGHT)
            self.chars_palette = EbPalette(NUM_SUBPALETTES,
                                           ANIM_SUBPALETTE_LENGTH)
            arrangement.from_image(image, tileset, self.chars_palette)
Exemplo n.º 16
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
Exemplo n.º 17
0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 3, 3, 6,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 6,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0
]
ARRANGEMENT_1 = EbTileArrangement(width=16, height=26)
for y in range(ARRANGEMENT_1.height):
    for x in range(ARRANGEMENT_1.width):
        i = y * ARRANGEMENT_1.width + x
        ARRANGEMENT_1[x, y].tile = i
        ARRANGEMENT_1[x, y].subpalette = ARRANGEMENT_PREVIEW_SUBPALETTES[i]
ARRANGEMENT_2 = EbTileArrangement(width=7, height=1)
for y in range(ARRANGEMENT_2.height):
    for x in range(ARRANGEMENT_2.width):
        ARRANGEMENT_2[x, y].tile = y * ARRANGEMENT_1.width + x
        ARRANGEMENT_2[x, y].subpalette = 0


class WindowGraphicsModule(EbModule):
    NAME = "Window Graphics"
    FREE_RANGES = [(0x200000, 0x20079f)]  # Graphics
Exemplo n.º 18
0
TOWN_MAP_ICON_PREVIEW_SUBPALETTES = [
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0,
    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
TOWN_MAP_ICON_PREVIEW_ARRANGEMENT = EbTileArrangement(width=16, height=18)
for i in range(16 * 18):
    item = TOWN_MAP_ICON_PREVIEW_ARRANGEMENT[i % 16, i // 16]
    item.is_priority = False
    item.is_horizontally_flipped = False
    item.is_vertically_flipped = False
    item.subpalette = TOWN_MAP_ICON_PREVIEW_SUBPALETTES[i]
    item.tile = i


class CompressedGraphicsModule(EbModule):
    NAME = "Compressed Graphics"
    FREE_RANGES = [
        (0x2021a8, 0x20ed02),  # Town Map data
        (0x214ec1, 0x21ae7b
         ),  # Company Logos, "Produced by" and "Presented by", and Gas Station
Exemplo n.º 19
0
from coilsnake.model.eb.blocks import EbCompressibleBlock
from coilsnake.model.eb.graphics import EbTileArrangement, EbGraphicTileset
from coilsnake.model.eb.palettes import EbPalette
from coilsnake.util.common.image import open_indexed_image
from coilsnake.util.common.yml import yml_load, yml_dump
from coilsnake.util.eb.pointer import from_snes_address, read_asm_pointer, write_asm_pointer, to_snes_address


FONT_IMAGE_PALETTE = EbPalette(1, 2)
FONT_IMAGE_PALETTE[0, 0].from_tuple((255, 255, 255))
FONT_IMAGE_PALETTE[0, 1].from_tuple((0, 0, 0))
FONT_IMAGE_ARRANGEMENT_WIDTH = 16
_FONT_IMAGE_ARRANGEMENT_96 = EbTileArrangement(width=FONT_IMAGE_ARRANGEMENT_WIDTH, height=6)
_FONT_IMAGE_ARRANGEMENT_128 = EbTileArrangement(width=FONT_IMAGE_ARRANGEMENT_WIDTH, height=8)

for y in range(_FONT_IMAGE_ARRANGEMENT_96.height):
    for x in range(_FONT_IMAGE_ARRANGEMENT_96.width):
        _FONT_IMAGE_ARRANGEMENT_96[x, y].tile = y * _FONT_IMAGE_ARRANGEMENT_96.width + x
for y in range(_FONT_IMAGE_ARRANGEMENT_128.height):
    for x in range(_FONT_IMAGE_ARRANGEMENT_128.width):
        _FONT_IMAGE_ARRANGEMENT_128[x, y].tile = y * _FONT_IMAGE_ARRANGEMENT_128.width + x


class EbFont(object):
    def __init__(self, num_characters=96, tile_width=16, tile_height=8):
        self.num_characters = num_characters
        self.tileset = EbGraphicTileset(num_tiles=num_characters, tile_width=tile_width, tile_height=tile_height)
        self.character_widths = None

    def from_block(self, block, tileset_offset, character_widths_offset):
        self.tileset.from_block(block=block, offset=tileset_offset, bpp=1)
Exemplo n.º 20
0
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3],
                           [5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1],
                           [5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1]]

SOUND_STONE_ARRANGEMENT = EbTileArrangement(width=16, height=22)
for y in range(SOUND_STONE_ARRANGEMENT.height):
    for x in range(SOUND_STONE_ARRANGEMENT.width):
        SOUND_STONE_ARRANGEMENT[x,
                                y].tile = y * SOUND_STONE_ARRANGEMENT.width + x
        SOUND_STONE_ARRANGEMENT[x,
                                y].subpalette = SOUND_STONE_SUBPALETTES[y][x]


class SoundStoneModule(EbModule):
    NAME = "Sound Stone"
    FREE_RANGES = [(0x0EDD5D, 0x0EF805)]  # Sound stone graphics

    def __init__(self):
        super(SoundStoneModule, self).__init__()
        self.tileset = EbGraphicTileset(num_tiles=352,