Beispiel #1
0
    def __init__(self, filename):
        filename = os.path.join(DATA_DIR, filename)
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        self.name = os.path.splitext(name)[0]

        self.outdir = os.path.join(DATA_DIR, 'mfas')  # + self.name
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        self.x_size = 16
        self.y_size = 16

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1
Beispiel #2
0
    def __init__(self, filename):
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        if self.tiles:
            self.name, size = name.split('_')[:2]
            size = size.split(',')
            self.x_size = int(size[0])
            self.y_size = int(size[1])
        else:
            self.name = name.split('_')[0]

        self.outdir = os.path.splitext(filename)[0]
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1
Beispiel #3
0
    def __init__(self, filename):
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        if self.tiles:
            self.name, size = name.split('_')[:2]
            size = size.split(',')
            self.x_size = int(size[0])
            self.y_size = int(size[1])
        else:
            self.name = name.split('_')[0]

        self.outdir = os.path.splitext(filename)[0]
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1
Beispiel #4
0
    def __init__(self, filename):
        filename = os.path.join(DATA_DIR, filename)
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        self.name = os.path.splitext(name)[0]

        self.outdir = os.path.join(DATA_DIR, 'mfas')# + self.name
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        self.x_size = 16
        self.y_size = 16

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1
Beispiel #5
0
class Tiler(object):
    def __init__(self, filename):
        filename = os.path.join(DATA_DIR, filename)
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        self.name = os.path.splitext(name)[0]

        self.outdir = os.path.join(DATA_DIR, 'mfas')  # + self.name
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        self.x_size = 16
        self.y_size = 16

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1

    def run(self, cmd):
        self.room = ByteReader(open(self.filename, 'rb'))
        self.file_ver = self.room.readByte(True)
        self.x_size = self.room.readByte(True)
        self.y_size = self.room.readByte(True)
        tileset_len = self.room.readByte(True)
        self.tileset = self.room.readString(tileset_len)
        self.tile_count = self.room.readInt(True)

        image_path = os.path.join(SETS_PATH, '%s.png' % self.tileset)
        image = Image.open(image_path).convert('RGBA')

        col = image.getpixel((0, 0))
        self.tileset_transparent = col[:3]
        if col[3] == 255:
            print 'Filtering image with transparent color', col
            buf = image.load()
            for y in xrange(image.size[1]):
                for x in xrange(image.size[0]):
                    test_col = buf[(x, y)]
                    if test_col != col:
                        continue
                    buf[(x, y)] = (0, 0, 0, 0)

        frame = self.mfa.frames[0]

        if cmd == 'extract_tiles':
            self.run_extract_tiles(image)
            return
        elif cmd == 'build':
            self.run_build(image)

        frame.folders = []
        for item in frame.items:
            folder = frame.new(ItemFolder)
            folder.items = [item.handle]
            frame.folders.append(folder)

        basename = os.path.basename(self.filename)
        out_name = os.path.splitext(basename)[0] + '.mfa'
        out_path = os.path.join(self.outdir, out_name)

        if os.path.isfile(out_path):
            os.remove(out_path)
        self.mfa.write(ByteReader(open(out_path, 'wb')))
        print 'Created %s' % out_name

    def run_build(self, image):
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.tileset)
        mask = Image.open(mask_path)

        if mask.mode != 'P':
            raise ValueError('The mask has to be palette image')

        #mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        if transparent != 0:
            raise ValueError('The transparent color should be the first color '
                             'in the palette')

        buf = image.load()

        for (_, color) in colors:
            if color == transparent or color == 255:
                continue
            color_image = mask.point(lambda x: 1 if x == color else 0)
            box = color_image.getbbox()
            tile_x = box[0] / self.x_size
            tile_y = box[1] / self.y_size
            height = box[3] - box[1]
            width = box[2] - box[0]
            new_image = Image.new('RGBA', (width, height),
                                  self.tileset_transparent)

            buf2 = color_image.load()
            buf3 = new_image.load()

            for y in xrange(height):
                for x in xrange(width):
                    xx = x + box[0]
                    yy = y + box[1]
                    if buf2[(xx, yy)] == 0 or buf[(xx, yy)][3] == 0:
                        continue
                    buf3[(x, y)] = buf[(xx, yy)]

            obstacle = mask.getpixel((tile_x, tile_y)) == 255
            self.create_object("%s%s" % (self.tileset, color), color,
                               new_image, obstacle)

        room_width = 0
        room_height = 0
        instances = []
        map = dict()
        for _ in xrange(self.tile_count):
            try:
                x = self.room.readShort() * self.x_size
                y = self.room.readShort() * self.y_size
                room_width = max(room_width, x + 200)
                room_height = max(room_height, y + 200)
                key = self.room.readByte(True)
                frameitem = self.objects[key]
                instances.append((frameitem, x, y))
                map[(x, y)] = 1
            except:
                break

        for i in instances:
            self.create_instance(*i)
            #statt self.create_instance(i[0], i[1], i[2])

        frame = self.mfa.frames[0]
        frame.size = room_width, room_height

    def run_extract_tiles(self, image):
        tile_folder = sys.argv[3]

        image_path = os.path.join(SETS_PATH, '%s.png' % self.tileset)
        image = Image.open(image_path).convert('RGBA')
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.tileset)
        mask = Image.open(mask_path)
        transparent_color = image.getpixel((0, 0))

        if mask.mode != 'P':
            raise ValueError('The mask has to be palette image')

        #mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        if transparent != 0:
            raise ValueError('The transparent color should be the first color '
                             'in the palette')

        ini = open(os.path.join(DATA_DIR, tile_folder, 'tiles.ini'), 'w')
        for (_, color) in colors:
            if color == transparent:
                continue
            # Extract the current tile's shape from the mask image
            tile_mask = mask.point(lambda x: 1 if x == color else 0, '1')
            box = tile_mask.getbbox()
            tile_mask = tile_mask.crop(box)
            # Create an image and render the tile to it
            tile = Image.new('RGBA', tile_mask.size)
            tile.paste(image.crop(box), tile_mask)
            col = image.getpixel((0, 0))
            buf = tile.load()
            # Clear transparent pixels
            for y in xrange(tile.size[1]):
                for x in xrange(tile.size[0]):
                    if buf[(x, y)] == transparent_color:
                        buf[(x, y)] = (0, 0, 0, 0)
            tile.save(os.path.join(DATA_DIR, tile_folder, "%s.png" % color),
                      "PNG")

            x = box[0]
            y = box[1]
            height = box[3] - y
            width = box[2] - x
            tile_x = x / self.x_size
            tile_y = y / self.y_size

            if color == 25:
                print tile_x * self.x_size, x

            ini.write("[t%s]\n" % color)
            ini.write("x=%s\n" % x)
            ini.write("y=%s\n" % y)
            ini.write("x_off=%s\n" % (x - tile_x * self.x_size))
            ini.write("y_off=%s\n" % (y - tile_y * self.y_size))
            ini.write("width=%s\n" % width)
            ini.write("height=%s\n" % height)

        ini.write("[image]\n")
        ini.write("width=%s\n" % image.size[0])
        ini.write("height=%s\n" % image.size[1])
        ini.close()

    def create_instance(self, frameitem, x, y):
        frame = self.mfa.frames[0]
        instance = frame.new(FrameInstance)
        instance.x = x
        instance.y = y
        instance.handle = len(frame.instances) + 1
        instance.flags = 0
        instance.parentType = NONE_PARENT
        instance.itemHandle = frameitem.handle
        instance.parentHandle = 0
        instance.layer = 0
        frame.instances.append(instance)

    def create_image(self, image, icon):
        if icon:
            bank = self.mfa.icons
            handle = self.icon_id
            self.icon_id += 1
            image = image.resize((32, 32), Image.LANCZOS)
        else:
            bank = self.mfa.images
            handle = self.image_id
            self.image_id += 1

        item = bank.new(ImageItem, debug=True)
        item.handle = handle

        item.checksum = 123
        item.references = 0
        item.width = image.size[0]
        item.height = image.size[1]
        item.xHotspot = item.yHotspot = item.actionX = item.actionY = 0
        item.flags['Alpha'] = False  #True
        item.transparent = self.tileset_transparent
        item.graphicMode = 4

        item.image = image.tobytes('raw', 'RGBA')
        item.alpha = image.tobytes('raw', 'A')

        bank.items.append(item)
        bank.itemDict[item.handle] = item
        return item

    def create_object(self, name, key, image, obstacle=False, size=None):
        item = self.create_image(image, False)
        icon = self.create_image(image, True)

        frame = self.mfa.frames[0]
        frameitem = frame.new(FrameItem)
        frame.items.append(frameitem)

        frameitem.name = name
        if size is not None:
            frameitem.objectType = QUICKBACKDROP
        else:
            frameitem.objectType = BACKDROP
        frameitem.handle = self.object_id
        self.object_id += 1
        frameitem.transparent = True
        frameitem.inkEffect = frameitem.inkEffectParameter = 0
        frameitem.antiAliasing = False
        frameitem.iconHandle = icon.handle
        frameitem.chunks = frameitem.new(ChunkList)

        if size is not None:
            obj = frameitem.new(QuickBackdrop)
            obj.width = size[0]
            obj.height = size[1]
            obj.shape = objects.RECTANGLE_SHAPE
            obj.borderSize = 0
            obj.borderColor = (0, 0, 0)
            obj.fillType = objects.MOTIF_FILL
            obj.color1 = (0, 0, 0)
            obj.color2 = (0, 0, 0)
            obj.image = item.handle
        else:
            obj = frameitem.new(Backdrop)
            obj.handle = item.handle
        obj.obstacleType = 1 if obstacle else 0
        obj.collisionType = 0

        frameitem.loader = obj

        if key is not None:
            self.objects[key] = frameitem

        return frameitem
