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(); }
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); } }
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); }