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