Beispiel #6
0
class Tiler(object):
    def __init__(self, filename):
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        if self.tiles:
            self.name, size = name.split('_')[:2]
            size = size.split(',')
            self.x_size = int(size[0])
            self.y_size = int(size[1])
        else:
            self.name = name.split('_')[0]

        self.outdir = os.path.splitext(filename)[0]
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1

    def run(self):
        image_path = os.path.join(SETS_PATH, '%s.png' % self.name)
        image = Image.open(image_path).convert('RGBA')

        col = image.getpixel((0, 0))
        if col[3] == 255:
            print 'Filtering image with transparent color', col
            buf = image.load()
            for y in xrange(image.size[1]):
                for x in xrange(image.size[0]):
                    test_col = buf[(x, y)]
                    if test_col != col:
                        continue
                    buf[(x, y)] = (0, 0, 0, 0)

        frame = self.mfa.frames[0]

        if self.tiles:
            self.run_tiles(image)
        else:
            self.run_special(image)

        frame.folders = []
        for item in frame.items:
            folder = frame.new(ItemFolder)
            folder.items = [item.handle]
            frame.folders.append(folder)

        basename = os.path.basename(self.filename)
        out_name = os.path.splitext(basename)[0] + '.mfa'
        out_path = os.path.join(self.outdir, out_name)

        self.mfa.write(ByteReader(open(out_path, 'wb')))
        print 'Created %s' % out_name

    def run_special(self, image):
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.name)
        mask = Image.open(mask_path).convert('RGBA')

        mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        buf = image.load()

        for (_, color) in colors:
            if color == transparent:
                continue
            color_image = mask.point(lambda x: 1 if x == color else 0)
            box = color_image.getbbox()
            height = box[3] - box[1]
            width = box[2] - box[0]
            new_image = Image.new('RGBA', (width, height), (255, 255, 255, 0))

            buf2 = color_image.load()
            buf3 = new_image.load()

            for y in xrange(height):
                for x in xrange(width):
                    xx = x + box[0]
                    yy = y + box[1]
                    color = buf2[(xx, yy)]
                    if color == 0:
                        continue
                    buf3[(x, y)] = buf[(xx, yy)]

            name = '%s_%s' % (self.name, self.image_id + 1)
            obj = self.create_object(name, None, new_image)
            self.create_instance(obj, box[0], box[1])

    def run_tiles(self, image):
        index_path = os.path.join(SETS_PATH, 'index.txt')
        charmap = open(index_path, 'rb').read()

        index = 0
        for y in xrange(0, image.size[1], self.y_size):
            for x in xrange(0, image.size[0], self.x_size):
                part = image.crop((x, y, x + self.x_size, y + self.y_size))
                char = charmap[index]
                name = '%s_%s_%s' % (self.name, x / self.x_size,
                                     y / self.y_size)
                self.create_object(name, char, part)
                index += 1

        data = open(self.filename, 'rb').read()

        x = 0
        y = 0
        for line in data.splitlines():
            for c in line:
                if c == ' ':
                    x += self.x_size
                    continue
                frameitem = self.objects[c]
                self.create_instance(frameitem, x, y)
                x += self.x_size

            x = 0
            y += self.y_size

    def create_instance(self, frameitem, x, y):
        frame = self.mfa.frames[0]
        instance = frame.new(FrameInstance)
        instance.x = x
        instance.y = y
        instance.handle = len(frame.instances) + 1
        instance.flags = 0
        instance.parentType = NONE_PARENT
        instance.itemHandle = frameitem.handle
        instance.parentHandle = 0
        instance.layer = 0
        frame.instances.append(instance)

    def create_image(self, image, icon):
        if icon:
            bank = self.mfa.icons
            handle = self.icon_id
            self.icon_id += 1
            image = image.resize((32, 32), Image.LANCZOS)
        else:
            bank = self.mfa.images
            handle = self.image_id
            self.image_id += 1

        item = bank.new(ImageItem, debug=True)
        item.handle = handle

        item.checksum = 123
        item.references = 0
        item.width = image.size[0]
        item.height = image.size[1]
        item.xHotspot = item.yHotspot = item.actionX = item.actionY = 0
        item.flags['Alpha'] = True
        item.transparent = (0, 0, 0)
        item.graphicMode = 4

        item.image = image.tobytes('raw', 'RGBA')
        item.alpha = image.tobytes('raw', 'A')

        bank.items.append(item)
        bank.itemDict[item.handle] = item
        return item

    def create_object(self, name, key, image, size=None):
        item = self.create_image(image, False)
        icon = self.create_image(image, True)

        frame = self.mfa.frames[0]
        frameitem = frame.new(FrameItem)
        frame.items.append(frameitem)

        frameitem.name = name
        if size is not None:
            frameitem.objectType = QUICKBACKDROP
        else:
            frameitem.objectType = BACKDROP
        frameitem.handle = self.object_id
        self.object_id += 1
        frameitem.transparent = True
        frameitem.inkEffect = frameitem.inkEffectParameter = 0
        frameitem.antiAliasing = False
        frameitem.iconHandle = icon.handle
        frameitem.chunks = frameitem.new(ChunkList)

        if size is not None:
            obj = frameitem.new(QuickBackdrop)
            obj.width = size[0]
            obj.height = size[1]
            obj.shape = objects.RECTANGLE_SHAPE
            obj.borderSize = 0
            obj.borderColor = (0, 0, 0)
            obj.fillType = objects.MOTIF_FILL
            obj.color1 = (0, 0, 0)
            obj.color2 = (0, 0, 0)
            obj.image = item.handle
        else:
            obj = frameitem.new(Backdrop)
            obj.handle = item.handle
        obj.obstacleType = 0
        obj.collisionType = 0

        frameitem.loader = obj

        if key is not None:
            self.objects[key] = frameitem

        return frameitem
