Exemplo n.º 1
0
        void TrackFrameCount_ValueChanged(object sender, EventArgs e)
        {
            var asset = _core.SelectedObject;

            if (_logicalSprite != null && asset != null)
            {
                int?newHeight =
                    trackFrameCount.Value <= 1
                        ? (int?)null
                        : _logicalSprite.Height / trackFrameCount.Value;

                if (!asset.Parent.Height.HasValue &&
                    asset.Parent.Format == FileFormat.FixedSizeSprite &&
                    asset.Height != newHeight)
                {
                    asset.Height   = newHeight;
                    _logicalSprite = null; // Force sprite reload
                    _visualSprite  = null;
                    Render();
                }
            }

            if (sender != numFrameCount && (int)numFrameCount.Value != trackFrameCount.Value)
            {
                numFrameCount.Value = trackFrameCount.Value;
            }
        }
Exemplo n.º 2
0
        public object Load(BinaryReader br, long streamLength, string name, AssetInfo config)
        {
            Debug.Assert(config.Transposed != true);
            long initialPosition = br.BaseStream.Position;
            var  sizes           = ParseSpriteSizes(config.SubSprites);

            AlbionSprite sprite = new AlbionSprite
            {
                Name          = name,
                Width         = 0,
                UniformFrames = false,
                Frames        = new List <AlbionSprite.Frame>()
            };

            int currentY   = 0;
            var frameBytes = new List <byte[]>();

            foreach (var(width, height) in sizes)
            {
                if (br.BaseStream.Position >= initialPosition + streamLength)
                {
                    break;
                }

                var bytes = br.ReadBytes(width * height);
                sprite.Frames.Add(new AlbionSprite.Frame(0, currentY, width, height));
                frameBytes.Add(bytes);

                currentY += height;
                if (width > sprite.Width)
                {
                    sprite.Width = width;
                }
            }

            sprite.Height    = currentY;
            sprite.PixelData = new byte[sprite.Frames.Count * sprite.Width * currentY];

            for (int n = 0; n < sprite.Frames.Count; n++)
            {
                var frame = sprite.Frames[n];

                for (int j = 0; j < frame.Height; j++)
                {
                    for (int i = 0; i < frame.Width; i++)
                    {
                        sprite.PixelData[(frame.Y + j) * sprite.Width + frame.X + i] = frameBytes[n][j * frame.Width + i];
                    }
                }
            }

            Debug.Assert(br.BaseStream.Position == initialPosition + streamLength);
            return(sprite);
        }
