class EbCreditsFont(object): def __init__(self): self.tileset = EbGraphicTileset(num_tiles=192, tile_width=8, tile_height=8) self.palette = EbPalette(num_subpalettes=2, subpalette_length=4) 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) def to_block(self, block, tileset_asm_pointer_offset, palette_offset): tileset_block_size = self.tileset.block_size(bpp=2) with EbCompressibleBlock(tileset_block_size) as compressed_block: self.tileset.to_block(block=compressed_block, offset=0, bpp=2) compressed_block.compress() tileset_offset = block.allocate(data=compressed_block) write_asm_pointer(block=block, offset=tileset_asm_pointer_offset, pointer=to_snes_address(tileset_offset)) self.palette.to_block(block=block, offset=palette_offset) def to_files(self, image_file, image_format="png"): image = _CREDITS_PREVIEW_ARRANGEMENT.image(self.tileset, self.palette) image.save(image_file, image_format) del image def from_files(self, image_file, image_format="png"): image = open_indexed_image(image_file) self.palette.from_image(image) self.tileset.from_image(image, _CREDITS_PREVIEW_ARRANGEMENT, self.palette) del image
def read_from_project(self, resource_open): with resource_open("sprite_group_palettes", "yml", True) as f: self.palette_table.from_yml_file(f) with resource_open("sprite_groups", "yml", True) 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() == self.palette_table[j][0].list(): group.palette = j break else: raise CoilSnakeError("Sprite Group #" + str(i).zfill(3) + " uses an invalid palette")
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 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())
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, tile_width=8, tile_height=8) self.palette = EbPalette(num_subpalettes=6, subpalette_length=16) 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): tileset_block_size = self.tileset.block_size(bpp=4) with EbCompressibleBlock(tileset_block_size) as compressed_block: self.tileset.to_block(block=compressed_block, offset=0, bpp=4) compressed_block.compress() tileset_offset = rom.allocate(data=compressed_block) write_asm_pointer(block=rom, offset=GRAPHICS_ASM_POINTER_OFFSET, pointer=to_snes_address(tileset_offset)) self.palette.to_block(block=rom, offset=PALETTE_OFFSET) def read_from_project(self, resource_open): with resource_open("Logos/SoundStone", "png") as image_file: image = open_indexed_image(image_file) self.palette.from_image(image) self.tileset.from_image(image, SOUND_STONE_ARRANGEMENT, self.palette) def write_to_project(self, resource_open): image = SOUND_STONE_ARRANGEMENT.image(self.tileset, self.palette) with resource_open("Logos/SoundStone", "png") as image_file: image.save(image_file, "png") def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete): if old_version < 8: self.read_from_rom(rom) self.write_to_project(resource_open_w)
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, tile_width=8, tile_height=8) self.palette = EbPalette(num_subpalettes=6, subpalette_length=16) 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): tileset_block_size = self.tileset.block_size(bpp=4) with EbCompressibleBlock(tileset_block_size) as compressed_block: self.tileset.to_block(block=compressed_block, offset=0, bpp=4) compressed_block.compress() tileset_offset = rom.allocate(data=compressed_block) write_asm_pointer(block=rom, offset=GRAPHICS_ASM_POINTER_OFFSET, pointer=to_snes_address(tileset_offset)) self.palette.to_block(block=rom, offset=PALETTE_OFFSET) def read_from_project(self, resource_open): with resource_open("Logos/SoundStone", "png") as image_file: image = open_indexed_image(image_file) self.palette.from_image(image) self.tileset.from_image(image, SOUND_STONE_ARRANGEMENT, self.palette) def write_to_project(self, resource_open): image = SOUND_STONE_ARRANGEMENT.image(self.tileset, self.palette) with resource_open("Logos/SoundStone", "png") as image_file: image.save(image_file, "png") def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete): if old_version < 8: self.read_from_rom(rom) self.write_to_project(resource_open_w)
class TestEbPalette(BaseTestCase, TilesetImageTestCase): def setup(self): super(TestEbPalette, self).setup() self.palette = EbPalette(2, 3) def test_init(self): assert_equal(self.palette.num_subpalettes, 2) assert_equal(self.palette.subpalette_length, 3) def test_init_invalid(self): assert_raises(InvalidArgumentError, EbPalette, 0, 1) assert_raises(InvalidArgumentError, EbPalette, -1, 1) assert_raises(InvalidArgumentError, EbPalette, 1, 0) assert_raises(InvalidArgumentError, EbPalette, 1, -1) assert_raises(InvalidArgumentError, EbPalette, 0, 0) assert_raises(InvalidArgumentError, EbPalette, -1, -1) def test_num_colors(self): assert_equal(self.palette.num_colors(), 6) def test_getitem(self): assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (0, 0, 0)) self.palette[0, 1].from_tuple((8, 16, 32)) assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (8, 16, 32)) def test_getitem_invalid(self): assert_raises(InvalidArgumentError, self.palette.__getitem__, (-1, 0)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (0, -1)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (-1, -1)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (2, 0)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (0, 3)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (2, 3)) def test_from_list(self): self.palette.from_list([ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (40, 8, 72)) assert_equal(self.palette[0, 2].tuple(), (80, 88, 48)) assert_equal(self.palette[1, 0].tuple(), (248, 0, 0)) assert_equal(self.palette[1, 1].tuple(), (80, 56, 40)) assert_equal(self.palette[1, 2].tuple(), (16, 136, 136)) def test_to_list(self): self.palette[0, 0].from_tuple((0, 0, 0)) self.palette[0, 1].from_tuple((40, 8, 72)) self.palette[0, 2].from_tuple((80, 88, 48)) self.palette[1, 0].from_tuple((248, 0, 0)) self.palette[1, 1].from_tuple((80, 56, 40)) self.palette[1, 2].from_tuple((16, 136, 136)) assert_list_equal(self.palette.list(), [0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136]) def test_from_block(self): block = Block() block.from_list([0, 0, 37, 36, 106, 25, 31, 0, 234, 20, 34, 70]) self.palette.from_block(block) assert_list_equal(self.palette.list(), [ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) def test_to_block(self): self.palette.from_list([ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) block = Block() block.from_list([0xff] * 50) self.palette.to_block(block, offset=1) assert_list_equal(block[0:14].to_list(), [0xff, 0, 0, 37, 36, 106, 25, 31, 0, 234, 20, 34, 70, 0xff]) def test_from_image(self): self.palette.from_image(self.tile_image_01_img) assert_list_equal(self.palette.list(), [0x00, 0x00, 0x00, 0x08, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xc0, 0xf8, 0x00, 0xf8, 0xf8, 0xf8]) def test_to_image(self): image = Image.new('P', (10, 10)) self.palette[0, 0].from_tuple((0, 0, 0)) self.palette[0, 1].from_tuple((40, 8, 72)) self.palette[0, 2].from_tuple((80, 88, 48)) self.palette[1, 0].from_tuple((248, 0, 0)) self.palette[1, 1].from_tuple((80, 56, 40)) self.palette[1, 2].from_tuple((16, 136, 136)) self.palette.to_image(image) assert_list_equal(image.getpalette()[0:(self.palette.num_colors() * 3)], [0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136]) del image def test_add_colors_to_subpalette_single_color(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) for i in range(self.palette.num_subpalettes): for j in range(self.palette.subpalette_length): if (i, j) not in [(1, 0)]: assert_false(self.palette[i, j].used) def test_add_colors_to_subpalette_shared_colors(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16), EbColor(r=128, g=0, b=16)]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) assert_equal(self.palette[1, 1].tuple(), (128, 0, 16)) assert_true(self.palette[1, 1].used) for i in range(self.palette.num_subpalettes): for j in range(self.palette.subpalette_length): if (i, j) not in [(1, 0), (1, 1)]: assert_false(self.palette[i, j].used) def test_add_colors_to_subpalette_shared_colors2(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16), EbColor(r=128, g=0, b=16)]) self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16), EbColor(r=16, g=32, b=64), EbColor(r=32, g=32, b=32)]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) assert_equal(self.palette[1, 1].tuple(), (128, 0, 16)) assert_true(self.palette[1, 1].used) assert_false(self.palette[1, 2].used) assert_equal(set([self.palette[0, x].tuple() for x in range(self.palette.subpalette_length)]), set([(64, 32, 16), (16, 32, 64), (32, 32, 32)])) assert_equal([self.palette[0, x].used for x in range(self.palette.subpalette_length)].count(True), 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)
class TestEbPalette(BaseTestCase, TilesetImageTestCase): def setup(self): super(TestEbPalette, self).setup() self.palette = EbPalette(2, 3) def test_init(self): assert_equal(self.palette.num_subpalettes, 2) assert_equal(self.palette.subpalette_length, 3) def test_init_invalid(self): assert_raises(InvalidArgumentError, EbPalette, 0, 1) assert_raises(InvalidArgumentError, EbPalette, -1, 1) assert_raises(InvalidArgumentError, EbPalette, 1, 0) assert_raises(InvalidArgumentError, EbPalette, 1, -1) assert_raises(InvalidArgumentError, EbPalette, 0, 0) assert_raises(InvalidArgumentError, EbPalette, -1, -1) def test_num_colors(self): assert_equal(self.palette.num_colors(), 6) def test_getitem(self): assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (0, 0, 0)) self.palette[0, 1].from_tuple((8, 16, 32)) assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (8, 16, 32)) def test_getitem_invalid(self): assert_raises(InvalidArgumentError, self.palette.__getitem__, (-1, 0)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (0, -1)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (-1, -1)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (2, 0)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (0, 3)) assert_raises(InvalidArgumentError, self.palette.__getitem__, (2, 3)) def test_from_list(self): self.palette.from_list([ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) assert_equal(self.palette[0, 0].tuple(), (0, 0, 0)) assert_equal(self.palette[0, 1].tuple(), (40, 8, 72)) assert_equal(self.palette[0, 2].tuple(), (80, 88, 48)) assert_equal(self.palette[1, 0].tuple(), (248, 0, 0)) assert_equal(self.palette[1, 1].tuple(), (80, 56, 40)) assert_equal(self.palette[1, 2].tuple(), (16, 136, 136)) def test_to_list(self): self.palette[0, 0].from_tuple((0, 0, 0)) self.palette[0, 1].from_tuple((40, 8, 72)) self.palette[0, 2].from_tuple((80, 88, 48)) self.palette[1, 0].from_tuple((248, 0, 0)) self.palette[1, 1].from_tuple((80, 56, 40)) self.palette[1, 2].from_tuple((16, 136, 136)) assert_list_equal(self.palette.list(), [ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) def test_from_block(self): block = Block() block.from_list([0, 0, 37, 36, 106, 25, 31, 0, 234, 20, 34, 70]) self.palette.from_block(block) assert_list_equal(self.palette.list(), [ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) def test_to_block(self): self.palette.from_list([ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) block = Block() block.from_list([0xff] * 50) self.palette.to_block(block, offset=1) assert_list_equal( block[0:14].to_list(), [0xff, 0, 0, 37, 36, 106, 25, 31, 0, 234, 20, 34, 70, 0xff]) def test_from_image(self): self.palette.from_image(self.tile_image_01_img) assert_list_equal(self.palette.list(), [ 0x00, 0x00, 0x00, 0x08, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xc0, 0xf8, 0x00, 0xf8, 0xf8, 0xf8 ]) def test_to_image(self): image = Image.new('P', (10, 10)) self.palette[0, 0].from_tuple((0, 0, 0)) self.palette[0, 1].from_tuple((40, 8, 72)) self.palette[0, 2].from_tuple((80, 88, 48)) self.palette[1, 0].from_tuple((248, 0, 0)) self.palette[1, 1].from_tuple((80, 56, 40)) self.palette[1, 2].from_tuple((16, 136, 136)) self.palette.to_image(image) assert_list_equal( image.getpalette()[0:(self.palette.num_colors() * 3)], [ 0, 0, 0, 40, 8, 72, 80, 88, 48, 248, 0, 0, 80, 56, 40, 16, 136, 136 ]) del image def test_add_colors_to_subpalette_single_color(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) for i in range(self.palette.num_subpalettes): for j in range(self.palette.subpalette_length): if (i, j) not in [(1, 0)]: assert_false(self.palette[i, j].used) def test_add_colors_to_subpalette_shared_colors(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) self.palette.add_colors_to_subpalette( [EbColor(r=64, g=32, b=16), EbColor(r=128, g=0, b=16)]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) assert_equal(self.palette[1, 1].tuple(), (128, 0, 16)) assert_true(self.palette[1, 1].used) for i in range(self.palette.num_subpalettes): for j in range(self.palette.subpalette_length): if (i, j) not in [(1, 0), (1, 1)]: assert_false(self.palette[i, j].used) def test_add_colors_to_subpalette_shared_colors2(self): self.palette.add_colors_to_subpalette([EbColor(r=64, g=32, b=16)]) self.palette.add_colors_to_subpalette( [EbColor(r=64, g=32, b=16), EbColor(r=128, g=0, b=16)]) self.palette.add_colors_to_subpalette([ EbColor(r=64, g=32, b=16), EbColor(r=16, g=32, b=64), EbColor(r=32, g=32, b=32) ]) assert_equal(self.palette[1, 0].tuple(), (64, 32, 16)) assert_true(self.palette[1, 0].used) assert_equal(self.palette[1, 1].tuple(), (128, 0, 16)) assert_true(self.palette[1, 1].used) assert_false(self.palette[1, 2].used) assert_equal( set([ self.palette[0, x].tuple() for x in range(self.palette.subpalette_length) ]), set([(64, 32, 16), (16, 32, 64), (32, 32, 32)])) assert_equal([ self.palette[0, x].used for x in range(self.palette.subpalette_length) ].count(True), 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)