Beispiel #7
0
class Tiler(object):
    def __init__(self, filename):
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        if self.tiles:
            self.name, size = name.split('_')[:2]
            size = size.split(',')
            self.x_size = int(size[0])
            self.y_size = int(size[1])
        else:
            self.name = name.split('_')[0]

        self.outdir = os.path.splitext(filename)[0]
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1

    def run(self):
        image_path = os.path.join(SETS_PATH, '%s.png' % self.name)
        image = Image.open(image_path).convert('RGBA')

        col = image.getpixel((0, 0))
        if col[3] == 255:
            print 'Filtering image with transparent color', col
            buf = image.load()
            for y in xrange(image.size[1]):
                for x in xrange(image.size[0]):
                    test_col = buf[(x, y)]
                    if test_col != col:
                        continue
                    buf[(x, y)] = (0, 0, 0, 0)

        frame = self.mfa.frames[0]

        if self.tiles:
            self.run_tiles(image)
        else:
            self.run_special(image)

        frame.folders = []
        for item in frame.items:
            folder = frame.new(ItemFolder)
            folder.items = [item.handle]
            frame.folders.append(folder)

        basename = os.path.basename(self.filename)
        out_name = os.path.splitext(basename)[0] + '.mfa'
        out_path = os.path.join(self.outdir, out_name)

        self.mfa.write(ByteReader(open(out_path, 'wb')))
        print 'Created %s' % out_name

    def run_special(self, image):
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.name)
        mask = Image.open(mask_path).convert('RGBA')

        mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        buf = image.load()

        for (_, color) in colors:
            if color == transparent:
                continue
            color_image = mask.point(lambda x: 1 if x == color else 0)
            box = color_image.getbbox()
            height = box[3] - box[1]
            width = box[2] - box[0]
            new_image = Image.new('RGBA', (width, height), (255, 255, 255, 0))

            buf2 = color_image.load()
            buf3 = new_image.load()

            for y in xrange(height):
                for x in xrange(width):
                    xx = x + box[0]
                    yy = y + box[1]
                    color = buf2[(xx, yy)]
                    if color == 0:
                        continue
                    buf3[(x, y)] = buf[(xx, yy)]

            name = '%s_%s' % (self.name, self.image_id + 1)
            obj = self.create_object(name, None, new_image)
            self.create_instance(obj, box[0], box[1])

    def run_tiles(self, image):
        index_path = os.path.join(SETS_PATH, 'index.txt')
        charmap = open(index_path, 'rb').read()

        index = 0
        for y in xrange(0, image.size[1], self.y_size):
            for x in xrange(0, image.size[0], self.x_size):
                part = image.crop((x, y, x + self.x_size, y + self.y_size))
                char = charmap[index]
                name = '%s_%s_%s' % (self.name,
                                     x / self.x_size,
                                     y / self.y_size)
                self.create_object(name, char, part)
                index += 1

        data = open(self.filename, 'rb').read()

        x = 0
        y = 0
        for line in data.splitlines():
            for c in line:
                if c == ' ':
                    x += self.x_size
                    continue
                frameitem = self.objects[c]
                self.create_instance(frameitem, x, y)
                x += self.x_size

            x = 0
            y += self.y_size

    def create_instance(self, frameitem, x, y):
        frame = self.mfa.frames[0]
        instance = frame.new(FrameInstance)
        instance.x = x
        instance.y = y
        instance.handle = len(frame.instances) + 1
        instance.flags = 0
        instance.parentType = NONE_PARENT
        instance.itemHandle = frameitem.handle
        instance.parentHandle = 0
        instance.layer = 0
        frame.instances.append(instance)

    def create_image(self, image, icon):
        if icon:
            bank = self.mfa.icons
            handle = self.icon_id
            self.icon_id += 1
            image = image.resize((32, 32), Image.LANCZOS)
        else:
            bank = self.mfa.images
            handle = self.image_id
            self.image_id += 1

        item = bank.new(ImageItem, debug=True)
        item.handle = handle

        item.checksum = 123
        item.references = 0
        item.width = image.size[0]
        item.height = image.size[1]
        item.xHotspot = item.yHotspot = item.actionX = item.actionY = 0
        item.flags['Alpha'] = True
        item.transparent = (0, 0, 0)
        item.graphicMode = 4

        item.image = image.tobytes('raw', 'RGBA')
        item.alpha = image.tobytes('raw', 'A')

        bank.items.append(item)
        bank.itemDict[item.handle] = item
        return item

    def create_object(self, name, key, image, size=None):
        item = self.create_image(image, False)
        icon = self.create_image(image, True)

        frame = self.mfa.frames[0]
        frameitem = frame.new(FrameItem)
        frame.items.append(frameitem)

        frameitem.name = name
        if size is not None:
            frameitem.objectType = QUICKBACKDROP
        else:
            frameitem.objectType = BACKDROP
        frameitem.handle = self.object_id
        self.object_id += 1
        frameitem.transparent = True
        frameitem.inkEffect = frameitem.inkEffectParameter = 0
        frameitem.antiAliasing = False
        frameitem.iconHandle = icon.handle
        frameitem.chunks = frameitem.new(ChunkList)

        if size is not None:
            obj = frameitem.new(QuickBackdrop)
            obj.width = size[0]
            obj.height = size[1]
            obj.shape = objects.RECTANGLE_SHAPE
            obj.borderSize = 0
            obj.borderColor = (0, 0, 0)
            obj.fillType = objects.MOTIF_FILL
            obj.color1 = (0, 0, 0)
            obj.color2 = (0, 0, 0)
            obj.image = item.handle
        else:
            obj = frameitem.new(Backdrop)
            obj.handle = item.handle
        obj.obstacleType = 0
        obj.collisionType = 0

        frameitem.loader = obj

        if key is not None:
            self.objects[key] = frameitem

        return frameitem
