Esempio n. 1
0
        public void Render(string name, Bitmap bitmap, int planeCount, Destination destination)
        {
            if (bitmap.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new InvalidOperationException("Only 8bpp format is supported.");
            }

            _transformer.SetBitmap(bitmap);

            _writer.StartObject(destination == Destination.Disk ? ObjectType.Chip: ObjectType.Bitmap, name);


            var byteWidth = _transformer.GetByteWidth();
            var height    = _transformer.GetHeight();

            _writer.WriteCode(Code.Normal, $"{name}_BPL\t\tequ\t{planeCount}");
            _writer.WriteCode(Code.Normal, $"{name}_BWIDTH\t\tequ\t{byteWidth}");
            _writer.WriteCode(Code.Normal, $"{name}_HEIGHT\t\tequ\t{height}");

            var interleaved = _transformer.GetInterleaved(planeCount);

            RunLengthEncoder.ProjectCompression(interleaved);

            _writer.WriteBlob(interleaved);
            _writer.EndObject();
        }
Esempio n. 2
0
        private void ConvertSprite(string name)
        {
            var palette = _definition.Palette.FromInputFolder().LoadIndexedBitmap();
            var bitmap  = _definition.File.FromInputFolder().LoadBitmap();

            var spriteX  = _definition.StartX;
            var spriteY  = _definition.StartY;
            var numTiles = _definition.Count;
            var width    = 16;
            var height   = _definition.Height;
            var maxX     = bitmap.Width / width;
            var maxY     = bitmap.Height / height;

            int i = 0;

            while (i < numTiles)
            {
                var bobBitmap = bitmap.Clone(new Rectangle(spriteX * width, spriteY * height, width, height),
                                             bitmap.PixelFormat);
                bobBitmap = MapColors(palette, bobBitmap);

                _transformer.SetBitmap(bobBitmap);

                var sprite = TrimSprite(_transformer.GetInterleaved(_attached ? PlaneCount * 2 : PlaneCount));
                if (sprite.Any(v => v != 0))
                {
                    if (_attached)
                    {
                        // Given the content (in words) w0,w1,w2,w3,w4,w5,w6,w7
                        // sprite0 will take w0,w1,w4,w5
                        // sprite1 will take w2,w3,w6,w7
                        var sprite0 = new List <byte>();
                        var sprite1 = new List <byte>();
                        var t       = 0;
                        while (t < sprite.Length)
                        {
                            for (var n = 0; n < 4; n++)
                            {
                                sprite0.Add(sprite[t++]);
                            }
                            for (var n = 0; n < 4; n++)
                            {
                                sprite1.Add(sprite[t++]);
                            }
                        }

                        AddSprite(_converted0, sprite0.ToArray());
                        AddSprite(_converted1, sprite1.ToArray());
                    }
                    else
                    {
                        AddSprite(_converted0, sprite);
                    }

                    i++;
                }

                spriteX++;
                if (spriteX >= maxX)
                {
                    spriteY++;
                    if (spriteY >= maxY)
                    {
                        throw new ConversionException(
                                  $"Converting {_definition.File} reached the end of the image trying to get {numTiles} tiles.");
                    }
                    spriteX = 0;
                }
            }

            WriteSpriteData(name, _converted0);
            if (_attached)
            {
                WriteSpriteData(name + "A", _converted1);
            }
        }
        /// <summary>
        /// Renders tiles so each tile's bitplanes are next to each other.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="bitmap"></param>
        /// <param name="tileWidth"></param>
        /// <param name="tileHeight"></param>
        public void Render(string name, Bitmap bitmap, int tileWidth, int tileHeight, int planeCount)
        {
            if (tileWidth % 8 != 0)
            {
                throw new ConversionException($"Tile rendering {name}. Tile width must be a multiple of 8.");
            }
            if (bitmap.Width % tileWidth != 0)
            {
                throw new ConversionException($"Bitmap must be a width that is a multiple of the tile width.");
            }
            if (bitmap.Height % tileHeight != 0)
            {
                throw new ConversionException($"Bitmap must be a height that is a multiple of the tile height.");
            }

            _transformer.SetBitmap(bitmap);

            var byteWidth     = _transformer.GetByteWidth();
            var height        = _transformer.GetHeight();
            var tileByteWidth = tileWidth / 8;
            var tileSize      = tileByteWidth * tileHeight * planeCount;

            var data        = _transformer.GetBitplanes(planeCount);
            var destination = new byte[data.Length + tileSize]; // For one blank tile at the beginning
            var bplSize     = byteWidth * height;

            var tileCounter = 0;

            for (int tileY = 0; tileY < bitmap.Height / tileHeight; tileY++)
            {
                for (int tileX = 0; tileX < bitmap.Width / tileWidth; tileX++)
                {
                    for (int tileRow = 0; tileRow < tileHeight; tileRow++)
                    {
                        for (int bpl = 0; bpl < planeCount; bpl++)
                        {
                            var src = tileX * tileByteWidth
                                      + tileY * tileHeight * byteWidth
                                      + bpl * bplSize
                                      + tileRow * byteWidth;

                            var dst = tileByteWidth * tileHeight * planeCount * tileCounter
                                      + bpl * tileByteWidth
                                      + tileRow * tileByteWidth * planeCount
                                      + tileSize // One blank tile at the beginning
                            ;

                            for (int b = 0; b < tileByteWidth; b++)
                            {
                                var s = data[src++];
                                destination[dst++] = s;
                            }
                        }
                    }

                    tileCounter++;
                }
            }

            _writer.WriteCode(Code.Data, "; Tiles are in interlaced format one after another.");
            _writer.WriteCode(Code.Data,
                              "; The first tile is all zeros and is to be used when Tiled does not have a tile assigned.");
            _writer.WriteCode(Code.Data,
                              $"; Tiles are {tileByteWidth} byte wide, {tileHeight} pixel tall and have {planeCount} biplanes");

            _writer.WriteCode(Code.Normal, $"; Tile definitions for {name}");
            _writer.WriteCode(Code.Normal, $"TILE_BWIDTH_{name.ToUpperInvariant()}\t\t\tequ\t{tileByteWidth}");
            _writer.WriteCode(Code.Normal, $"TILE_HEIGHT_{name.ToUpperInvariant()}\t\t\tequ\t{tileHeight}");
            _writer.WriteCode(Code.Normal, $"TILE_PLANE_COUNT_{name.ToUpperInvariant()}\tequ\t{planeCount}");


            _writer.StartObject(ObjectType.Tile, name);
            _writer.WriteBlob(destination);
            _writer.EndObject();
        }
