Esempio n. 1
0
    public async Task <SpriteResourceContext> DeserializeSprite(string fileName, MonsterMetadata metadata)
    {
        var dataFile   = new FileDataSource("monsterFile", fileName);
        var palEntries = metadata.ColorDepth == TileColorDepth.Bpp4 ? 16 : 8;

        var paletteSources = Enumerable.Range(0, palEntries)
                             .Select(x => (IColorSource) new FileColorSource(new BitAddress(PaletteOffset + 16 * metadata.PaletteID + x * 2, 0), Endian.Little))
                             .ToList();

        var pal = new Palette("monsterPalette", new ColorFactory(), ColorModel.Bgr15, paletteSources, true, PaletteStorageSource.Project);

        pal.DataSource = dataFile;

        Console.WriteLine(pal.GetNativeColor(0).ToString());

        int arrangerWidth  = metadata.TileSetSize == TileSetSize.Small ? 8 : 16;
        int arrangerHeight = metadata.TileSetSize == TileSetSize.Small ? 8 : 16;

        var formData    = new byte[arrangerWidth * arrangerHeight / 8];
        int formAddress = metadata.TileSetSize == TileSetSize.Small ? FormSmallOffset + 8 * metadata.FormID : FormLargeOffset + 32 * metadata.FormID;

        //dataFile.Stream.Seek(formAddress, SeekOrigin.Begin);
        //var length = await dataFile.Stream.ReadAsync(formData, 0, formData.Length);
        dataFile.Read(new BitAddress(formAddress, 0), formData.Length * 8, formData);

        if (metadata.TileSetSize == TileSetSize.Large) // Requires endian swapping the tile form
        {
            EndianSwapArray(formData);
        }
        var bitStream = BitStream.OpenRead(formData, formData.Length * 8);

        var arranger = ArrangerBuilder.WithTiledLayout()
                       .WithArrangerElementSize(arrangerWidth, arrangerHeight)
                       .WithElementPixelSize(8, 8)
                       .WithPixelColorType(PixelColorType.Indexed)
                       .WithName("monsterArranger")
                       .AsScatteredArranger()
                       .Build();

        int elementsStored = 0;
        int tileOffset     = TileSetOffset + 8 * metadata.TileSetID;
        int tileSize       = metadata.ColorDepth == TileColorDepth.Bpp4 ? 32 : 24;

        for (int y = 0; y < arrangerHeight; y++)
        {
            for (int x = 0; x < arrangerWidth; x++)
            {
                if (bitStream.ReadBit() == 1)
                {
                    IGraphicsCodec codec   = metadata.ColorDepth == TileColorDepth.Bpp4 ? new Snes4bppCodec(8, 8) : new Snes3bppCodec(8, 8);
                    var            element = new ArrangerElement(x * 8, y * 8, dataFile, new BitAddress(tileOffset * 8), codec, pal);
                    tileOffset += tileSize;
                    arranger.SetElement(element, x, y);
                    elementsStored++;
                }
            }
        }

        return(new SpriteResourceContext(dataFile, pal, arranger));
    }
Esempio n. 2
0
    public static ScatteredArranger CreateIndexedArrangerFromImage(string imageFile, ColorModel colorModel,
                                                                   bool zeroIndexTransparent, ICodecFactory factory, IGraphicsCodec codec)
    {
        var image        = new Bitmap(imageFile);
        var imagePalette = image.Palette;

        var palette      = new Palette("testPalette", new ColorFactory(), colorModel, zeroIndexTransparent, PaletteStorageSource.Project);
        var colorSources = imagePalette.Entries
                           .Select(x => new ProjectNativeColorSource(new ColorRgba32(x.R, x.G, x.B, x.A)));

        palette.SetColorSources(colorSources);

        var file   = new MemoryDataSource("test", image.Width * image.Height);
        var elemsX = image.Width / codec.Width;
        var elemsY = image.Height / codec.Height;

        var arranger = new ScatteredArranger("testArranger", PixelColorType.Indexed, ElementLayout.Tiled, elemsX, elemsY, codec.Width, codec.Height);

        var address = new BitAddress(0);

        for (int y = 0; y < elemsY; y++)
        {
            for (int x = 0; x < elemsX; x++)
            {
                var element = new ArrangerElement(x, y, file, address, factory.CloneCodec(codec), palette);
                address += codec.StorageSize;

                arranger.SetElement(element, x, y);
            }
        }

        return(arranger);
    }