Beispiel #8
0
def translate(game, print_func = dummy_out):
    onepointfive = game.settings.get('old', False)
    mfa = MFA(ByteReader(open('template.mfa', 'rb')))

    # mfa = MFA()
    mfa.frames = []
    mfa.mfaBuild = 4 #MFA_CURRENT_VERSION
    mfa.product = game.productVersion
    mfa.buildVersion = 251
    mfa.name = game.name or ''
    mfa.description = ''
    mfa.path = game.editorFilename
    mfa.stamp = 6196 * '\x00'

    mfa.fonts = game.fonts or mfa.new(FontBank, compressed = False)
    mfa.sounds = game.sounds or mfa.new(SoundBank, compressed = False)
    mfa.music = game.music or mfa.new(MusicBank, compressed = False)
    for bank in (mfa.fonts, mfa.sounds, mfa.music):
        if bank.items is None:
            continue
        for item in bank.items:
            item.settings = {'compressed' : False}

    # mfa.icons = mfa.new(AGMIBank)
    images = mfa.new(AGMIBank)
    images.items = game.images.items
    for item in images.items:
        item.settings['debug'] = True
    mfa.images = images
    for item in (mfa.images, mfa.icons):
        item.paletteVersion = 768
        item.paletteEntries = 256
        item.palette = mfa.icons.palette
    mfa.author = game.author or ''
    mfa.copyright = game.copyright or ''
    mfa.company = ''
    mfa.version = ''
    if game.files is not None:
        for binaryFile in game.files.items:
            mfa.binaryFiles.append(binaryFile.name)
    header = game.header
    displaySettings = mfa.displaySettings
    graphicSettings = mfa.graphicSettings
    flags = header.flags
    newFlags = header.newFlags
    otherFlags = header.otherFlags
    displaySettings['MDI'] = newFlags['MDI']
    displaySettings['MenuBar'] = flags['MenuBar']
    displaySettings['MenuOnBoot'] = not flags['MenuHidden']
    graphicSettings['MultiSamples'] = flags['MultiSamples']
    mfa.windowSize = (header.windowWidth, header.windowHeight)
    mfa.borderColor = header.borderColor
    mfa.helpFile = ''
    mfa.vitalizePreview = ''
    mfa.initialScore = header.initialScore
    mfa.initialLifes = header.initialLives
    mfa.frameRate = header.frameRate or 50
    mfa.buildType = 0
    mfa.buildPath = game.targetFilename
    mfa.commandLine = ''
    mfa.aboutBox = game.aboutText or ''
    controls = mfa.new(Controls)
    for control in header.controls.items:
        newControl = controls.new(PlayerControl)
        newControl.controlType = 4
        keys = control.keys
        for key in ('up', 'down', 'left', 'right', 'button1', 'button2',
        'button3', 'button4'):
            try:
                key_value = getattr(keys, key).getValue()
            except AttributeError:
                key_value = 0
            getattr(newControl, key).setValue(key_value)
        controls.controls.append(newControl)
    mfa.controls = controls
    mfa.menu = game.menu
    mfa.windowMenuIndex = header.windowsMenuIndex or 0
    mfa.menuImages = {}
    globalValues = mfa.new(ValueList)
    if game.globalValues is not None:
        for index, item in enumerate(game.globalValues.items):
            newValue = ValueItem()
            newValue.name = 'Global Value %s' % (index + 1)
            newValue.value = item
            globalValues.items.append(newValue)
    globalStrings = mfa.new(ValueList)
    if game.globalStrings is not None:
        for index, item in enumerate(game.globalStrings.items):
            newValue = ValueItem()
            newValue.name = 'Global String %s' % (index + 1)
            newValue.value = item
            globalStrings.items.append(newValue)

    mfa.globalValues = globalValues
    mfa.globalStrings = globalStrings

    mfa.globalEvents = ''
    mfa.graphicMode = header.mode
    # mfa.iconImages = []
    mfa.customQualifiers = {}
    mfa.chunks = mfa.new(ChunkList)

    frameItems = {}

    for itemIndex, item in enumerate(game.frameItems.items):
    # for itemIndex, item in enumerate([]):
        newItem = mfa.new(FrameItem)
        newItem.name = item.name or ('Unnamed %s' % itemIndex)
        newItem.objectType = item.objectType
        newItem.handle = item.handle
        newItem.transparent = item.transparent
        newItem.inkEffect = item.inkEffect
        newItem.inkEffectParameter = item.inkEffectValue
        newItem.antiAliasing = item.antialias
        newItem.flags.setFlags(item.flags.getFlags())
        newItem.iconHandle = 10
        newItem.chunks = newItem.new(ChunkList)
        itemLoader = item.properties.loader
        if item.objectType >= EXTENSION_BASE:
            objectClass = ExtensionObject
        else:
            objectClass = FRAME_ITEM_LOADERS[item.objectType]
        newLoader = newItem.loader = newItem.new(objectClass)
        if item.objectType in (QUICKBACKDROP, BACKDROP):
            newLoader.obstacleType = itemLoader.obstacleType
            newLoader.collisionType = itemLoader.collisionMode
            if item.objectType == QUICKBACKDROP:
                newLoader.width = itemLoader.width
                newLoader.height = itemLoader.height
                shape = itemLoader.shape
                newLoader.shape = shape.shape
                newLoader.borderSize = shape.borderSize
                newLoader.borderColor = shape.borderColor
                newLoader.fillType = shape.fillType
                newLoader.color1 = shape.color1 or (0, 0, 0)
                newLoader.color2 = shape.color2 or (0, 0, 0)
                newLoader.flags.setFlags(shape.gradientFlags)
                newLoader.image = shape.image
            else:
                newLoader.handle = itemLoader.image
        else:
            newLoader.objectFlags.setFlags(itemLoader.flags.getFlags())
            try:
                newLoader.newObjectFlags.setFlags(
                    itemLoader.newFlags.getFlags())
            except AttributeError:
                # could happen for MMF1.5
                pass
            newLoader.backgroundColor = itemLoader.backColour
            newLoader.qualifiers = itemLoader.qualifiers
            newLoader.values = convert_alterables(itemLoader.values, 'Value')
            newLoader.strings = convert_alterables(itemLoader.strings, 'String')

            newLoader.movements = movements = newLoader.new(Movements)
            for index, movement in enumerate(itemLoader.movements.items):
                newMovement = movements.new(Movement)
                newMovement.name = 'Movement #%s' % (index + 1)
                if movement.getName() == 'Extension':
                    newMovement.extension = movement.loader.name + '.mvx'
                    newMovement.identifier = movement.loader.id
                else:
                    newMovement.extension = ''
                    newMovement.identifier = movement.type
                    newMovement.player = movement.player
                    newMovement.type = movement.type
                    newMovement.movingAtStart = movement.movingAtStart
                    newMovement.directionAtStart = movement.directionAtStart
                newMovement.loader = movement.loader
                movements.items.append(newMovement)

            newLoader.behaviours = newLoader.new(Behaviours)
            newLoader.fadeIn = convert_transition(itemLoader.fadeIn)
            newLoader.fadeOut = convert_transition(itemLoader.fadeOut)
            if itemLoader.animations is not None:
                animationHeader = itemLoader.animations
                newLoader.items = items = []
                for i in xrange(max(animationHeader.loadedAnimations) + 1):
                    newAnimation = newLoader.new(Animation)
                    items.append(newAnimation)
                    newAnimation.directions = newDirections = []
                    try:
                        animation = animationHeader.loadedAnimations[i]
                    except KeyError:
                        continue
                    for n, direction in animation.loadedDirections.iteritems():
                        newDirection = newAnimation.new(AnimationDirection)
                        newDirections.append(newDirection)
                        newDirection.index = n
                        newDirection.minSpeed = direction.minSpeed
                        newDirection.maxSpeed = direction.maxSpeed
                        newDirection.repeat = direction.repeat
                        newDirection.backTo = direction.backTo
                        newDirection.frames = direction.frames
            if item.objectType >= EXTENSION_BASE:
                extension = item.getExtension(game.extensions)
                newLoader.extensionType = -1
                newLoader.extensionName = ''
                newLoader.filename = extension.name + '.mfx'
                newLoader.magic = extension.magicNumber
                newLoader.subType = extension.subType
                newLoader.extensionVersion = itemLoader.extensionVersion
                newLoader.extensionId = itemLoader.extensionId
                newLoader.extensionPrivate = itemLoader.extensionPrivate
                newLoader.extensionData = itemLoader.extensionData or ''
            elif item.objectType == COUNTER:
                counter = itemLoader.counter
                counters = itemLoader.counters
                newLoader.value = counter.initial
                newLoader.minimum = counter.minimum
                newLoader.maximum = counter.maximum
                if counters is None:
                    newLoader.displayType = HIDDEN
                    shape = None
                    newLoader.countType = 0
                    newLoader.width = 0
                    newLoader.height = 0
                    newLoader.images = []
                    newLoader.font = 0
                else:
                    shape = counters.shape
                    newLoader.displayType = counters.displayType
                    newLoader.countType = counters.inverse
                    newLoader.width = counters.width
                    newLoader.height = counters.height
                    newLoader.images = counters.frames or []
                    newLoader.font = counters.font or 0
                if shape is None:
                    color1 = color2 = (0, 0, 0)
                    newLoader.verticalGradient = 0
                    newLoader.flags = 0
                else:
                    color1 = shape.color1 or (0, 0, 0)
                    color2 = shape.color2 or (0, 0, 0)
                    newLoader.verticalGradient = shape.gradientFlags or 0
                    newLoader.flags = shape.fillType
                newLoader.color1 = color1
                newLoader.color2 = color2
            elif item.objectType in (SCORE, LIVES):
                counters = itemLoader.counters
                newLoader.player = counters.player
                newLoader.images = counters.frames or []
                newLoader.displayType = counters.displayType
                newLoader.flags = counters.flags
                newLoader.font = counters.font
                newLoader.width = counters.width
                newLoader.height = counters.height
            elif item.objectType == RTF:
                rtf = itemLoader.rtf
                newLoader.width = rtf.width
                newLoader.height = rtf.height
                newLoader.value = rtf.value
                newLoader.color = rtf.color
                newLoader.flags = rtf.options.getFlags()
            elif item.objectType == SUBAPPLICATION:
                subApplication = itemLoader.subApplication
                newLoader.width = subApplication.width
                newLoader.height = subApplication.height
                newLoader.filename = subApplication.name
                if subApplication.options['Internal']:
                    startFrame = subApplication.startFrame
                else:
                    startFrame = -1
                newLoader.startFrame = startFrame
                newLoader.options.setFlags(subApplication.options.getFlags())
            elif item.objectType == TEXT:
                text = itemLoader.text
                newLoader.width = text.width
                newLoader.height = text.height
                paragraph = text.items[0]
                newLoader.font = paragraph.font
                newLoader.color = paragraph.color
                newLoader.flags = 0
                newLoader.items = paragraphs = []
                for paragraph in text.items:
                    newParagraph = newLoader.new(Paragraph)
                    paragraphs.append(newParagraph)
                    newParagraph.value = paragraph.value
                    newParagraph.flags = paragraph.flags.getFlags()
            elif item.objectType == QUESTION:
                text = itemLoader.text
                newLoader.width = text.width
                newLoader.height = text.height
                question = text.items[0]
                answer = text.items[1]
                print question.font
                newLoader.questionFont = question.font
                newLoader.questionColor = question.color
                newLoader.questionFlags = 0
                newLoader.question = question.value
                newLoader.answerFont = answer.font
                newLoader.answerColor = answer.color
                newLoader.answerFlags = 0
                newLoader.items = paragraphs = []
                for paragraph in text.items[1:]:
                    newParagraph = newLoader.new(Paragraph)
                    paragraphs.append(newParagraph)
                    newParagraph.value = paragraph.value
                    newParagraph.flags = paragraph.flags.getFlags()
        frameItems[newItem.handle] = newItem

    qualifiers = {}

    indexHandles = dict(
        [(v, index) for (index, v) in enumerate(game.frameHandles)])

    for index, frame in enumerate(game.frames[:20]):
        frame.load()
        newFrame = mfa.new(Frame)
        newFrame.handle = indexHandles[index]
        newFrame.name = frame.name or ''
        newFrame.size = (frame.width, frame.height)
        newFrame.background = frame.background
        newFrame.fadeIn = convert_transition(frame.fadeIn)
        newFrame.fadeOut = convert_transition(frame.fadeOut)
        flags = newFrame.flags
        originalFlags = frame.flags
        flags['GrabDesktop'] = originalFlags['GrabDesktop']
        flags['KeepDisplay'] = originalFlags['KeepDisplay']
        flags['BackgroundCollisions'] = originalFlags['TotalCollisionMask']
        flags['ResizeToScreen'] = originalFlags['ResizeAtStart']
        flags['ForceLoadOnCall'] = originalFlags['ForceLoadOnCall']
        flags['NoDisplaySurface'] = False#originalFlags['NoSurface']
        flags['TimerBasedMovements'] = originalFlags['TimedMovements']
        newFrame.maxObjects = frame.maxObjects
        newFrame.password = frame.password or ''
        newFrame.lastViewedX = 320
        newFrame.lastViewedY = 240
        newFrame.palette = newFrame.palette
        newFrame.stampHandle = 12
        newFrame.activeLayer = 0
        newFrame.layers = layers = []
        try:
            for layer in frame.layers.items:
                newLayer = newFrame.new(Layer)
                newLayer.name = layer.name
                flags = newLayer.flags
                originalFlags = layer.flags
                flags['HideAtStart'] = originalFlags['ToHide']
                flags['Visible'] = True
                flags['NoBackground'] = originalFlags['DoNotSaveBackground']
                flags['WrapHorizontally'] = originalFlags['WrapHorizontally']
                flags['WrapVertically'] = originalFlags['WrapVertically']
                newLayer.xCoefficient = layer.xCoefficient
                newLayer.yCoefficient = layer.yCoefficient
                layers.append(newLayer)
        except AttributeError:
            # MMF 1.5
            layer = newFrame.new(Layer)
            layer.name = 'Default Layer'
            layer.xCoefficient = layer.yCoefficient = 1.0
            layers.append(layer)
        newFrameItems = set()
        newFrame.instances = instances = []
        print_func('Translating frame %r (%s)' % (newFrame.name, index))
        if frame.instances is not None:
            for instanceIndex, instance in enumerate(frame.instances.items):
                try:
                    frameItem = frameItems[instance.objectInfo]
                except KeyError:
                    continue
                newFrameItems.add(frameItem)
                newInstance = newFrame.new(FrameInstance)
                newInstance.x = instance.x
                newInstance.y = instance.y
                newInstance.handle = instanceIndex
                if instance.parentType != NONE_PARENT:
                    newInstance.flags = 8
                else:
                    newInstance.flags = 0
                newInstance.parentType = instance.parentType
                newInstance.itemHandle = instance.objectInfo
                parentHandle = instance.parentHandle
                newInstance.parentHandle = parentHandle
                newInstance.layer = instance.layer
                instances.append(newInstance)
        newFrame.items = list(newFrameItems)
        newFrame.folders = folders = []
        for item in newFrame.items:
            newFolder = newFrame.new(ItemFolder)
            newFolder.items = [item.handle]
            folders.append(newFolder)
        events = newFrame.events = frame.new(Events)
        events.version = 1027
        events.frameType = 0
        events.items = frame.events.items
        events.objects = objects = []
        for item in newFrame.items:
            newObject = events.new(EventObject)
            objects.append(newObject)
            newObject.handle = item.handle
            newObject.name = item.name
            newObject.typeName = ''
            newObject.itemType = item.objectType
            newObject.objectType = FRAME_ITEM_TYPE
            newObject.flags = 0
            newObject.itemHandle = item.handle
            newObject.instanceHandle = 0xFFFFFFFF
        for k, item in frame.events.qualifiers.iteritems():
            key = (k, item.type)
            objectInfo = item.objectInfo
            if key in qualifiers:
                newObject = qualifiers[key]
                newHandle = newObject.handle
            else:
                newObject = events.new(EventObject)
                qualifiers[key] = newObject
                newHandle = 0
                while 1:
                    if newHandle not in qualifiers and newHandle not in frameItems:
                        break
                    newHandle += 1
                frameItems[newHandle] = newObject
                newObject.handle = newHandle
                newObject.systemQualifier = item.qualifier
                newObject.name = ''
                newObject.typeName = ''
                newObject.itemType = item.type
                newObject.objectType = SYSTEM_ITEM_TYPE
                newObject.flags = 0
            for eventGroup in frame.events.items:
                for aceList in (eventGroup.actions, eventGroup.conditions):
                    for ace in aceList:
                        if ace.objectInfo == objectInfo:
                            ace.objectInfo = newHandle
                        for parameter in ace.items:
                            parameter = parameter.loader
                            if hasattr(parameter, 'objectInfo'):
                                if parameter.objectInfo == objectInfo:
                                    parameter.objectInfo = newHandle
                            if hasattr(parameter, 'objectInfoParent'):
                                if parameter.objectInfoParent == objectInfo:
                                    parameter.objectInfoParent = newHandle
                            if hasattr(parameter, 'position'):
                                position = parameter.position
                                if position.objectInfoParent == objectInfo:
                                    position.objectInfoParent = newHandle
                            if parameter.isExpression:
                                for expression in parameter.items:
                                    if expression.objectInfo == objectInfo:
                                        expression.objectInfo = newHandle
            objects.append(newObject)
        # group stuff
        groups = {}
        groupId = 0
        def loop_parameters():
            for eventGroup in frame.events.items:
                for aceList in (eventGroup.actions, eventGroup.conditions):
                    for ace in aceList:
                        for parameter in ace.items:
                            yield parameter.getName(), parameter.loader

        for name, parameter in loop_parameters():
            if name == 'GROUP':
                offset = parameter.offset
                if onepointfive:
                    offset = parameter.offset + 2
                groups[offset] = groupId
                parameter.id = groupId
                parameter.password = make_group_checksum('', parameter.name)
                groupId += 1

        for name, parameter in loop_parameters():
            if name == 'GROUPOINTER':
                parameter.id = groups[parameter.pointer]
                parameter.savedPointer = parameter.pointer = 0

        newFrame.chunks = mfa.new(ChunkList)
        mfa.frames.append(save_data_loader(newFrame))
        frame.close()

    return mfa