Exemplo n.º 3
0
        Bitmap GenerateBitmap(AlbionSprite sprite, int frameNumber, int width, int magnify, uint[] palette)
        {
            var frame  = sprite.Frames[frameNumber];
            var offset = frame.Y * sprite.Width;
            int height = Math.Min(frame.Height, (sprite.PixelData.Length - offset + (width - 1)) / width);

            if (height == 0)
            {
                return(new Bitmap(1, 1));
            }
            Bitmap bmp;

            if (canvas.Image?.Width == width * magnify && canvas.Image?.Height == height * magnify)
            {
                bmp = (Bitmap)canvas.Image;
            }
            else
            {
                bmp = new Bitmap(width * magnify, height * magnify);
            }

            var d = bmp.LockBits(
                new Rectangle(0, 0, bmp.Width, bmp.Height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format24bppRgb);

            try
            {
                for (int n = offset; n < offset + width * height && n < sprite.PixelData.Length; n++)
                {
                    unsafe
                    {
                        for (int my = 0; my < magnify; my++)
                        {
                            for (int mx = 0; mx < magnify; mx++)
                            {
                                int   x     = magnify * ((n - offset) % width) + mx;
                                int   y     = magnify * ((n - offset) / width) + my;
                                byte *p     = (byte *)d.Scan0 + y * d.Stride + x * 3;
                                byte  color = sprite.PixelData[n];

                                p[0] = (byte)((palette[color] & 0x00ff0000) >> 16);
                                p[1] = (byte)((palette[color] & 0x0000ff00) >> 8);
                                p[2] = (byte)(palette[color] & 0x000000ff);
                            }
                        }
                    }
                }
            }
            finally { bmp.UnlockBits(d); }

            return(bmp);
        }
Exemplo n.º 4
0
        void TrackWidth_ValueChanged(object sender, EventArgs e)
        {
            var asset = _core.SelectedObject;

            if (asset == null)
            {
                return;
            }

            if (!asset.Parent.Width.HasValue &&
                asset.Parent.Format == FileFormat.FixedSizeSprite &&
                asset.Width != trackWidth.Value)
            {
                asset.Width    = trackWidth.Value;
                _logicalSprite = null; // Force sprite reload
                _visualSprite  = null;
                Render();
            }

            if (sender != numWidth && (int)numWidth.Value != trackWidth.Value)
            {
                numWidth.Value = trackWidth.Value;
            }
        }
Exemplo n.º 5
0
        public object Serdes(object existing, AssetInfo config, AssetMapping mapping, ISerializer s)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }
            if (s.Mode != SerializerMode.Reading)
            {
                throw new NotImplementedException("Fixed size sprite saving not currently supported");
            }

            var streamLength = s.BytesRemaining;

            if (streamLength == 0)
            {
                return(null);
            }

            int width  = config.EffectiveWidth;
            int height = config.EffectiveHeight;

            if (width == 0)
            {
                width = (int)Math.Sqrt(streamLength);
            }
            if (height == 0)
            {
                height = (int)streamLength / width;
            }

            // ApiUtil.Assert(streamLength % width == 0);
            // ApiUtil.Assert(streamLength % (width * height) == 0);

            // long initialPosition = s.BaseStream.Position;
            int spriteCount = Math.Max(1, unchecked ((int)(streamLength / (width * height))));

            height = (int)streamLength / (width * spriteCount);

            int currentY  = 0;
            var pixelData = new byte[spriteCount * width * height];
            var frames    = new AlbionSpriteFrame[spriteCount];

            for (int n = 0; n < spriteCount; n++)
            {
                frames[n] = new AlbionSpriteFrame(0, currentY, width, height);

                var bytes = s.ByteArray(null, null, width * height);
                for (int i = 0; i < width * height; i++)
                {
                    pixelData[n * width * height + i] = bytes[i];
                }

                currentY += height;
            }

            var sprite = new AlbionSprite(config.AssetId.ToString(), width, height * spriteCount, true, pixelData, frames);

            if (!config.Transposed)
            {
                return(sprite);
            }

            int rotatedFrameHeight = width;

            pixelData = new byte[spriteCount * width * height];
            frames    = new AlbionSpriteFrame[spriteCount];
            for (int n = 0; n < spriteCount; n++)
            {
                frames[n] = new AlbionSpriteFrame(0, rotatedFrameHeight * n, height, rotatedFrameHeight);

                ApiUtil.RotateImage(width, height,
                                    new ReadOnlySpan <byte>(sprite.PixelData, n * width * height, width * height),
                                    new Span <byte>(pixelData, n * width * height, width * height));
            }

            return(new AlbionSprite(config.AssetId.ToString(), height, width * spriteCount, true, pixelData, frames));
        }
Exemplo n.º 6
0
        void Render()
        {
            const int magnify = 3;
            var       asset   = _core.SelectedObject;

            if (asset == null)
            {
                return;
            }

            Bitmap bmp;

            if (IsSprite(asset.Parent.Format))
            {
                if (asset.Filename != _logicalSprite?.Name)
                {
                    // Ugh
                    bool isRotated = asset.Parent.Transposed ?? false;
                    asset.Parent.Transposed = false;
                    _logicalSprite          = LoadSprite(asset.Filename, asset);
                    asset.Parent.Transposed = isRotated;

                    _visualSprite = isRotated ? LoadSprite(asset.Filename, asset) : _logicalSprite;
                }

                if (_logicalSprite == null)
                {
                    return;
                }

                trackFrameCount.Maximum = _logicalSprite.Height;
                numFrameCount.Maximum   = trackFrameCount.Maximum;
                trackFrame.Maximum      = _logicalSprite.Frames.Count - 1;
                numFrame.Maximum        = trackFrame.Maximum;

                if (trackWidth.Value == 1)
                {
                    trackWidth.Value = _logicalSprite.Width;
                }

                var    palette    = (AlbionPalette)(chkListPalettes.SelectedItem ?? chkListPalettes.Items[0]);
                uint[] curPalette = palette.GetPaletteAtTime((int)((DateTime.Now - _startTime).TotalSeconds * 4));

                var width = _visualSprite.Width;
                var frame = Math.Max(0, trackFrame.Value);
                bmp = GenerateBitmap(_visualSprite, frame, width, magnify, curPalette);
            }
            //else if (asset.Layer == FileFormat.Map2D)
            //{
            //    _logicalSprite = null;
            //    _visualSprite = null;
            //    bmp = new Bitmap(1, 1);
            //}
            else
            {
                _logicalSprite = null;
                _visualSprite  = null;
                bmp            = new Bitmap(1, 1);
            }

            canvas.Image = bmp;
        }
