public static Bitmap CustomTerrainBitmap(World world) { var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; var custom = map.CustomTerrain[mapX, mapY]; if (custom == null) continue; *(c + (y * bitmapData.Stride >> 2) + x) = world.TileSet.Terrain[custom].Color.ToArgb(); } } bitmap.UnlockBits(bitmapData); return bitmap; }
public static Bitmap CustomTerrainBitmap(World world) { var map = world.Map; var b = map.Bounds; var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; for (var y = 0; y < b.Height; y++) { for (var x = 0; x < b.Width; x++) { var mapX = x + b.Left; var mapY = y + b.Top; var custom = map.CustomTerrain[mapX, mapY]; if (custom == byte.MaxValue) continue; colors[y * stride + x] = world.TileSet[custom].Color.ToArgb(); } } } bitmap.UnlockBits(bitmapData); return bitmap; }
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, Palette p) { var image = info.EditorSprite; using (var s = FileSystem.OpenWithExts(image, exts)) { // TODO: Do this properly var shp = new ShpReader(s) as ISpriteSource; var frame = shp.Frames.Last(); var bitmap = new Bitmap(frame.Size.Width, frame.Size.Height, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { byte* q = (byte*)data.Scan0.ToPointer(); var stride = data.Stride; for (var i = 0; i < frame.Size.Width; i++) for (var j = 0; j < frame.Size.Height; j++) q[j * stride + i] = frame.Data[i + frame.Size.Width * j]; } bitmap.UnlockBits(data); return new ResourceTemplate { Bitmap = bitmap, Info = info, Value = shp.Frames.Count() - 1 }; } }
public static Bitmap ActorsBitmap(World world) { var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; foreach (var t in world.ActorsWithTrait<IRadarSignature>()) { if (world.FogObscures(t.Actor)) continue; var color = t.Trait.RadarSignatureColor(t.Actor); foreach (var cell in t.Trait.RadarSignatureCells(t.Actor)) if (world.Map.IsInMap(cell)) *(c + ((cell.Y - world.Map.Bounds.Top) * bitmapData.Stride >> 2) + cell.X - world.Map.Bounds.Left) = color.ToArgb(); } } bitmap.UnlockBits(bitmapData); return bitmap; }
// Add the static resources defined in the map; if the map lives // in a world use AddCustomTerrain instead public static Bitmap AddStaticResources(Map map, Bitmap terrainBitmap) { Bitmap terrain = new Bitmap(terrainBitmap); var tileset = Rules.TileSets[map.Tileset]; var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; if (map.MapResources.Value[mapX, mapY].type == 0) continue; var res = Rules.Info["world"].Traits.WithInterface<ResourceTypeInfo>() .Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].type) .Select(t => t.TerrainType).FirstOrDefault(); if (res == null) continue; *(c + (y * bitmapData.Stride >> 2) + x) = tileset.Terrain[res].Color.ToArgb(); } } terrain.UnlockBits(bitmapData); return terrain; }
public static Bitmap ActorsBitmap(World world) { var map = world.Map; var b = map.Bounds; var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; foreach (var t in world.ActorsWithTrait<IRadarSignature>()) { if (world.FogObscures(t.Actor)) continue; var color = t.Trait.RadarSignatureColor(t.Actor); foreach (var cell in t.Trait.RadarSignatureCells(t.Actor)) { var uv = Map.CellToMap(map.TileShape, cell); if (b.Contains(uv.X, uv.Y)) colors[(uv.Y - b.Top) * stride + uv.X - b.Left] = color.ToArgb(); } } } bitmap.UnlockBits(bitmapData); return bitmap; }
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, Palette p) { var image = info.SpriteNames[0]; using (var s = FileSystem.OpenWithExts(image, exts)) { var shp = new ShpReader(s); var frame = shp[shp.ImageCount - 1]; var bitmap = new Bitmap(shp.Width, shp.Height, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { byte* q = (byte*)data.Scan0.ToPointer(); var stride = data.Stride; for (var i = 0; i < shp.Width; i++) for (var j = 0; j < shp.Height; j++) q[j * stride + i] = frame.Image[i + shp.Width * j]; } bitmap.UnlockBits(data); return new ResourceTemplate { Bitmap = bitmap, Info = info, Value = shp.ImageCount - 1 }; } }
public static void FastCopyIntoSprite(Sprite dest, Bitmap src) { var destStride = dest.sheet.Size.Width; var width = dest.bounds.Width; var height = dest.bounds.Height; var srcData = src.LockBits(src.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var c = (int*)srcData.Scan0; // Cast the data to an int array so we can copy the src data directly fixed (byte* bd = &dest.sheet.Data[0]) { var data = (int*)bd; var x = dest.bounds.Left; var y = dest.bounds.Top; for (var j = 0; j < height; j++) for (var i = 0; i < width; i++) data[(y + j) * destStride + x + i] = *(c + (j * srcData.Stride >> 2) + i); } } src.UnlockBits(srcData); }
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, TileSet tileset, IPalette p) { var image = ResolveFilename(info.EditorSprite, tileset); using (var s = GlobalFileSystem.Open(image)) { // TODO: Do this properly var shp = new ShpTDSprite(s); var frame = shp.Frames.Last(); var bitmap = new Bitmap(frame.Size.Width, frame.Size.Height, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { var q = (byte*)data.Scan0.ToPointer(); var stride = data.Stride; for (var i = 0; i < frame.Size.Width; i++) for (var j = 0; j < frame.Size.Height; j++) q[j * stride + i] = frame.Data[i + frame.Size.Width * j]; } bitmap.UnlockBits(data); return new ResourceTemplate { Bitmap = bitmap, Info = info, Value = shp.Frames.Count - 1 }; } }
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false) { var isDiamond = map.TileShape == TileShape.Diamond; var b = map.Bounds; // Fudge the heightmap offset by adding as much extra as we need / can. // This tries to correct for our incorrect assumption that MPos == PPos var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); var width = b.Width; var height = b.Height + heightOffset; var bitmapWidth = width; if (isDiamond) bitmapWidth = 2 * bitmapWidth - 1; if (!actualSize) bitmapWidth = height = Exts.NextPowerOf2(Math.Max(bitmapWidth, height)); var terrain = new Bitmap(bitmapWidth, height); var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var mapTiles = map.MapTiles.Value; unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var uv = new MPos(x + b.Left, y + b.Top); var type = tileset.GetTileInfo(mapTiles[uv]); var leftColor = type != null ? type.LeftColor : Color.Black; if (isDiamond) { // Odd rows are shifted right by 1px var dx = uv.V & 1; var rightColor = type != null ? type.RightColor : Color.Black; if (x + dx > 0) colors[y * stride + 2 * x + dx - 1] = leftColor.ToArgb(); if (2 * x + dx < stride) colors[y * stride + 2 * x + dx] = rightColor.ToArgb(); } else colors[y * stride + x] = leftColor.ToArgb(); } } } terrain.UnlockBits(bitmapData); return terrain; }
public Bitmap AsBitmap() { var d = GetData(); var dataStride = 4 * Size.Width; var bitmap = new Bitmap(Size.Width, Size.Height); var bd = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); for (var y = 0; y < Size.Height; y++) Marshal.Copy(d, y * dataStride, IntPtr.Add(bd.Scan0, y * bd.Stride), dataStride); bitmap.UnlockBits(bd); return bitmap; }
public static void FastCopyIntoSprite(Sprite dest, Bitmap src) { var createdTempBitmap = false; if (src.PixelFormat != PixelFormat.Format32bppArgb) { src = src.CloneWith32bbpArgbPixelFormat(); createdTempBitmap = true; } try { var destData = dest.Sheet.GetData(); var destStride = dest.Sheet.Size.Width; var width = dest.Bounds.Width; var height = dest.Bounds.Height; var srcData = src.LockBits(src.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var c = (int*)srcData.Scan0; // Cast the data to an int array so we can copy the src data directly fixed (byte* bd = &destData[0]) { var data = (int*)bd; var x = dest.Bounds.Left; var y = dest.Bounds.Top; for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++) { var cc = Color.FromArgb(*(c + (j * srcData.Stride >> 2) + i)); data[(y + j) * destStride + x + i] = PremultiplyAlpha(cc).ToArgb(); } } } } src.UnlockBits(srcData); } finally { if (createdTempBitmap) src.Dispose(); } }
public static void FastCopyIntoSprite(Sprite dest, Bitmap src) { var data = dest.sheet.Data; var dataStride = dest.sheet.Size.Width * 4; var x = dest.bounds.Left * 4; var width = dest.bounds.Width * 4; var y = dest.bounds.Top; var height = dest.bounds.Height; var bd = src.LockBits(src.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); for (var row = 0; row < height; row++) Marshal.Copy(IntPtr.Add(bd.Scan0, row * bd.Stride), data, (y + row) * dataStride + x, width); src.UnlockBits(bd); }
public override void Initialize(WidgetArgs args) { base.Initialize(args); hueBitmap = new Bitmap(256, 256); hueSprite = new Sprite(new Sheet(new Size(256, 256)), new Rectangle(0, 0, 256, 1), TextureChannel.Alpha); var bitmapData = hueBitmap.LockBits(hueBitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; for (var h = 0; h < 256; h++) *(c + h) = HSLColor.FromHSV(h/255f, 1, 1).RGB.ToArgb(); } hueBitmap.UnlockBits(bitmapData); hueSprite.sheet.Texture.SetData(hueBitmap); }
public Bitmap RenderTemplate(ushort id, Palette p) { var template = TileSet.Templates[id]; var templateData = templates[id]; var bitmap = new Bitmap(TileSize * template.Size.X, TileSize * template.Size.Y, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { var q = (byte*)data.Scan0.ToPointer(); var stride = data.Stride; for (var u = 0; u < template.Size.X; u++) { for (var v = 0; v < template.Size.Y; v++) { var rawImage = templateData[u + v * template.Size.X]; if (rawImage != null && rawImage.Length > 0) { for (var i = 0; i < TileSize; i++) for (var j = 0; j < TileSize; j++) q[(v * TileSize + j) * stride + u * TileSize + i] = rawImage[i + TileSize * j]; } else { for (var i = 0; i < TileSize; i++) for (var j = 0; j < TileSize; j++) q[(v * TileSize + j) * stride + u * TileSize + i] = 0; } } } } bitmap.UnlockBits(data); return bitmap; }
// Add the static resources defined in the map; if the map lives // in a world use AddCustomTerrain instead static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap) { var terrain = new Bitmap(terrainBitmap); var b = map.Bounds; var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; for (var y = 0; y < b.Height; y++) { for (var x = 0; x < b.Width; x++) { var mapX = x + b.Left; var mapY = y + b.Top; if (map.MapResources.Value[new MPos(mapX, mapY)].Type == 0) continue; var res = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>() .Where(t => t.ResourceType == map.MapResources.Value[new MPos(mapX, mapY)].Type) .Select(t => t.TerrainType).FirstOrDefault(); if (res == null) continue; colors[y * stride + x] = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb(); } } } terrain.UnlockBits(bitmapData); return terrain; }
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false) { var b = map.Bounds; var width = b.Width; var height = b.Height; if (!actualSize) width = height = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var terrain = new Bitmap(width, height); var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var mapTiles = map.MapTiles.Value; unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; for (var y = 0; y < b.Height; y++) { for (var x = 0; x < b.Width; x++) { var mapX = x + b.Left; var mapY = y + b.Top; var type = tileset.GetTileInfo(mapTiles[new MPos(mapX, mapY)]); var color = type != null ? type.LeftColor : Color.Black; colors[y * stride + x] = color.ToArgb(); } } } terrain.UnlockBits(bitmapData); return terrain; }
static Bitmap RenderShp(ISpriteSource shp, IPalette p) { var frame = shp.Frames.First(); var bitmap = new Bitmap(frame.Size.Width, frame.Size.Height, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { var q = (byte*)data.Scan0.ToPointer(); var stride2 = data.Stride; for (var i = 0; i < frame.Size.Width; i++) for (var j = 0; j < frame.Size.Height; j++) q[j * stride2 + i] = frame.Data[i + frame.Size.Width * j]; } bitmap.UnlockBits(data); return bitmap; }
public static Bitmap Load(Stream s) { using (var br = new BinaryReader(s)) { var signature = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }; foreach (var b in signature) if (br.ReadByte() != b) throw new InvalidDataException("PNG Signature is bogus"); Bitmap bitmap = null; Color[] palette = null; var data = new List<byte>(); for (; ; ) { var length = IPAddress.NetworkToHostOrder(br.ReadInt32()); var type = Encoding.UTF8.GetString(br.ReadBytes(4)); var content = br.ReadBytes(length); /*var crc = */br.ReadInt32(); using (var ms = new MemoryStream(content)) using (var cr = new BinaryReader(ms)) switch (type) { case "IHDR": { var width = IPAddress.NetworkToHostOrder(cr.ReadInt32()); var height = IPAddress.NetworkToHostOrder(cr.ReadInt32()); var bitDepth = cr.ReadByte(); var colorType = (PngColorType)cr.ReadByte(); var compression = cr.ReadByte(); /*var filter = */cr.ReadByte(); var interlace = cr.ReadByte(); if (compression != 0) throw new InvalidDataException("Compression method not supported"); if (interlace != 0) throw new InvalidDataException("Interlacing not supported"); bitmap = new Bitmap(width, height, MakePixelFormat(bitDepth, colorType)); } break; case "PLTE": { palette = new Color[256]; for (var i = 0; i < 256; i++) { var r = cr.ReadByte(); var g = cr.ReadByte(); var b = cr.ReadByte(); palette[i] = Color.FromArgb(r, g, b); } } break; case "tRNS": { for (var i = 0; i < length; i++) palette[i] = Color.FromArgb(cr.ReadByte(), palette[i]); } break; case "IDAT": { data.AddRange(content); } break; case "IEND": { var bits = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); using (var ns = new MemoryStream(data.ToArray())) { // 'zlib' flags bytes; confuses the DeflateStream. /*var flags = (byte)*/ns.ReadByte(); /*var moreFlags = (byte)*/ns.ReadByte(); using (var ds = new DeflateStream(ns, CompressionMode.Decompress)) using (var dr = new BinaryReader(ds)) { var prevLine = new byte[bitmap.Width]; // all zero for (var y = 0; y < bitmap.Height; y++) { var filter = (PngFilter)dr.ReadByte(); var line = dr.ReadBytes(bitmap.Width); for (var i = 0; i < bitmap.Width; i++) line[i] = i > 0 ? UnapplyFilter(filter, line[i], line[i - 1], prevLine[i], prevLine[i - 1]) : UnapplyFilter(filter, line[i], 0, prevLine[i], 0); Marshal.Copy(line, 0, new IntPtr(bits.Scan0.ToInt64() + y * bits.Stride), line.Length); prevLine = line; } } } bitmap.UnlockBits(bits); using (var temp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) { var cp = temp.Palette; for (var i = 0; i < 256; i++) cp.Entries[i] = palette[i]; // finalize the palette. bitmap.Palette = cp; return bitmap; } } } } } }
// Add the static resources defined in the map; if the map lives // in a world use AddCustomTerrain instead static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap) { var terrain = new Bitmap(terrainBitmap); var isDiamond = map.TileShape == TileShape.Diamond; var b = map.Bounds; // Fudge the heightmap offset by adding as much extra as we need / can // This tries to correct for our incorrect assumption that MPos == PPos var heightOffset = Math.Min(map.MaximumTerrainHeight, map.MapSize.Y - b.Bottom); var width = b.Width; var height = b.Height + heightOffset; var resources = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>() .ToDictionary(r => r.ResourceType, r => r.TerrainType); var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var uv = new MPos(x + b.Left, y + b.Top); if (map.MapResources.Value[uv].Type == 0) continue; string res; if (!resources.TryGetValue(map.MapResources.Value[uv].Type, out res)) continue; var color = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb(); if (isDiamond) { // Odd rows are shifted right by 1px var dx = uv.V & 1; if (x + dx > 0) colors[y * stride + 2 * x + dx - 1] = color; if (2 * x + dx < stride) colors[y * stride + 2 * x + dx] = color; } else colors[y * stride + x] = color; } } } terrain.UnlockBits(bitmapData); return terrain; }
static Bitmap RenderShp(ShpReader shp, Palette p) { var frame = shp[0]; var bitmap = new Bitmap(shp.Width, shp.Height, PixelFormat.Format8bppIndexed); bitmap.Palette = p.AsSystemPalette(); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { byte* q = (byte*)data.Scan0.ToPointer(); var stride2 = data.Stride; for (var i = 0; i < shp.Width; i++) for (var j = 0; j < shp.Height; j++) q[j * stride2 + i] = frame.Image[i + shp.Width * j]; } bitmap.UnlockBits(data); return bitmap; }
public static Bitmap ShroudBitmap(World world) { var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); if (world.RenderedShroud.Disabled) return bitmap; var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var shroud = Color.Black.ToArgb(); var fog = Color.FromArgb(128, Color.Black).ToArgb(); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; if (!world.RenderedShroud.IsExplored(mapX, mapY)) *(c + (y * bitmapData.Stride >> 2) + x) = shroud; else if (!world.RenderedShroud.IsVisible(mapX,mapY)) *(c + (y * bitmapData.Stride >> 2) + x) = fog; } } bitmap.UnlockBits(bitmapData); return bitmap; }
public static Bitmap ShroudBitmap(World world) { var map = world.Map; var b = map.Bounds; var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height)); var bitmap = new Bitmap(size, size); if (world.RenderPlayer == null) return bitmap; var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var shroud = Color.Black.ToArgb(); var fog = Color.FromArgb(128, Color.Black).ToArgb(); var offset = new CVec(b.Left, b.Top); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; var shroudObscured = world.ShroudObscuresTest(map.Cells); var fogObscured = world.FogObscuresTest(map.Cells); foreach (var cell in map.Cells) { var uv = Map.CellToMap(map.TileShape, cell) - offset; if (shroudObscured(cell)) colors[uv.Y * stride + uv.X] = shroud; else if (fogObscured(cell)) colors[uv.Y * stride + uv.X] = fog; } } bitmap.UnlockBits(bitmapData); return bitmap; }
public static Bitmap TerrainBitmap(Map map, bool actualSize) { var tileset = Rules.TileSets[map.Tileset]; var width = map.Bounds.Width; var height = map.Bounds.Height; if (!actualSize) width = height = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var terrain = new Bitmap(width, height); var bitmapData = terrain.LockBits(terrain.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var mapX = x + map.Bounds.Left; var mapY = y + map.Bounds.Top; var type = tileset.GetTerrainType(map.MapTiles.Value[mapX, mapY]); if (!tileset.Terrain.ContainsKey(type)) throw new InvalidDataException("Tileset {0} lacks terraintype {1}".F(tileset.Id, type)); *(c + (y * bitmapData.Stride >> 2) + x) = tileset.Terrain[type].Color.ToArgb(); } } terrain.UnlockBits(bitmapData); return terrain; }
public static Bitmap ShroudBitmap(World world) { var map = world.Map; var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height)); var bitmap = new Bitmap(size, size); if (world.RenderPlayer == null) return bitmap; var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var shroud = Color.Black.ToArgb(); var fog = Color.FromArgb(128, Color.Black).ToArgb(); unsafe { int* c = (int*)bitmapData.Scan0; for (var x = 0; x < map.Bounds.Width; x++) for (var y = 0; y < map.Bounds.Height; y++) { var p = new CPos(x + map.Bounds.Left, y + map.Bounds.Top); if (world.ShroudObscures(p)) *(c + (y * bitmapData.Stride >> 2) + x) = shroud; else if (world.FogObscures(p)) *(c + (y * bitmapData.Stride >> 2) + x) = fog; } } bitmap.UnlockBits(bitmapData); return bitmap; }
public Bitmap AsBitmap(TextureChannel channel, IPalette pal) { var d = GetData(); var dataStride = 4 * Size.Width; var bitmap = new Bitmap(Size.Width, Size.Height); var channelOffset = (int)channel; var bd = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { var colors = (uint*)bd.Scan0; for (var y = 0; y < Size.Height; y++) { var dataRowIndex = y * dataStride + channelOffset; var bdRowIndex = y * bd.Stride / 4; for (var x = 0; x < Size.Width; x++) { var paletteIndex = d[dataRowIndex + 4 * x]; colors[bdRowIndex + x] = pal[paletteIndex]; } } } bitmap.UnlockBits(bd); return bitmap; }
public byte[] SavePreview() { var tileset = Rules.TileSet; var resources = Rules.Actors["world"].TraitInfos<ResourceTypeInfo>() .ToDictionary(r => r.ResourceType, r => r.TerrainType); using (var stream = new MemoryStream()) { var isRectangularIsometric = Grid.Type == MapGridType.RectangularIsometric; // Fudge the heightmap offset by adding as much extra as we need / can. // This tries to correct for our incorrect assumption that MPos == PPos var heightOffset = Math.Min(Grid.MaximumTerrainHeight, MapSize.Y - Bounds.Bottom); var width = Bounds.Width; var height = Bounds.Height + heightOffset; var bitmapWidth = width; if (isRectangularIsometric) bitmapWidth = 2 * bitmapWidth - 1; using (var bitmap = new Bitmap(bitmapWidth, height)) { var bitmapData = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { var colors = (int*)bitmapData.Scan0; var stride = bitmapData.Stride / 4; Color leftColor, rightColor; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var uv = new MPos(x + Bounds.Left, y + Bounds.Top); var resourceType = Resources[uv].Type; if (resourceType != 0) { // Cell contains resources string res; if (!resources.TryGetValue(resourceType, out res)) continue; leftColor = rightColor = tileset[tileset.GetTerrainIndex(res)].Color; } else { // Cell contains terrain var type = tileset.GetTileInfo(Tiles[uv]); leftColor = type != null ? type.LeftColor : Color.Black; rightColor = type != null ? type.RightColor : Color.Black; } if (isRectangularIsometric) { // Odd rows are shifted right by 1px var dx = uv.V & 1; if (x + dx > 0) colors[y * stride + 2 * x + dx - 1] = leftColor.ToArgb(); if (2 * x + dx < stride) colors[y * stride + 2 * x + dx] = rightColor.ToArgb(); } else colors[y * stride + x] = leftColor.ToArgb(); } } } bitmap.UnlockBits(bitmapData); bitmap.Save(stream, ImageFormat.Png); } return stream.ToArray(); } }
public const int ChunkSize = 8; // 8x8 chunks ==> 192x192 bitmaps. Bitmap RenderChunk(int u, int v) { var bitmap = new Bitmap(ChunkSize * TileSetRenderer.TileSize, ChunkSize * TileSetRenderer.TileSize); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { var p = (int*)data.Scan0.ToPointer(); var stride = data.Stride >> 2; for (var i = 0; i < ChunkSize; i++) for (var j = 0; j < ChunkSize; j++) { var cell = new CPos(u * ChunkSize + i, v * ChunkSize + j); var tr = Map.MapTiles.Value[cell]; var tile = TileSetRenderer.Data(tr.Type); var index = (tr.Index < tile.Count) ? tr.Index : (byte)0; var rawImage = tile[index]; for (var x = 0; x < TileSetRenderer.TileSize; x++) for (var y = 0; y < TileSetRenderer.TileSize; y++) p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize * y]).ToArgb(); if (Map.MapResources.Value[cell].Type != 0) { var resourceImage = ResourceTemplates[Map.MapResources.Value[cell].Type].Bitmap; var srcdata = resourceImage.LockBits(resourceImage.Bounds(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var q = (int*)srcdata.Scan0.ToPointer(); var srcstride = srcdata.Stride >> 2; for (var x = 0; x < TileSetRenderer.TileSize; x++) for (var y = 0; y < TileSetRenderer.TileSize; y++) { var c = q[y * srcstride + x]; if ((c & 0xff000000) != 0) /* quick & dirty, i cbf doing real alpha */ p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = c; } resourceImage.UnlockBits(srcdata); } } } bitmap.UnlockBits(data); if (ShowGrid) { using (var g = SGraphics.FromImage(bitmap)) { var ts = Game.modData.Manifest.TileSize; var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); ControlPaint.DrawGrid(g, rect, new Size(2, ts.Height), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(ts.Width, 2), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(ts.Width, ts.Height), Color.Red); } } return bitmap; }