Beispiel #9
0
class Tiler(object):
    def __init__(self, filename):
        filename = os.path.join(DATA_DIR, filename)
        self.filename = filename

        self.tiles = os.stat(filename).st_size != 0

        name = os.path.basename(filename).encode('utf-8')
        self.name = os.path.splitext(name)[0]

        self.outdir = os.path.join(DATA_DIR, 'mfas')# + self.name
        try:
            os.makedirs(self.outdir)
        except OSError:
            pass

        self.objects = {}

        self.x_size = 16
        self.y_size = 16

        template_path = os.path.join(DATA_DIR, 'template.mfa')
        self.mfa = MFA(ByteReader(open(template_path, 'rb')))

        self.object_id = 32
        self.image_id = 0
        self.icon_id = max(self.mfa.icons.itemDict) + 1

    def run(self, cmd):
        self.room = ByteReader(open(self.filename, 'rb'))
        self.file_ver = self.room.readByte(True)
        self.x_size = self.room.readByte(True)
        self.y_size = self.room.readByte(True)
        tileset_len = self.room.readByte(True)
        self.tileset = self.room.readString(tileset_len)
        self.tile_count = self.room.readInt(True)

        image_path = os.path.join(SETS_PATH, '%s.png' % self.tileset)
        image = Image.open(image_path).convert('RGBA')

        col = image.getpixel((0, 0))
        self.tileset_transparent = col[:3]
        if col[3] == 255:
            print 'Filtering image with transparent color', col
            buf = image.load()
            for y in xrange(image.size[1]):
                for x in xrange(image.size[0]):
                    test_col = buf[(x, y)]
                    if test_col != col:
                        continue
                    buf[(x, y)] = (0, 0, 0, 0)

        frame = self.mfa.frames[0]

        if cmd == 'extract_tiles':
            self.run_extract_tiles(image)
            return
        elif cmd == 'build':
            self.run_build(image)

        frame.folders = []
        for item in frame.items:
            folder = frame.new(ItemFolder)
            folder.items = [item.handle]
            frame.folders.append(folder)

        basename = os.path.basename(self.filename)
        out_name = os.path.splitext(basename)[0] + '.mfa'
        out_path = os.path.join(self.outdir, out_name)

        if os.path.isfile(out_path):
            os.remove(out_path)
        self.mfa.write(ByteReader(open(out_path, 'wb')))
        print 'Created %s' % out_name

    def run_build(self, image):
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.tileset)
        mask = Image.open(mask_path)

        if mask.mode != 'P':
            raise ValueError('The mask has to be palette image')

        #mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        if transparent != 0:
            raise ValueError('The transparent color should be the first color '
                             'in the palette')

        buf = image.load()

        for (_, color) in colors:
            if color == transparent or color == 255:
                continue
            color_image = mask.point(lambda x: 1 if x == color else 0)
            box = color_image.getbbox()
            tile_x = box[0] / self.x_size
            tile_y = box[1] / self.y_size
            height = box[3] - box[1]
            width = box[2] - box[0]
            new_image = Image.new('RGBA', (width, height),
                                  self.tileset_transparent)

            buf2 = color_image.load()
            buf3 = new_image.load()


            for y in xrange(height):
                for x in xrange(width):
                    xx = x + box[0]
                    yy = y + box[1]
                    if buf2[(xx, yy)] == 0 or buf[(xx, yy)][3] == 0:
                        continue
                    buf3[(x, y)] = buf[(xx, yy)]

            obstacle = mask.getpixel((tile_x, tile_y)) == 255
            self.create_object("%s%s" % (self.tileset, color), color,
                               new_image, obstacle)

        room_width = 0
        room_height = 0
        instances = []
        map = dict()
        for _ in xrange(self.tile_count):
            try:
                x = self.room.readShort() * self.x_size
                y = self.room.readShort() * self.y_size
                room_width = max(room_width, x + 200)
                room_height = max(room_height, y + 200)
                key = self.room.readByte(True)
                frameitem = self.objects[key]
                instances.append((frameitem, x, y))
                map[(x,y)] = 1
            except:
                break

        for i in instances:
            self.create_instance(*i)
            #statt self.create_instance(i[0], i[1], i[2])

        frame = self.mfa.frames[0]
        frame.size = room_width, room_height

    def run_extract_tiles(self, image):
        tile_folder = sys.argv[3]

        image_path = os.path.join(SETS_PATH, '%s.png' % self.tileset)
        image = Image.open(image_path).convert('RGBA')
        mask_path = os.path.join(SETS_PATH, '%s_mask.png' % self.tileset)
        mask = Image.open(mask_path)
        transparent_color = image.getpixel((0, 0))

        if mask.mode != 'P':
            raise ValueError('The mask has to be palette image')

        #mask = mask.convert('P')
        colors = mask.getcolors()
        transparent = mask.getpixel((0, 0))

        if transparent != 0:
            raise ValueError('The transparent color should be the first color '
                             'in the palette')

        ini = open(os.path.join(DATA_DIR, tile_folder, 'tiles.ini'), 'w')
        for (_, color) in colors:
            if color == transparent:
                continue
            # Extract the current tile's shape from the mask image
            tile_mask = mask.point(lambda x: 1 if x == color else 0, '1')
            box = tile_mask.getbbox()
            tile_mask = tile_mask.crop(box)
            # Create an image and render the tile to it
            tile = Image.new('RGBA', tile_mask.size)
            tile.paste(image.crop(box), tile_mask)
            col = image.getpixel((0, 0))
            buf = tile.load()
            # Clear transparent pixels
            for y in xrange(tile.size[1]):
                for x in xrange(tile.size[0]):
                    if buf[(x, y)] == transparent_color:
                        buf[(x, y)] = (0, 0, 0, 0)
            tile.save(os.path.join(DATA_DIR, tile_folder, "%s.png" % color),
                      "PNG")

            x = box[0]
            y = box[1]
            height = box[3] - y
            width = box[2] - x
            tile_x = x / self.x_size
            tile_y = y / self.y_size

            if color == 25:
                print tile_x * self.x_size, x

            ini.write("[t%s]\n" % color)
            ini.write("x=%s\n" % x)
            ini.write("y=%s\n" % y)
            ini.write("x_off=%s\n" % (x - tile_x * self.x_size))
            ini.write("y_off=%s\n" % (y - tile_y * self.y_size))
            ini.write("width=%s\n" % width)
            ini.write("height=%s\n" % height)

        ini.write("[image]\n")
        ini.write("width=%s\n" % image.size[0])
        ini.write("height=%s\n" % image.size[1])
        ini.close()

    def create_instance(self, frameitem, x, y):
        frame = self.mfa.frames[0]
        instance = frame.new(FrameInstance)
        instance.x = x
        instance.y = y
        instance.handle = len(frame.instances) + 1
        instance.flags = 0
        instance.parentType = NONE_PARENT
        instance.itemHandle = frameitem.handle
        instance.parentHandle = 0
        instance.layer = 0
        frame.instances.append(instance)

    def create_image(self, image, icon):
        if icon:
            bank = self.mfa.icons
            handle = self.icon_id
            self.icon_id += 1
            image = image.resize((32, 32), Image.LANCZOS)
        else:
            bank = self.mfa.images
            handle = self.image_id
            self.image_id += 1

        item = bank.new(ImageItem, debug=True)
        item.handle = handle

        item.checksum = 123
        item.references = 0
        item.width = image.size[0]
        item.height = image.size[1]
        item.xHotspot = item.yHotspot = item.actionX = item.actionY = 0
        item.flags['Alpha'] = False#True
        item.transparent = self.tileset_transparent
        item.graphicMode = 4

        item.image = image.tobytes('raw', 'RGBA')
        item.alpha = image.tobytes('raw', 'A')

        bank.items.append(item)
        bank.itemDict[item.handle] = item
        return item

    def create_object(self, name, key, image, obstacle=False, size=None):
        item = self.create_image(image, False)
        icon = self.create_image(image, True)

        frame = self.mfa.frames[0]
        frameitem = frame.new(FrameItem)
        frame.items.append(frameitem)

        frameitem.name = name
        if size is not None:
            frameitem.objectType = QUICKBACKDROP
        else:
            frameitem.objectType = BACKDROP
        frameitem.handle = self.object_id
        self.object_id += 1
        frameitem.transparent = True
        frameitem.inkEffect = frameitem.inkEffectParameter = 0
        frameitem.antiAliasing = False
        frameitem.iconHandle = icon.handle
        frameitem.chunks = frameitem.new(ChunkList)

        if size is not None:
            obj = frameitem.new(QuickBackdrop)
            obj.width = size[0]
            obj.height = size[1]
            obj.shape = objects.RECTANGLE_SHAPE
            obj.borderSize = 0
            obj.borderColor = (0, 0, 0)
            obj.fillType = objects.MOTIF_FILL
            obj.color1 = (0, 0, 0)
            obj.color2 = (0, 0, 0)
            obj.image = item.handle
        else:
            obj = frameitem.new(Backdrop)
            obj.handle = item.handle
        obj.obstacleType = 1 if obstacle else 0
        obj.collisionType = 0

        frameitem.loader = obj

        if key is not None:
            self.objects[key] = frameitem

        return frameitem