Exemplo n.º 7
0
        public object Load(BinaryReader br, long streamLength, string name, AssetInfo config)
        {
            if (streamLength == 0)
            {
                return(null);
            }

            int width  = config.EffectiveWidth;
            int height = config.EffectiveHeight;

            if (width == 0)
            {
                width = (int)Math.Sqrt(streamLength);
            }
            if (height == 0)
            {
                height = (int)streamLength / width;
            }

            // Debug.Assert(streamLength % width == 0);
            // Debug.Assert(streamLength % (width * height) == 0);

            long initialPosition = br.BaseStream.Position;
            int  spriteCount     = unchecked ((int)(streamLength / (width * height)));

            height = (int)streamLength / (width * spriteCount);

            var sprite = new AlbionSprite
            {
                Name          = name,
                Width         = width,
                Height        = height * spriteCount,
                Frames        = new AlbionSprite.Frame[spriteCount],
                UniformFrames = true,
                PixelData     = new byte[spriteCount * width * height]
            };

            int currentY = 0;

            for (int n = 0; n < spriteCount; n++)
            {
                sprite.Frames[n] = new AlbionSprite.Frame(0, currentY, width, height);

                var bytes = br.ReadBytes(width * height);
                for (int i = 0; i < width * height; i++)
                {
                    sprite.PixelData[n * width * height + i] = bytes[i];
                }

                currentY += height;
            }

            if (config.Transposed)
            {
                var rotatedSprite = new AlbionSprite
                {
                    Name          = name,
                    Width         = height,
                    Height        = width * spriteCount,
                    Frames        = new AlbionSprite.Frame[spriteCount],
                    UniformFrames = true,
                    PixelData     = new byte[spriteCount * width * height]
                };
                int rotatedFrameHeight = width;

                for (int n = 0; n < spriteCount; n++)
                {
                    rotatedSprite.Frames[n] = new AlbionSprite.Frame(
                        0, rotatedFrameHeight * n,
                        rotatedSprite.Width, rotatedFrameHeight);

                    Util.RotateImage(width, height,
                                     new Span <byte>(sprite.PixelData, n * width * height, width * height),
                                     new Span <byte>(rotatedSprite.PixelData, n * width * height, width * height));
                }

                return(rotatedSprite);
            }

            // Debug.Assert(br.BaseStream.Position == initialPosition + streamLength);
            return(sprite);
        }
Exemplo n.º 8
0
        public object Load(BinaryReader br, long streamLength, AssetKey key, AssetInfo config)
        {
            ApiUtil.Assert(config.Transposed != true);
            var  sprite          = new AlbionSprite();
            long initialPosition = br.BaseStream.Position;

            sprite.Name          = key.ToString();
            sprite.UniformFrames = config.Format == FileFormat.SingleHeaderSprite;

            int width     = br.ReadUInt16();
            int height    = br.ReadUInt16();
            int something = br.ReadByte();

            ApiUtil.Assert(something == 0);
            int spriteCount = br.ReadByte();

            sprite.Frames = new AlbionSprite.Frame[spriteCount];
            var frameBytes = new List <byte[]>();
            int currentY   = 0;

            sprite.Width = 0;
            for (int i = 0; i < spriteCount; i++)
            {
                if (!sprite.UniformFrames && i > 0)
                {
                    width     = br.ReadUInt16();
                    height    = br.ReadUInt16();
                    something = br.ReadByte();
                    ApiUtil.Assert(something == 0);
                    int spriteCount2 = br.ReadByte();
                    ApiUtil.Assert(spriteCount2 == spriteCount);
                }

                var bytes = br.ReadBytes(width * height);
                sprite.Frames[i] = new AlbionSprite.Frame(0, currentY, width, height);
                frameBytes.Add(bytes);

                currentY += height;
                if (width > sprite.Width)
                {
                    sprite.Width = width;
                }
            }

            sprite.Height    = currentY;
            sprite.PixelData = new byte[spriteCount * sprite.Width * currentY];

            for (int n = 0; n < spriteCount; n++)
            {
                var frame = sprite.Frames[n];

                for (int j = 0; j < frame.Height; j++)
                {
                    for (int i = 0; i < frame.Width; i++)
                    {
                        sprite.PixelData[(frame.Y + j) * sprite.Width + frame.X + i] = frameBytes[n][j * frame.Width + i];
                    }
                }
            }

            ApiUtil.Assert(br.BaseStream.Position == initialPosition + streamLength);
            return(sprite);
        }
