Exemplo n.º 1
0
    public MagitekResult AddScatteredArranger(ScatteredArrangerModel arrangerModel, string parentNodePath, string fileLocation)
    {
        var arranger = new ScatteredArranger(arrangerModel.Name, arrangerModel.ColorType, arrangerModel.Layout,
                                             arrangerModel.ArrangerElementSize.Width, arrangerModel.ArrangerElementSize.Height, arrangerModel.ElementPixelSize.Width, arrangerModel.ElementPixelSize.Height);

        for (int x = 0; x < arrangerModel.ElementGrid.GetLength(0); x++)
        {
            for (int y = 0; y < arrangerModel.ElementGrid.GetLength(1); y++)
            {
                var result = CreateElement(arrangerModel, x, y);

                if (result.IsT0)
                {
                    arranger.SetElement(result.AsT0.Result, x, y);
                }
                else if (result.IsT1)
                {
                    return(new MagitekResult.Failed(result.AsT1.Reason));
                }
            }
        }

        var arrangerNode = new ArrangerNode(arranger.Name, arranger)
        {
            DiskLocation = fileLocation,
            Model        = arrangerModel
        };

        Tree.TryGetNode(parentNodePath, out var parentNode);
        parentNode.AttachChildNode(arrangerNode);

        return(MagitekResult.SuccessResult);
    }
Exemplo n.º 2
0
 /// <summary>
 /// Returns the enumeration of a subsection of Elements in the grid in a left-to-right, row-by-row order
 /// </summary>
 /// <param name="elemX">Starting x-coordinate in element coordinates</param>
 /// <param name="elemY">Starting y-coordinate in element coordinates</param>
 /// <param name="width">Number of elements to enumerate in x-direction</param>
 /// <param name="height">Number of elements to enumerate in y-direction</param>
 /// <returns></returns>
 public static IEnumerable <ArrangerElementModel> EnumerateElements(this ScatteredArrangerModel model,
                                                                    int elemX, int elemY, int width, int height)
 {
     for (int y = 0; y < height; y++)
     {
         for (int x = 0; x < width; x++)
         {
             yield return(model.ElementGrid[x + elemX, y + elemY]);
         }
     }
 }
Exemplo n.º 3
0
    public static ScatteredArrangerModel MapToModel(this ScatteredArranger arranger, Dictionary <IProjectResource, string> resourceMap)
    {
        var model = new ScatteredArrangerModel()
        {
            Name = arranger.Name,
            ArrangerElementSize = arranger.ArrangerElementSize,
            ElementPixelSize    = arranger.ElementPixelSize,
            Layout    = arranger.Layout,
            ColorType = arranger.ColorType
        };

        model.ElementGrid = new ArrangerElementModel[model.ArrangerElementSize.Width, model.ArrangerElementSize.Height];

        for (int x = 0; x < model.ElementGrid.GetLength(0); x++)
        {
            for (int y = 0; y < model.ElementGrid.GetLength(1); y++)
            {
                if (arranger.GetElement(x, y) is ArrangerElement el)
                {
                    model.ElementGrid[x, y] = MapToModel(el, x, y);
                }
            }
        }

        return(model);

        ArrangerElementModel MapToModel(ArrangerElement el, int elemX, int elemY)
        {
            var model = new ArrangerElementModel
            {
                FileAddress = el.SourceAddress,
                PositionX   = elemX,
                PositionY   = elemY,
                CodecName   = el.Codec.Name,
                Mirror      = el.Mirror,
                Rotation    = el.Rotation
            };

            if (el.Source is not null && resourceMap.TryGetValue(el.Source, out var dataFileKey))
            {
                model.DataFileKey = dataFileKey;
            }

            if (el.Palette is not null && resourceMap.TryGetValue(el.Palette, out var paletteKey))
            {
                model.PaletteKey = paletteKey;
            }

            return(model);
        }
    }
Exemplo n.º 4
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));
    }
Exemplo n.º 5
0
 public static string FindMostFrequentElementPropertyValue(this ScatteredArrangerModel model, Func <ArrangerElementModel, string> selector)
 {
     return(EnumerateElements(model)
            .OfType <ArrangerElementModel>()
            .Select(selector)
            .GroupBy(x => x)
            .Select(group => new
     {
         Item = group.Key,
         Count = group.Count()
     })
            .MaxBy(x => x.Count)
            ?.Item);
 }
