/// <summary> /// arrange the array of tiles into a single bitmap /// </summary> public static Bitmap FromBitmaps(Bitmap[] bitmaps, COLFile collisionInfo) { // 20x50 makes most sense for maps with 1000 tiles int num = bitmaps.Length; int w = 20; int h = (num / w) + 1; Bitmap bmp = new Bitmap(16 * w, 16 * h); using (var gfx = Graphics.FromImage(bmp)) { for (int i = 0; i < num; i++) { int x = i % w; int y = i / w; gfx.DrawImage(bitmaps[i], 16 * x, 16 * y, 16, 16); if (collisionInfo != null) { CollisionDrawer.Draw(gfx, collisionInfo, i, x, y); } } } return(bmp); }
internal static void Draw(Graphics gfx, COLFile collisionInfo, int tileId, int x, int y) { SolidBrush brush = new SolidBrush(Color.White); Dictionary <int, Color> colors = new Dictionary <int, Color>() { { 0x01, Color.FromArgb(200, 255, 255, 0) }, { 0x80, Color.FromArgb(200, 255, 0, 255) }, { 0x7F, Color.FromArgb(200, 0, 255, 255) }, { 0xD3, Color.FromArgb(200, 0, 255, 0) }, { 0x31, Color.FromArgb(200, 10, 100, 200) } }; if (tileId < collisionInfo.Entries.Length) { var entry = collisionInfo.Entries[tileId]; if (entry.A > 0) { brush.Color = colors[entry.A]; gfx.FillRectangle(brush, 16 * x, 16 * y, 8, 8); } if (entry.B > 0) { brush.Color = colors[entry.B]; gfx.FillRectangle(brush, 16 * x + 8, 16 * y, 8, 8); } if (entry.C > 0) { brush.Color = colors[entry.C]; gfx.FillRectangle(brush, 16 * x, 16 * y + 8, 8, 8); } if (entry.D > 0) { brush.Color = colors[entry.D]; gfx.FillRectangle(brush, 16 * x + 8, 16 * y + 8, 8, 8); } } else // no collision info available for this tile { gfx.DrawLine(Pens.Red, 16 * x + 2, 16 * y + 2, 16 * x + 14, 16 * y + 14); gfx.DrawLine(Pens.Red, 16 * x + 14, 16 * y + 2, 16 * x + 2, 16 * y + 14); } }
public Bitmap MakeTilesetBitmap(TOCEntry entry, bool collisions) // entry can be COL or PIC { string picName, palName, colName; TOCEntry picEntry, palEntry, colEntry; // level number from BLOCK?.PIC or WORLD?.COL file if (!int.TryParse(entry.Name.Substring(5, 1), out int levelNumber)) { return(null); } if (entry.Type == TOCEntryType.CollisionInfo) // get matching block?.pic { colEntry = entry; picName = $"BLOCK{levelNumber}.PIC"; if (!assets.Entries.ContainsKey(picName)) { return(null); } picEntry = assets.Entries[picName]; } else // get matching world?.col { if (levelNumber == 6) { levelNumber = 5; } picEntry = entry; // collision entry colName = $"WORLD{levelNumber}.COL"; if (!assets.Entries.ContainsKey(colName)) { return(null); } colEntry = assets.Entries[colName]; } if (levelNumber == 6) { levelNumber = 5; } // palette entry palName = $"WORLD{levelNumber}.PAL"; if (!assets.Entries.ContainsKey(palName)) { return(null); } palEntry = assets.Entries[palName]; // read col data COLFile colFile = collisions ? new COLFile(colEntry.Data) : null; try { return(FromBitmaps(PICConverter.PICToBitmaps(picEntry.Data, palEntry.Data), colFile)); } catch { return(null); } }
private void make(object sender, DoWorkEventArgs e) { try { worker.ReportProgress(0); Map = new PCMFile(mapEntry.Data); COLFile colFile = new COLFile(collisionsEntry.Data); EIBFile entitiesFile = entitiesEntry != null ? new EIBFile(entitiesEntry.Data) : null; worker.ReportProgress(10); if (worker.CancellationPending) { return; } // get tileset bitmaps Bitmap[] tiles = PICConverter.PICToBitmaps(tilesetEntry.Data, paletteEntry.Data); worker.ReportProgress(40); if (worker.CancellationPending) { return; } TilesBitmap = new Bitmap(Game.TileSize * Map.Width, Game.TileSize * Map.Height); CollisionsBitmap = new Bitmap(Game.TileSize * Map.Width, Game.TileSize * Map.Height); EntitiesBitmap = new Bitmap(Game.TileSize * Map.Width, Game.TileSize * Map.Height); GridBitmap = new Bitmap(Game.TileSize * Map.Width, Game.TileSize * Map.Height); // draw map tiles and collisions Graphics tilesGfx = Graphics.FromImage(TilesBitmap); Graphics collGfx = Graphics.FromImage(CollisionsBitmap); int total = Map.Width * Map.Height; for (int y = 0; y < Map.Height; y++) { for (int x = 0; x < Map.Width; x++) { int id = x + y * Map.Width; int tileId = Map.TilesIndices[y, x]; // draw cell Bitmap tile = tiles[tileId]; tilesGfx.DrawImage(tile, x * Game.TileSize, y * Game.TileSize, Game.TileSize, Game.TileSize); CollisionDrawer.Draw(collGfx, colFile, tileId, x, y); worker.ReportProgress(40 + (int)Math.Round(50f * id / total)); if (worker.CancellationPending) { Error = "Cancelled"; goto end; } } } // draw entity info if (entitiesFile != null) { EntityDrawer.Draw(EntitiesBitmap, entitiesFile); } // draw grid Graphics gridGfx = Graphics.FromImage(GridBitmap); Pen pen = new Pen(Color.FromArgb(100, 200, 200, 0), 1); for (int x = 0; x < Map.Width; x++) { gridGfx.DrawLine(pen, x * Game.TileSize, 0, x * Game.TileSize, Map.Height * Game.TileSize); } for (int y = 0; y < Map.Height; y++) { gridGfx.DrawLine(pen, 0, y * Game.TileSize, Map.Width * Game.TileSize, y * Game.TileSize); } gridGfx.Dispose(); end: tilesGfx.Dispose(); collGfx.Dispose(); } catch (Exception ex) { Error = ex.Message; return; } }