Esempio n. 3
0
    private MagitekResult <ArrangerElement?> CreateElement(ScatteredArrangerModel arrangerModel, int x, int y)
    {
        var            elementModel = arrangerModel.ElementGrid[x, y];
        IGraphicsCodec codec        = default;
        Palette        palette      = default;
        DataSource     df           = default;
        var            address      = BitAddress.Zero;

        if (elementModel is null)
        {
            return(new MagitekResult <ArrangerElement?> .Success(null));
        }
        else if (arrangerModel.ColorType == PixelColorType.Indexed)
        {
            if (!string.IsNullOrWhiteSpace(elementModel.DataFileKey))
            {
                Tree.TryGetItem <DataSource>(elementModel.DataFileKey, out df);
            }

            address = elementModel.FileAddress;
            var paletteKey = elementModel.PaletteKey;
            palette = ResolvePalette(paletteKey);

            if (palette is null)
            {
                return(new MagitekResult <ArrangerElement?> .Failed($"Could not resolve palette '{paletteKey}' referenced by arranger '{arrangerModel.Name}'"));
            }

            codec = _codecFactory.GetCodec(elementModel.CodecName, new Size(arrangerModel.ElementPixelSize.Width, arrangerModel.ElementPixelSize.Height));
        }
        else if (arrangerModel.ColorType == PixelColorType.Direct)
        {
            if (!string.IsNullOrWhiteSpace(elementModel.DataFileKey))
            {
                Tree.TryGetItem <DataSource>(elementModel.DataFileKey, out df);
            }

            address = elementModel.FileAddress;
            codec   = _codecFactory.GetCodec(elementModel.CodecName, new Size(arrangerModel.ElementPixelSize.Width, arrangerModel.ElementPixelSize.Height));
        }
        else
        {
            return(new MagitekResult <ArrangerElement?> .Failed($"{nameof(CreateElement)}: Arranger '{arrangerModel.Name}' has invalid {nameof(PixelColorType)} '{arrangerModel.ColorType}'"));
        }

        var pixelX = x * arrangerModel.ElementPixelSize.Width;
        var pixelY = y * arrangerModel.ElementPixelSize.Height;
        var el     = new ArrangerElement(pixelX, pixelY, df, address, codec, palette, elementModel.Mirror, elementModel.Rotation);

        return(new MagitekResult <ArrangerElement?> .Success(el));
    }
Esempio n. 4
0
    /// <summary>
    /// Lays out ArrangerElements
    /// </summary>
    private void PerformLayout()
    {
        var address = Address;

        var patternsX = ArrangerElementSize.Width / TileLayout.Width;
        var patternsY = ArrangerElementSize.Height / TileLayout.Height;

        for (int y = 0; y < patternsY; y++)
        {
            for (int x = 0; x < patternsX; x++)
            {
                foreach (var pos in TileLayout.Pattern)
                {
                    var posX = x * TileLayout.Width + pos.X;
                    var posY = y * TileLayout.Height + pos.Y;

                    var el = new ArrangerElement(posX * ElementPixelSize.Width,
                                                 posY * ElementPixelSize.Height, ActiveDataSource, address, ActiveCodec, ActivePalette);

                    if (el.Codec.Layout == ImageLayout.Tiled)
                    {
                        address += ActiveCodec.StorageSize;
                    }
                    else if (el.Codec.Layout == ImageLayout.Single)
                    {
                        address += ElementPixelSize.Width * ActiveCodec.ColorDepth / 4; // TODO: Fix sequential arranger offsets to be bit-wise
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    ElementGrid[posY, posX] = el;
                }
            }
        }

        Move(Address);
    }
Esempio n. 5
0
    public void Setup(string dataFileName, string arrangerName)
    {
        using (var fs = File.Create(dataFileName))
        {
            Random rng  = new Random();
            var    data = new byte[3 * 16 * 32];
            rng.NextBytes(data);
            fs.Write(data);
        }

        _df = new FileDataSource("FileSource", Path.GetFullPath(dataFileName));

        _arranger = new ScatteredArranger(arrangerName, PixelColorType.Indexed, ElementLayout.Tiled, 16, 32, 8, 8);

        for (int y = 0; y < _arranger.ArrangerElementSize.Height; y++)
        {
            for (int x = 0; x < _arranger.ArrangerElementSize.Width; x++)
            {
                var el = new ArrangerElement(x * 8, y * 8, _df, new BitAddress(24 * x + 24 * x * y), _codec, _pal);
                _arranger.SetElement(el, x, y);
            }
        }
    }