Exemplo n.º 6
0
 /// <summary>
 /// Returns the enumeration of all Elements in the grid in a left-to-right, row-by-row order
 /// </summary>
 /// <returns></returns>
 public static IEnumerable <ArrangerElementModel> EnumerateElements(this ScatteredArrangerModel model) =>
 model.EnumerateElements(0, 0, model.ArrangerElementSize.Width, model.ArrangerElementSize.Height);
Exemplo n.º 7
0
    private bool TryDeserializeScatteredArranger(XElement element, string resourceName, out ScatteredArrangerModel arrangerModel)
    {
        var model = new ScatteredArrangerModel();

        model.Name = resourceName;
        var elementsx          = int.Parse(element.Attribute("elementsx").Value); // Width of arranger in elements
        var elementsy          = int.Parse(element.Attribute("elementsy").Value); // Height of arranger in elements
        var width              = int.Parse(element.Attribute("width").Value);     // Width of element in pixels
        var height             = int.Parse(element.Attribute("height").Value);    // Height of element in pixels
        var defaultCodecName   = element.Attribute("defaultcodec").Value;
        var defaultDataFileKey = element.Attribute("defaultdatafile").Value;
        var defaultPaletteKey  = element.Attribute("defaultpalette")?.Value ?? _globalDefaultPalette.Name;
        var layoutName         = element.Attribute("layout").Value;
        var colorType          = element.Attribute("color")?.Value ?? "indexed";
        var elementList        = element.Descendants("element");

        if (layoutName == "tiled")
        {
            model.Layout = ElementLayout.Tiled;
        }
        else if (layoutName == "single")
        {
            model.Layout = ElementLayout.Single;
        }
        else
        {
            throw new XmlException($"Unsupported arranger layout type ('{layoutName}') for arranger '{model.Name}'");
        }

        if (colorType == "indexed")
        {
            model.ColorType = PixelColorType.Indexed;
        }
        else if (colorType == "direct")
        {
            model.ColorType = PixelColorType.Direct;
        }
        else
        {
            throw new XmlException($"Unsupported pixel color type ('{colorType}') for arranger '{model.Name}'");
        }

        model.ArrangerElementSize = new Size(elementsx, elementsy);
        model.ElementGrid         = new ArrangerElementModel[elementsx, elementsy];
        model.ElementPixelSize    = new Size(width, height);

        var xmlElements = elementList.Select(e => new
        {
            fileoffset = long.Parse(e.Attribute("fileoffset").Value, System.Globalization.NumberStyles.HexNumber),
            bitoffset  = e.Attribute("bitoffset"),
            posx       = int.Parse(e.Attribute("posx").Value),
            posy       = int.Parse(e.Attribute("posy").Value),
            format     = e.Attribute("codec"),
            palette    = e.Attribute("palette"),
            datafile   = e.Attribute("datafile"),
            mirror     = e.Attribute("mirror"),
            rotation   = e.Attribute("rotation")
        });

        foreach (var xmlElement in xmlElements)
        {
            var el = new ArrangerElementModel();

            el.DataFileKey = xmlElement.datafile?.Value ?? defaultDataFileKey;
            el.PaletteKey  = xmlElement.palette?.Value ?? defaultPaletteKey;
            el.CodecName   = xmlElement.format?.Value ?? defaultCodecName;
            el.PositionX   = xmlElement.posx;
            el.PositionY   = xmlElement.posy;

            if (xmlElement.bitoffset is not null)
            {
                el.FileAddress = new BitAddress(xmlElement.fileoffset, int.Parse(xmlElement.bitoffset.Value));
            }
            else
            {
                el.FileAddress = new BitAddress(xmlElement.fileoffset, 0);
            }

            el.Mirror = xmlElement.mirror?.Value switch
            {
                "none" => MirrorOperation.None,
                "horizontal" => MirrorOperation.Horizontal,
                "vertical" => MirrorOperation.Vertical,
                "both" => MirrorOperation.Both,
                _ => MirrorOperation.None
            };

            el.Rotation = xmlElement.rotation?.Value switch
            {
                "none" => RotationOperation.None,
                "left" => RotationOperation.Left,
                "right" => RotationOperation.Right,
                "turn" => RotationOperation.Turn,
                _ => RotationOperation.None
            };

            model.ElementGrid[xmlElement.posx, xmlElement.posy] = el;
        }

        arrangerModel = model;
        return(true);
    }
}