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)]
def from_yml_rep(cls, yml_rep): palette = EbPalette(num_subpalettes=1, subpalette_length=(cls.size // 2)) try: palette.from_yml_rep(yml_rep) except InvalidYmlRepresentationError as e: raise TableEntryInvalidYmlRepresentationError(str(e)) return palette
def read_gfx_from_project(self, obj, resource_open): with resource_open(obj.path(), 'png') as image_file: image = open_indexed_image(image_file) palette = EbPalette(num_subpalettes=1, subpalette_length=4) palette.from_image(image) obj.palettes[0] = palette obj.from_image(image, obj.cast_arrangement())
def __init__(self): super(WindowGraphicsModule, self).__init__() self.graphics_1 = EbGraphicTileset(num_tiles=416, tile_width=8, tile_height=8) self.graphics_2 = EbGraphicTileset(num_tiles=7, tile_width=8, tile_height=8) self.flavor_palettes = [EbPalette(8, 4) for i in range(7)] self.flavor_names = dict()
def write_background_data_to_project(self, resource_open): # Write out the reference background image # This image is used to get the arrangement, tileset and static palette # that will be used by all background images. with resource_open( BG_REFERENCE_PATH, "png" ) as f: image = self.bg_arrangement.image(self.bg_tileset, self.bg_palette) image.save(f) # Write out the background's animated frames for frame in range(NUM_ANIM_FRAMES): palette = EbPalette(NUM_SUBPALETTES, BG_SUBPALETTE_LENGTH) if frame < CHARS_NUM_ANIM_SUBPALETTES: palette[0, CHARS_ANIM_SLICE] = \ self.chars_anim_palette.get_subpalette(frame)[0, :] else: palette[0, :] = self.bg_palette.get_subpalette(0)[0, :] palette[0, BG_ANIM_SLICE] = \ self.bg_anim_palette.get_subpalette( frame - CHARS_NUM_ANIM_SUBPALETTES )[0, :] with resource_open(BG_FRAMES_PATH.format(frame), "png") as f: image = self.bg_arrangement.image(self.bg_tileset, palette) image.save(f)
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]])
def __init__(self, num_tiles, tile_width, tile_height, bpp, arrangement_width, arrangement_height, num_palettes, num_subpalettes, subpalette_length, compressed_palettes=True): self.bpp = bpp self.compressed_palettes = compressed_palettes self.graphics = EbGraphicTileset(num_tiles=num_tiles, tile_width=tile_width, tile_height=tile_height) if arrangement_width and arrangement_height: self.arrangement = EbTileArrangement(width=arrangement_width, height=arrangement_height) else: self.arrangement = None self.palettes = [ EbPalette(num_subpalettes=num_subpalettes, subpalette_length=subpalette_length) for x in range(num_palettes) ]
def read_from_project(self, resource_open): with resource_open("sprite_group_palettes", "yml") as f: self.palette_table.from_yml_file(f) with resource_open("sprite_groups", "yml") as f: input = yml_load(f) num_groups = len(input) self.groups = [] for i in range(num_groups): group = SpriteGroup(16) group.from_yml_rep(input[i]) palette = EbPalette(1, 16) with resource_open("SpriteGroups/" + str(i).zfill(3), "png") as f2: image = open_indexed_image(f2) group.from_image(image) palette.from_image(image) del image self.groups.append(group) # Assign the palette number to the sprite for j in range(8): if palette.list()[3:] == self.palette_table[j][0].list( )[3:]: group.palette = j break else: raise CoilSnakeError("Sprite Group #" + str(i).zfill(3) + " uses an invalid palette")
def test_8x8_2colors_1subpaletteof2(self): return eb_palette = EbPalette(num_subpalettes=1, subpalette_length=2) setup_eb_palette_from_image(eb_palette, self.tile_8x8_2bpp_img, 8, 8) assert_equal(eb_palette.num_subpalettes, 1) assert_equal(eb_palette.subpalette_length, 2) assert_equal(eb_palette[0, 0].tuple(), (0xf8, 0xf8, 0xf8)) assert_equal(eb_palette[0, 1].tuple(), (0, 0, 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)
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)
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) )
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)
def test_extra_colors(self): return eb_palette = EbPalette(num_subpalettes=3, subpalette_length=4) setup_eb_palette_from_image(eb_palette, self.tile_8x8_2bpp_img, 8, 8) assert_equal(eb_palette.num_subpalettes, 3) assert_equal(eb_palette.subpalette_length, 4) assert_equal(eb_palette[0, 0].tuple(), (0xf8, 0xf8, 0xf8)) assert_equal(eb_palette[0, 1].tuple(), (0, 0, 0)) assert_equal(eb_palette[0, 2].tuple(), (0, 0, 0)) assert_equal(eb_palette[0, 3].tuple(), (0, 0, 0)) assert_equal(eb_palette[1, 0].tuple(), (0, 0, 0)) assert_equal(eb_palette[1, 1].tuple(), (0, 0, 0)) assert_equal(eb_palette[1, 2].tuple(), (0, 0, 0)) assert_equal(eb_palette[1, 3].tuple(), (0, 0, 0)) assert_equal(eb_palette[2, 0].tuple(), (0, 0, 0)) assert_equal(eb_palette[2, 1].tuple(), (0, 0, 0)) assert_equal(eb_palette[2, 2].tuple(), (0, 0, 0)) assert_equal(eb_palette[2, 3].tuple(), (0, 0, 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])
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)
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)
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)
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) ]
def test_8x8_5colors_2subpalettesof4(self): return eb_palette = EbPalette(num_subpalettes=2, subpalette_length=4) setup_eb_palette_from_image(eb_palette, self.tile_8x8_2bpp_3_img, 8, 8) assert_equal(eb_palette.num_subpalettes, 2) assert_equal(eb_palette.subpalette_length, 4) assert_set_equal({eb_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({eb_palette[0, i] for i in range(4)}, { EbColor(24, 0, 248), EbColor(0, 248, 24), EbColor(216, 248, 0), EbColor(152, 0, 248) })
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
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)
def from_block(cls, block, offset): palette = EbPalette(num_subpalettes=1, subpalette_length=(cls.size // 2)) palette.from_block(block, offset) return palette
from PIL import Image, ImageDraw from coilsnake.exceptions.common.exceptions import InvalidArgumentError from coilsnake.model.common.blocks import Block from coilsnake.model.eb.palettes import EbPalette from coilsnake.util.common.type import EqualityMixin SWIRL_IMAGE_PALETTE = EbPalette(num_subpalettes=1, subpalette_length=2, rgb_list=[255, 255, 255, 0, 0, 0]) class SwirlFrameRow(EqualityMixin): def __init__(self, x1=0, x2=0, x3=0, x4=0): self.set(x1, x2, x3, x4) def set(self, x1, x2, x3, x4): self.x1 = x1 self.x2 = x2 self.x3 = x3 self.x4 = x4 def from_block(self, block, offset, is_mode_01): self.x1 = block[offset] self.x2 = block[offset + 1] if is_mode_01: self.x3 = 0xff self.x4 = 0 else: self.x3 = block[offset + 2] self.x4 = block[offset + 3]
def read_from_project(self, resource_open): with resource_open("enemy_configuration_table", "yml") as f: self.enemy_config_table.from_yml_file(f) # Read the sprites and palettes self.battle_sprites = [] self.palettes = [] sprite_hashes = dict() num_sprites = 0 palette_hashes = dict() num_palettes = 0 for i in range(self.enemy_config_table.num_rows): battle_sprite = EbBattleSprite() palette = EbPalette(num_subpalettes=1, subpalette_length=16) try: with resource_open("BattleSprites/" + str(i).zfill(3), "png") as f: image = open_indexed_image(f) battle_sprite.from_image(image) palette.from_image(image) del image except IOError: # No battle sprite self.enemy_config_table[i][4] = 0 self.enemy_config_table[i][14] = 0 continue sprite_hash = battle_sprite.hash() try: self.enemy_config_table[i][4] = sprite_hashes[sprite_hash] + 1 except KeyError: self.enemy_config_table[i][4] = num_sprites + 1 sprite_hashes[sprite_hash] = num_sprites self.battle_sprites.append(battle_sprite) num_sprites += 1 palette_hash = palette.hash() try: self.enemy_config_table[i][14] = palette_hashes[palette_hash] except KeyError: self.enemy_config_table[i][14] = num_palettes palette_hashes[palette_hash] = num_palettes self.palettes.append(palette) num_palettes += 1 # Read the groups with resource_open("enemy_groups", "yml") as f: self.enemy_group_table.from_yml_file(f) with resource_open("enemy_groups", "yml") as f: self.enemy_group_bg_table.from_yml_file(f) with resource_open("enemy_groups", "yml") as f: self.enemy_groups = [] enemy_groups_yml_rep = yml_load(f) for entry in enemy_groups_yml_rep.itervalues(): enemy_group = entry["Enemies"] if type(enemy_group) == dict: enemy_group = [enemy_group[x] for x in sorted(enemy_group.keys())] group = [EnemyGroupTableEntry.from_yml_rep(x) for x in enemy_group] self.enemy_groups.append(group)
def test_cant_fit_colors_2(self): eb_palette = EbPalette(num_subpalettes=1, subpalette_length=4) setup_eb_palette_from_image(eb_palette, self.tile_8x8_2bpp_3_img, 8, 8)
def setup(self): super(TestEbPalette, self).setup() self.palette = EbPalette(2, 3)
def __init__(self): self.tileset = EbGraphicTileset(num_tiles=192, tile_width=8, tile_height=8) self.palette = EbPalette(num_subpalettes=2, subpalette_length=4)
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)
def __init__(self): super(SoundStoneModule, self).__init__() self.tileset = EbGraphicTileset(num_tiles=352, tile_width=8, tile_height=8) self.palette = EbPalette(num_subpalettes=6, subpalette_length=16)