def translate(game, print_func=dummy_out):
    onepointfive = game.settings.get('old', False)
    mfa = MFA(ByteReader(open('template.mfa', 'rb')))

    # mfa = MFA()
    mfa.frames = []
    mfa.mfaBuild = 4  #MFA_CURRENT_VERSION
    mfa.product = game.productVersion
    mfa.buildVersion = 251
    mfa.name = game.name or ''
    mfa.description = ''
    mfa.path = game.editorFilename
    mfa.stamp = 6196 * '\x00'

    mfa.fonts = game.fonts or mfa.new(FontBank, compressed=False)
    mfa.sounds = game.sounds or mfa.new(SoundBank, compressed=False)
    mfa.music = game.music or mfa.new(MusicBank, compressed=False)
    for bank in (mfa.fonts, mfa.sounds, mfa.music):
        if bank.items is None:
            continue
        for item in bank.items:
            item.settings = {'compressed': False}

    # mfa.icons = mfa.new(AGMIBank)
    images = mfa.new(AGMIBank)
    images.items = game.images.items
    for item in images.items:
        item.settings['debug'] = True
    mfa.images = images
    for item in (mfa.images, mfa.icons):
        item.paletteVersion = 768
        item.paletteEntries = 256
        item.palette = mfa.icons.palette
    mfa.author = game.author or ''
    mfa.copyright = game.copyright or ''
    mfa.company = ''
    mfa.version = ''
    if game.files is not None:
        for binaryFile in game.files.items:
            mfa.binaryFiles.append(binaryFile.name)
    header = game.header
    displaySettings = mfa.displaySettings
    graphicSettings = mfa.graphicSettings
    flags = header.flags
    newFlags = header.newFlags
    otherFlags = header.otherFlags
    displaySettings['MDI'] = newFlags['MDI']
    displaySettings['MenuBar'] = flags['MenuBar']
    displaySettings['MenuOnBoot'] = not flags['MenuHidden']
    graphicSettings['MultiSamples'] = flags['MultiSamples']
    mfa.windowSize = (header.windowWidth, header.windowHeight)
    mfa.borderColor = header.borderColor
    mfa.helpFile = ''
    mfa.vitalizePreview = ''
    mfa.initialScore = header.initialScore
    mfa.initialLifes = header.initialLives
    mfa.frameRate = header.frameRate or 50
    mfa.buildType = 0
    mfa.buildPath = game.targetFilename
    mfa.commandLine = ''
    mfa.aboutBox = game.aboutText or ''
    controls = mfa.new(Controls)
    for control in header.controls.items:
        newControl = controls.new(PlayerControl)
        newControl.controlType = 4
        keys = control.keys
        for key in ('up', 'down', 'left', 'right', 'button1', 'button2',
                    'button3', 'button4'):
            try:
                key_value = getattr(keys, key).getValue()
            except AttributeError:
                key_value = 0
            getattr(newControl, key).setValue(key_value)
        controls.controls.append(newControl)
    mfa.controls = controls
    mfa.menu = game.menu
    mfa.windowMenuIndex = header.windowsMenuIndex or 0
    mfa.menuImages = {}
    globalValues = mfa.new(ValueList)
    if game.globalValues is not None:
        for index, item in enumerate(game.globalValues.items):
            newValue = ValueItem()
            newValue.name = 'Global Value %s' % (index + 1)
            newValue.value = item
            globalValues.items.append(newValue)
    globalStrings = mfa.new(ValueList)
    if game.globalStrings is not None:
        for index, item in enumerate(game.globalStrings.items):
            newValue = ValueItem()
            newValue.name = 'Global String %s' % (index + 1)
            newValue.value = item
            globalStrings.items.append(newValue)

    mfa.globalValues = globalValues
    mfa.globalStrings = globalStrings

    mfa.globalEvents = ''
    mfa.graphicMode = header.mode
    # mfa.iconImages = []
    mfa.customQualifiers = {}
    mfa.chunks = mfa.new(ChunkList)

    frameItems = {}

    for itemIndex, item in enumerate(game.frameItems.items):
        # for itemIndex, item in enumerate([]):
        newItem = mfa.new(FrameItem)
        newItem.name = item.name or ('Unnamed %s' % itemIndex)
        newItem.objectType = item.objectType
        newItem.handle = item.handle
        newItem.transparent = item.transparent
        newItem.inkEffect = item.inkEffect
        newItem.inkEffectParameter = item.inkEffectValue
        newItem.antiAliasing = item.antialias
        newItem.flags.setFlags(item.flags.getFlags())
        newItem.iconHandle = 10
        newItem.chunks = newItem.new(ChunkList)
        itemLoader = item.properties.loader
        if item.objectType >= EXTENSION_BASE:
            objectClass = ExtensionObject
        else:
            objectClass = FRAME_ITEM_LOADERS[item.objectType]
        newLoader = newItem.loader = newItem.new(objectClass)
        if item.objectType in (QUICKBACKDROP, BACKDROP):
            newLoader.obstacleType = itemLoader.obstacleType
            newLoader.collisionType = itemLoader.collisionMode
            if item.objectType == QUICKBACKDROP:
                newLoader.width = itemLoader.width
                newLoader.height = itemLoader.height
                shape = itemLoader.shape
                newLoader.shape = shape.shape
                newLoader.borderSize = shape.borderSize
                newLoader.borderColor = shape.borderColor
                newLoader.fillType = shape.fillType
                newLoader.color1 = shape.color1 or (0, 0, 0)
                newLoader.color2 = shape.color2 or (0, 0, 0)
                newLoader.flags.setFlags(shape.gradientFlags)
                newLoader.image = shape.image
            else:
                newLoader.handle = itemLoader.image
        else:
            newLoader.objectFlags.setFlags(itemLoader.flags.getFlags())
            try:
                newLoader.newObjectFlags.setFlags(
                    itemLoader.newFlags.getFlags())
            except AttributeError:
                # could happen for MMF1.5
                pass
            newLoader.backgroundColor = itemLoader.backColour
            newLoader.qualifiers = itemLoader.qualifiers
            newLoader.values = convert_alterables(itemLoader.values, 'Value')
            newLoader.strings = convert_alterables(itemLoader.strings,
                                                   'String')

            newLoader.movements = movements = newLoader.new(Movements)
            for index, movement in enumerate(itemLoader.movements.items):
                newMovement = movements.new(Movement)
                newMovement.name = 'Movement #%s' % (index + 1)
                if movement.getName() == 'Extension':
                    newMovement.extension = movement.loader.name + '.mvx'
                    newMovement.identifier = movement.loader.id
                else:
                    newMovement.extension = ''
                    newMovement.identifier = movement.type
                    newMovement.player = movement.player
                    newMovement.type = movement.type
                    newMovement.movingAtStart = movement.movingAtStart
                    newMovement.directionAtStart = movement.directionAtStart
                newMovement.loader = movement.loader
                movements.items.append(newMovement)

            newLoader.behaviours = newLoader.new(Behaviours)
            newLoader.fadeIn = convert_transition(itemLoader.fadeIn)
            newLoader.fadeOut = convert_transition(itemLoader.fadeOut)
            if itemLoader.animations is not None:
                animationHeader = itemLoader.animations
                newLoader.items = items = []
                for i in xrange(max(animationHeader.loadedAnimations) + 1):
                    newAnimation = newLoader.new(Animation)
                    items.append(newAnimation)
                    newAnimation.directions = newDirections = []
                    try:
                        animation = animationHeader.loadedAnimations[i]
                    except KeyError:
                        continue
                    for n, direction in animation.loadedDirections.iteritems():
                        newDirection = newAnimation.new(AnimationDirection)
                        newDirections.append(newDirection)
                        newDirection.index = n
                        newDirection.minSpeed = direction.minSpeed
                        newDirection.maxSpeed = direction.maxSpeed
                        newDirection.repeat = direction.repeat
                        newDirection.backTo = direction.backTo
                        newDirection.frames = direction.frames
            if item.objectType >= EXTENSION_BASE:
                extension = item.getExtension(game.extensions)
                newLoader.extensionType = -1
                newLoader.extensionName = ''
                newLoader.filename = extension.name + '.mfx'
                newLoader.magic = extension.magicNumber
                newLoader.subType = extension.subType
                newLoader.extensionVersion = itemLoader.extensionVersion
                newLoader.extensionId = itemLoader.extensionId
                newLoader.extensionPrivate = itemLoader.extensionPrivate
                newLoader.extensionData = itemLoader.extensionData or ''
            elif item.objectType == COUNTER:
                counter = itemLoader.counter
                counters = itemLoader.counters
                newLoader.value = counter.initial
                newLoader.minimum = counter.minimum
                newLoader.maximum = counter.maximum
                if counters is None:
                    newLoader.displayType = HIDDEN
                    shape = None
                    newLoader.countType = 0
                    newLoader.width = 0
                    newLoader.height = 0
                    newLoader.images = []
                    newLoader.font = 0
                else:
                    shape = counters.shape
                    newLoader.displayType = counters.displayType
                    newLoader.countType = counters.inverse
                    newLoader.width = counters.width
                    newLoader.height = counters.height
                    newLoader.images = counters.frames or []
                    newLoader.font = counters.font or 0
                if shape is None:
                    color1 = color2 = (0, 0, 0)
                    newLoader.verticalGradient = 0
                    newLoader.flags = 0
                else:
                    color1 = shape.color1 or (0, 0, 0)
                    color2 = shape.color2 or (0, 0, 0)
                    newLoader.verticalGradient = shape.gradientFlags or 0
                    newLoader.flags = shape.fillType
                newLoader.color1 = color1
                newLoader.color2 = color2
            elif item.objectType in (SCORE, LIVES):
                counters = itemLoader.counters
                newLoader.player = counters.player
                newLoader.images = counters.frames or []
                newLoader.displayType = counters.displayType
                newLoader.flags = counters.flags
                newLoader.font = counters.font
                newLoader.width = counters.width
                newLoader.height = counters.height
            elif item.objectType == RTF:
                rtf = itemLoader.rtf
                newLoader.width = rtf.width
                newLoader.height = rtf.height
                newLoader.value = rtf.value
                newLoader.color = rtf.color
                newLoader.flags = rtf.options.getFlags()
            elif item.objectType == SUBAPPLICATION:
                subApplication = itemLoader.subApplication
                newLoader.width = subApplication.width
                newLoader.height = subApplication.height
                newLoader.filename = subApplication.name
                if subApplication.options['Internal']:
                    startFrame = subApplication.startFrame
                else:
                    startFrame = -1
                newLoader.startFrame = startFrame
                newLoader.options.setFlags(subApplication.options.getFlags())
            elif item.objectType == TEXT:
                text = itemLoader.text
                newLoader.width = text.width
                newLoader.height = text.height
                paragraph = text.items[0]
                newLoader.font = paragraph.font
                newLoader.color = paragraph.color
                newLoader.flags = 0
                newLoader.items = paragraphs = []
                for paragraph in text.items:
                    newParagraph = newLoader.new(Paragraph)
                    paragraphs.append(newParagraph)
                    newParagraph.value = paragraph.value
                    newParagraph.flags = paragraph.flags.getFlags()
            elif item.objectType == QUESTION:
                text = itemLoader.text
                newLoader.width = text.width
                newLoader.height = text.height
                question = text.items[0]
                answer = text.items[1]
                print question.font
                newLoader.questionFont = question.font
                newLoader.questionColor = question.color
                newLoader.questionFlags = 0
                newLoader.question = question.value
                newLoader.answerFont = answer.font
                newLoader.answerColor = answer.color
                newLoader.answerFlags = 0
                newLoader.items = paragraphs = []
                for paragraph in text.items[1:]:
                    newParagraph = newLoader.new(Paragraph)
                    paragraphs.append(newParagraph)
                    newParagraph.value = paragraph.value
                    newParagraph.flags = paragraph.flags.getFlags()
        frameItems[newItem.handle] = newItem

    qualifiers = {}

    indexHandles = dict([(v, index)
                         for (index, v) in enumerate(game.frameHandles)])

    for index, frame in enumerate(game.frames):
        #print 'this application has %s frames. I am currently working on frame %s.' % (len(game.frames), len(frame)) #invalid type lol
        frame.load()
        newFrame = mfa.new(Frame)
        newFrame.handle = indexHandles[index]
        newFrame.name = frame.name or ''
        newFrame.size = (frame.width, frame.height)
        newFrame.background = frame.background
        newFrame.fadeIn = convert_transition(frame.fadeIn)
        newFrame.fadeOut = convert_transition(frame.fadeOut)
        flags = newFrame.flags
        originalFlags = frame.flags
        flags['GrabDesktop'] = originalFlags['GrabDesktop']
        flags['KeepDisplay'] = originalFlags['KeepDisplay']
        flags['BackgroundCollisions'] = originalFlags['TotalCollisionMask']
        flags['ResizeToScreen'] = originalFlags['ResizeAtStart']
        flags['ForceLoadOnCall'] = originalFlags['ForceLoadOnCall']
        flags['NoDisplaySurface'] = False  #originalFlags['NoSurface']
        flags['TimerBasedMovements'] = originalFlags['TimedMovements']
        newFrame.maxObjects = frame.maxObjects
        newFrame.password = frame.password or ''
        newFrame.lastViewedX = 320
        newFrame.lastViewedY = 240
        newFrame.palette = newFrame.palette
        newFrame.stampHandle = 12
        newFrame.activeLayer = 0
        newFrame.layers = layers = []
        try:
            for layer in frame.layers.items:
                newLayer = newFrame.new(Layer)
                newLayer.name = layer.name
                flags = newLayer.flags
                originalFlags = layer.flags
                flags['HideAtStart'] = originalFlags['ToHide']
                flags['Visible'] = True
                flags['NoBackground'] = originalFlags['DoNotSaveBackground']
                flags['WrapHorizontally'] = originalFlags['WrapHorizontally']
                flags['WrapVertically'] = originalFlags['WrapVertically']
                newLayer.xCoefficient = layer.xCoefficient
                newLayer.yCoefficient = layer.yCoefficient
                layers.append(newLayer)
        except AttributeError:
            # MMF 1.5
            layer = newFrame.new(Layer)
            layer.name = 'Default Layer'
            layer.xCoefficient = layer.yCoefficient = 1.0
            layers.append(layer)
        newFrameItems = set()
        newFrame.instances = instances = []
        print_func('Translating frame %r (%s)' % (newFrame.name, index))
        if frame.instances is not None:
            for instanceIndex, instance in enumerate(frame.instances.items):
                try:
                    frameItem = frameItems[instance.objectInfo]
                except KeyError:
                    continue
                newFrameItems.add(frameItem)
                newInstance = newFrame.new(FrameInstance)
                newInstance.x = instance.x
                newInstance.y = instance.y
                newInstance.handle = instanceIndex
                if instance.parentType != NONE_PARENT:
                    newInstance.flags = 8
                else:
                    newInstance.flags = 0
                newInstance.parentType = instance.parentType
                newInstance.itemHandle = instance.objectInfo
                parentHandle = instance.parentHandle
                newInstance.parentHandle = parentHandle
                newInstance.layer = instance.layer
                instances.append(newInstance)
        newFrame.items = list(newFrameItems)
        newFrame.folders = folders = []
        for item in newFrame.items:
            newFolder = newFrame.new(ItemFolder)
            newFolder.items = [item.handle]
            folders.append(newFolder)
        events = newFrame.events = frame.new(Events)
        events.version = 1027
        events.frameType = 0
        events.items = frame.events.items
        events.objects = objects = []
        for item in newFrame.items:
            newObject = events.new(EventObject)
            objects.append(newObject)
            newObject.handle = item.handle
            newObject.name = item.name
            newObject.typeName = ''
            newObject.itemType = item.objectType
            newObject.objectType = FRAME_ITEM_TYPE
            newObject.flags = 0
            newObject.itemHandle = item.handle
            newObject.instanceHandle = 0xFFFFFFFF
        for k, item in frame.events.qualifiers.iteritems():
            key = (k, item.type)
            objectInfo = item.objectInfo
            if key in qualifiers:
                newObject = qualifiers[key]
                newHandle = newObject.handle
            else:
                newObject = events.new(EventObject)
                qualifiers[key] = newObject
                newHandle = 0
                while 1:
                    if newHandle not in qualifiers and newHandle not in frameItems:
                        break
                    newHandle += 1
                frameItems[newHandle] = newObject
                newObject.handle = newHandle
                newObject.systemQualifier = item.qualifier
                newObject.name = ''
                newObject.typeName = ''
                newObject.itemType = item.type
                newObject.objectType = SYSTEM_ITEM_TYPE
                newObject.flags = 0
            for eventGroup in frame.events.items:
                for aceList in (eventGroup.actions, eventGroup.conditions):
                    for ace in aceList:
                        if ace.objectInfo == objectInfo:
                            ace.objectInfo = newHandle
                        for parameter in ace.items:
                            parameter = parameter.loader
                            if hasattr(parameter, 'objectInfo'):
                                if parameter.objectInfo == objectInfo:
                                    parameter.objectInfo = newHandle
                            if hasattr(parameter, 'objectInfoParent'):
                                if parameter.objectInfoParent == objectInfo:
                                    parameter.objectInfoParent = newHandle
                            if hasattr(parameter, 'position'):
                                position = parameter.position
                                if position.objectInfoParent == objectInfo:
                                    position.objectInfoParent = newHandle
                            if parameter.isExpression:
                                for expression in parameter.items:
                                    if expression.objectInfo == objectInfo:
                                        expression.objectInfo = newHandle
            objects.append(newObject)
        # group stuff
        groups = {}
        groupId = 0

        def loop_parameters():
            for eventGroup in frame.events.items:
                for aceList in (eventGroup.actions, eventGroup.conditions):
                    for ace in aceList:
                        for parameter in ace.items:
                            yield parameter.getName(), parameter.loader

        for name, parameter in loop_parameters():
            if name == 'GROUP':
                print "loopname GROUP"
                offset = parameter.offset
                print "offset:"
                print offset
                if onepointfive:
                    offset += 2
                else:
                    offset -= 2
                groups[offset] = groupId
                parameter.id = groupId
                parameter.password = make_group_checksum('', parameter.name)
                groupId += 1

        for name, parameter in loop_parameters():
            if name == 'GROUPOINTER':
                parameter.id = groups[parameter.pointer]
                parameter.savedPointer = parameter.pointer = 0

        newFrame.chunks = mfa.new(ChunkList)
        mfa.frames.append(save_data_loader(newFrame))
        frame.close()

    return mfa