Exemplo n.º 9
0
        void AddToTree(string location, FullXldInfo xld)
        {
            var      parts = location.Split('\\');
            TreeNode node  = _rootNode;

            foreach (var dir in parts.Take(parts.Length - 1)) // Ensure parent nodes exist
            {
                if (!node.Nodes.ContainsKey(dir))
                {
                    node.Nodes.Add(dir, dir);
                }
                node = node.Nodes[dir];
            }

            string key = parts.Last();

            if (!key.EndsWith(".bin"))
            {
                return;
            }
            key = key.Substring(0, key.Length - 4);
            int number = int.Parse(key);

            if (!xld.Assets.ContainsKey(number))
            {
                xld.Assets[number] = new FullAssetInfo {
                    Width = 32
                }
            }
            ;

            FullAssetInfo asset = xld.Assets[number];

            string name = string.IsNullOrEmpty(asset.Name)
                ? key
                : $"{asset.Name} ({number})";

            if (!node.Nodes.ContainsKey(key))
            {
                var newNode = node.Nodes.Add(key, name);
                newNode.Tag      = asset;
                newNode.NodeFont = (asset.PaletteHints?.Count == 0) ? _boldFont : _defaultFont;
                _nodes[asset]    = newNode;
            }
        }

        (string, FullXldInfo) CurrentXld
        {
            get
            {
                if (fileTree.SelectedNode == null)
                {
                    return(null, null);
                }

                var node = fileTree.SelectedNode;
                if (int.TryParse(fileTree.SelectedNode.Name, out _))
                {
                    node = fileTree.SelectedNode.Parent;
                }

                string filename = "";
                while (node != _rootNode)
                {
                    filename = node.Name + "\\" + filename;
                    node     = node.Parent;
                }

                filename = filename.TrimEnd('\\');
                var fullXldPath = Path.GetFullPath(Path.Combine(Path.Combine(_generalConfig.BasePath, _generalConfig.ExportedXldPath), filename));
                return(_config.Xlds.ContainsKey(filename)
                    ? (fullXldPath, _config.Xlds[filename])
                    : (null, null));
            }
        }

        (string, FullAssetInfo) CurrentObject
        {
            get
            {
                if (!int.TryParse(fileTree.SelectedNode?.Name, out int number))
                {
                    return(null, null);
                }

                var(xldFilename, xld) = CurrentXld;
                if (xld == null || !xld.Assets.ContainsKey(number))
                {
                    return(null, null);
                }

                var filename = $"{xldFilename}\\{number:00}.bin";
                return(filename, xld.Assets[number]);
            }
        }

        void SyncSelectedPalettes()
        {
            var(filename, asset) = CurrentObject;
            if (asset == null)
            {
                return;
            }

            if (asset.PaletteHints == null)
            {
                asset.PaletteHints = new List <int>();
            }

            for (int index = 0; index < chkListPalettes.Items.Count; index++)
            {
                var item = (AlbionPalette)chkListPalettes.Items[index];
                chkListPalettes.SetItemChecked(index, asset.PaletteHints.Contains(item.Id));
            }

            if (!chkListPalettes.GetItemChecked(chkListPalettes.SelectedIndex) && chkListPalettes.CheckedIndices.Count > 0)
            {
                chkListPalettes.SelectedIndex = chkListPalettes.CheckedIndices[0];
            }
        }

        void FileTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var(filename, asset) = CurrentObject;
            if (asset == null)
            {
                return;
            }
            SyncSelectedPalettes();

            trackWidth.Value = asset.EffectiveWidth == 0 ? 1 : asset.EffectiveWidth;
            trackFrame.Value = 0;
            textName.Text    = asset.Name;
            Render();

            if (_logicalSprite != null)
            {
                trackFrameCount.Value = _logicalSprite.Frames.Count;
                if (asset.Parent.Format == FileFormat.FixedSizeSprite &&
                    asset.Height != null &&
                    _logicalSprite.Frames[0].Height != asset.Height)
                {
                    asset.Height = _logicalSprite.Frames[0].Height;
                }
            }
        }

        #region Width
        void TrackWidth_ValueChanged(object sender, EventArgs e)
        {
            var(filename, asset) = CurrentObject;
            if (asset == null)
            {
                return;
            }

            if (!asset.Parent.Width.HasValue &&
                asset.Parent.Format == FileFormat.FixedSizeSprite &&
                asset.Width != trackWidth.Value)
            {
                asset.Width    = trackWidth.Value;
                _logicalSprite = null; // Force sprite reload
                _visualSprite  = null;
                Render();
            }

            if (sender != numWidth && (int)numWidth.Value != trackWidth.Value)
            {
                numWidth.Value = trackWidth.Value;
            }
        }

        void TrackWidth_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.Left && trackWidth.Value != 0)
            {
                trackWidth.Value = (int)(trackWidth.Value / (e.Shift ? 1.5 : 2.0));
                e.Handled        = true;
            }

            if (e.Control && e.KeyCode == Keys.Right)
            {
                var newValue = (int)(trackWidth.Value * (e.Shift ? 1.5 : 2.0));
                if (newValue > trackWidth.Maximum)
                {
                    newValue = trackWidth.Maximum;
                }
                trackWidth.Value = newValue;
                e.Handled        = true;
            }
        }

        void NumWidth_ValueChanged(object sender, EventArgs e)
        {
            if (sender != trackWidth && trackWidth.Value != (int)numWidth.Value)
            {
                trackWidth.Value = (int)numWidth.Value;
            }
        }

        void NumWidth_Enter(object sender, EventArgs e)
        {
            numWidth.Select(0, numWidth.Text.Length);
        }

        #endregion

        void TextName_TextChanged(object sender, EventArgs e)
        {
            var(filename, asset) = CurrentObject;
            if (asset != null)
            {
                asset.Name = textName.Text;
            }
        }

        void TrackFrameCount_ValueChanged(object sender, EventArgs e)
        {
            var(filename, asset) = CurrentObject;
            if (_logicalSprite != null && asset != null)
            {
                int?newHeight =
                    trackFrameCount.Value <= 1
                        ? (int?)null
                        : _logicalSprite.Height / trackFrameCount.Value;

                if (!asset.Parent.Height.HasValue &&
                    asset.Parent.Format == FileFormat.FixedSizeSprite &&
                    asset.Height != newHeight)
                {
                    asset.Height   = newHeight;
                    _logicalSprite = null; // Force sprite reload
                    _visualSprite  = null;
                    Render();
                }
            }

            if (sender != numFrameCount && (int)numFrameCount.Value != trackFrameCount.Value)
            {
                numFrameCount.Value = trackFrameCount.Value;
            }
        }

        void NumFrameCount_ValueChanged(object sender, EventArgs e)
        {
            if (sender != trackFrameCount && trackFrameCount.Value != (int)numFrameCount.Value)
            {
                trackFrameCount.Value = (int)numFrameCount.Value;
            }
        }

        void TrackFrame_ValueChanged(object sender, EventArgs e)
        {
            Render();
            if (sender != numFrame && (int)numFrame.Value != trackFrame.Value)
            {
                numFrame.Value = trackFrame.Value;
            }
        }

        void NumFrame_ValueChanged(object sender, EventArgs e)
        {
            if (sender != trackFrame && trackFrame.Value != (int)numFrame.Value)
            {
                trackFrame.Value = (int)numFrame.Value;
            }
        }

        void BtnSave_Click(object sender, EventArgs e)
        {
            SaveClicked?.Invoke(this, EventArgs.Empty);
        }

        void ChkListPalettes_SelectedIndexChanged(object sender, EventArgs e)
        {
            Render();
        }

        void ChkAnimate_CheckedChanged(object sender, EventArgs e)
        {
            if (chkAnimate.Checked)
            {
                _timer.Start();
            }
            else
            {
                _timer.Stop();
            }
        }

        void FileTree_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.X && _logicalSprite != null)
            {
                trackWidth.Value = _logicalSprite.Frames[0].Height;
            }

            var(_, asset) = CurrentObject;
            if (e.Control && e.KeyCode == Keys.C && asset != null)
            {
                _savedPalettes = asset.PaletteHints.ToList();
            }

            if (e.Control && e.KeyCode == Keys.V && asset != null && _savedPalettes != null)
            {
                asset.PaletteHints.Clear();
                foreach (var palette in _savedPalettes)
                {
                    asset.PaletteHints.Add(palette);
                }
                SyncSelectedPalettes();
            }
        }

        void ChkListPalettes_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            var(_, asset) = CurrentObject;
            if (asset == null)
            {
                return;
            }

            var palette = (AlbionPalette)chkListPalettes.Items[e.Index];

            if (e.NewValue == CheckState.Checked)
            {
                if (!asset.PaletteHints.Contains(palette.Id))
                {
                    asset.PaletteHints.Add(palette.Id);
                }
            }
            else
            {
                asset.PaletteHints.Remove(palette.Id);
            }

            _nodes[asset].NodeFont = asset.PaletteHints?.Count == 0 ? _boldFont : _defaultFont;
        }
    }