Exemplo n.º 1
0
    public void Build_SequentialArranger()
    {
        var codecFactory = new CodecFactory(new());
        var memorySource = new MemoryDataSource("TestMemoryFile", 2 * 256 * 512);

        SequentialArranger arranger = ArrangerBuilder
                                      .WithSingleLayout()
                                      .WithElementPixelSize(256, 512)
                                      .WithPixelColorType(PixelColorType.Direct)
                                      .WithName("SequentialTestArranger")
                                      .AsSequentialArranger(codecFactory)
                                      .WithDataFile(memorySource)
                                      .WithCodecName("PSX 16bpp")
                                      .Build();

        Assert.That(arranger.Layout == ElementLayout.Single);
        Assert.That(arranger.ArrangerElementSize == new Size(1, 1));
        Assert.That(arranger.ElementPixelSize == new Size(256, 512));
        Assert.That(arranger.ColorType == PixelColorType.Direct);
        Assert.That(arranger.Name == "SequentialTestArranger");
        Assert.That(arranger.ActiveCodec.Name == "PSX 16bpp");
        Assert.That(arranger.ActiveCodec.ColorType == PixelColorType.Direct);
        Assert.That(arranger.ActiveCodec.Layout == ImageLayout.Single);
        Assert.That(arranger.ActiveCodec.Width == 256);
        Assert.That(arranger.ActiveCodec.Height == 512);
        Assert.That(arranger.ActivePalette is null);
        Assert.That(arranger.ActiveDataSource.Name == "TestMemoryFile");
    }
Exemplo n.º 2
0
    /// <summary>
    /// Moves a Sequential Arranger's file position and updates each Element
    /// Will not move outside of the bounds of the underlying file
    /// </summary>
    /// <param name="moveType">Type of move requested</param>
    /// <returns>Updated address of first element</returns>
    public static BitAddress Move(this SequentialArranger arranger, ArrangerMoveType moveType)
    {
        if (arranger.Mode != ArrangerMode.Sequential)
        {
            throw new InvalidOperationException($"{nameof(Move)}: Arranger {arranger.Name} is not in sequential mode");
        }

        var  initialAddress = arranger.Address;
        var  newAddress     = initialAddress;
        long bitDelta       = 0;

        var patternWidth  = arranger.TileLayout?.Width ?? 1;
        var patternHeight = arranger.TileLayout?.Height ?? 1;

        switch (moveType) // Calculate the new address based on the movement command. Negative and post-EOF addresses are handled after the switch
        {
        case ArrangerMoveType.ByteDown:
            newAddress += 8;
            break;

        case ArrangerMoveType.ByteUp:
            newAddress -= 8;
            break;

        case ArrangerMoveType.RowDown:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ArrangerElementSize.Width * arranger.ActiveCodec.StorageSize * patternHeight;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = arranger.ActiveCodec.StorageSize / arranger.ArrangerPixelSize.Height;
            }

            newAddress += bitDelta;
            break;

        case ArrangerMoveType.RowUp:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ArrangerElementSize.Width * arranger.ActiveCodec.StorageSize * patternHeight;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = arranger.ActiveCodec.StorageSize / arranger.ArrangerPixelSize.Height;
            }
            newAddress -= bitDelta;
            break;

        case ArrangerMoveType.ColRight:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ActiveCodec.StorageSize * patternWidth * patternHeight;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = 16 * arranger.ActiveCodec.StorageSize * arranger.ActiveCodec.Height / arranger.ActiveCodec.Width;
            }
            newAddress += bitDelta;
            break;

        case ArrangerMoveType.ColLeft:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ActiveCodec.StorageSize * patternWidth * patternHeight;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = 16 * arranger.ActiveCodec.StorageSize * arranger.ActiveCodec.Height / arranger.ActiveCodec.Width;
            }
            newAddress -= bitDelta;
            break;

        case ArrangerMoveType.PageDown:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ArrangerElementSize.Width * arranger.ActiveCodec.StorageSize * arranger.ArrangerElementSize.Height / 2;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = arranger.ActiveCodec.StorageSize / 2;
            }
            newAddress += bitDelta;
            break;

        case ArrangerMoveType.PageUp:
            if (arranger.Layout == ElementLayout.Tiled)
            {
                bitDelta = arranger.ArrangerElementSize.Width * arranger.ActiveCodec.StorageSize * arranger.ArrangerElementSize.Height / 2;
            }
            else if (arranger.Layout == ElementLayout.Single)
            {
                bitDelta = arranger.ActiveCodec.StorageSize / 2;
            }
            newAddress -= bitDelta;
            break;

        case ArrangerMoveType.Home:
            newAddress = BitAddress.Zero;
            break;

        case ArrangerMoveType.End:
            newAddress = new BitAddress(arranger.FileSize * 8 - arranger.ArrangerBitSize);
            break;
        }

        var maxAddress = new BitAddress(arranger.FileSize * 8 - arranger.ArrangerBitSize);

        if (maxAddress.Offset < 0)
        {
            maxAddress = BitAddress.Zero;
        }

        newAddress = new BitAddress(Math.Clamp(newAddress.Offset, 0, maxAddress.Offset));

        if (initialAddress != newAddress)
        {
            newAddress = arranger.Move(newAddress);
        }

        return(newAddress);
    }