Esempio n. 4
0
        private void SaveBobsWithMasks(Bitmap bitmap, int initialOffset)
        {
            var width    = _definition.Width;
            var height   = _definition.Height.GetValueOrDefault(bitmap.Height);
            var numTiles = _definition.Count.GetValueOrDefault(bitmap.Width / _definition.Width);
            var bobX     = _definition.StartX;
            var bobY     = _definition.StartY;

            var info = new BobData[numTiles];

            _writer.WriteWord((ushort)(_bobWordWidth));
            initialOffset += 2;
            _writer.WriteWord((ushort)numTiles);
            initialOffset += 2;

            for (var i = 0; i < numTiles;)
            {
                var currentBob = new BobData();
                info[i] = currentBob;

                if (bobX + width > bitmap.Width)
                {
                    throw new ConversionException("Bob out of bitmap bounds");
                }
                if (bobY + height > bitmap.Height)
                {
                    throw new ConversionException("Bob out of bitmap bounds");
                }

                var bobBitmap = bitmap.Clone(new Rectangle(bobX, bobY, width, height),
                                             bitmap.PixelFormat);

                _transformer.SetBitmap(bobBitmap);

                byte transparent = 0;
                if (_colorFlip)
                {
                    transparent = (byte)((1 << _planeCount) - 1);
                    _transformer.FlipColors(0, transparent);
                }

                var planes = _transformer.GetInterleaved(_planeCount); // This will bump up to word size...

                if (planes.Any(_ => _ != 0))
                {
                    for (var y = 0; y < height; y++)
                    {
                        var rowData = new byte[_bobWordWidth * 2 * _planeCount];
                        var rowMask = new byte[_bobWordWidth * 2 * _planeCount];

                        if (_colorFlip)
                        {
                            ArrayFill(rowData, transparent);
                        }

                        for (var x = 0; x < width / 8; x++)
                        {
                            byte mask = _colorFlip ? (byte)0xff : (byte)0x00;

                            for (var bpl = 0; bpl < _planeCount; bpl++)
                            {
                                var value = planes[y * _planeCount * _bobWordWidth * 2 + bpl * _bobWordWidth * 2 + x];
                                rowData[bpl * _bobWordWidth * 2 + x] = value;

                                if (_colorFlip)
                                {
                                    mask &= value;
                                }
                                else
                                {
                                    mask |= value;
                                }
                            }

                            for (var bpl = 0; bpl < _planeCount; bpl++)
                            {
                                rowMask[bpl * _bobWordWidth * 2 + x] = _colorFlip ? (byte)~mask : (byte)mask;
                            }
                        }

                        currentBob.PlaneRows.Add(rowData);
                        currentBob.MaskRows.Add(rowMask);
                    }

                    i++;
                }

                if (i < numTiles)
                {
                    bobX += width;
                    if (bobX >= bitmap.Width)
                    {
                        bobY += height;
                        if (bobY >= bitmap.Height)
                        {
                            throw new ConversionException(
                                      $"Converting {_definition.ImageFile} reached the end of the image trying to get {numTiles} tiles.");
                        }
                        bobX = _definition.StartX;
                    }
                }
            }

            // All Bob info added to the initial offset
            initialOffset += numTiles * 16; // 8 bytes per tile of information in the header

            AdjustBobs(info, initialOffset);
            WriteBobs(info);
        }