public void Update(EditorState editorState, TileSetCollection tileSetCollection, Map map, int gridSize, Rectangle rect) { if (editorState == null || map == null) { return; } Debug.Assert(this.DeviceContext != IntPtr.Zero); Point offset = editorState.GetMapOffset(map.Id); int offscreenWidth = this.Size.Width; int offscreenHeight = this.Size.Height; Size offscreenSize = this.Size; int tileGridSize = gridSize; int tileStartI = Math.Max(-offset.X / tileGridSize, 0); int tileEndI = Math.Min((offscreenWidth - offset.X) / tileGridSize + 1, map.Width); int tileStartJ = Math.Max(-offset.Y / tileGridSize, 0); int tileEndJ = Math.Min((offscreenHeight - offset.Y) / tileGridSize + 1, map.Height); using (Graphics g = Graphics.FromHdc(this.DeviceContext)) { if (0 < offscreenHeight - map.Height * gridSize) { NativeMethods.RECT win32Rect = new NativeMethods.RECT { Left = 0, Right = offscreenWidth, Top = map.Height * gridSize, Bottom = offscreenHeight, }; NativeMethods.FillRect(this.DeviceContext, ref win32Rect, (IntPtr)(NativeMethods.COLOR_BTNFACE + 1)); } if (0 < offscreenWidth - map.Width * gridSize) { NativeMethods.RECT win32Rect = new NativeMethods.RECT { Left = map.Width * gridSize, Right = offscreenWidth, Top = 0, Bottom = map.Height * gridSize, }; NativeMethods.FillRect(this.DeviceContext, ref win32Rect, (IntPtr)(NativeMethods.COLOR_BTNFACE + 1)); } Dictionary<Bitmap, BitmapData> bdHash = null; try { bdHash = new Dictionary<Bitmap, BitmapData>(); LayerMode layerMode = editorState.LayerMode; ScaleMode scaleMode = editorState.ScaleMode; int reductionRatio = 0; switch (scaleMode) { case ScaleMode.Scale2: reductionRatio = 1; break; case ScaleMode.Scale4: reductionRatio = 2; break; case ScaleMode.Scale8: reductionRatio = 4; break; } int halfTileGridSize = tileGridSize >> 1; for (int layer = -1; layer < 2; layer++) { byte alpha = 255; if (layerMode == LayerMode.Layer1 && layer == 1) { alpha = 128; } for (int j = tileStartJ; j < tileEndJ; j++) { int y = j * tileGridSize + offset.Y; for (int i = tileStartI; i < tileEndI; i++) { int x = i * tileGridSize + offset.X; if (0 <= layer) { Tile tile = map.GetTile(layer, i, j); if (tileSetCollection.ContainsId(tile.TileSetId)) { int tileId = tile.TileId; TileSet tileSet = tileSetCollection.GetItem(tile.TileSetId); Bitmap bitmap = tileSet.GetBitmap(scaleMode); BitmapData srcBD; if (!bdHash.ContainsKey(bitmap)) { srcBD = bdHash[bitmap] = bitmap.LockBits(new Rectangle { Size = bitmap.Size, }, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); } else { srcBD = bdHash[bitmap]; } int srcX = (tileId % Util.PaletteHorizontalCount) * tileGridSize; int srcY = (tileId / Util.PaletteHorizontalCount) * tileGridSize; Util.DrawBitmap(this.Pixels, offscreenSize, x, y, tileGridSize, tileGridSize, srcBD, srcX, srcY, alpha); } } else { if (scaleMode == ScaleMode.Scale1) { this.DrawRectOffscreen(new Rectangle { X = x, Y = y, Width = halfTileGridSize, Height = halfTileGridSize, }, 0x00, 0x00, 0x80); this.DrawRectOffscreen(new Rectangle { X = x + halfTileGridSize, Y = y, Width = halfTileGridSize, Height = halfTileGridSize, }, 0x00, 0x00, 0x40); this.DrawRectOffscreen(new Rectangle { X = x, Y = y + halfTileGridSize, Width = halfTileGridSize, Height = halfTileGridSize, }, 0x00, 0x00, 0x40); this.DrawRectOffscreen(new Rectangle { X = x + halfTileGridSize, Y = y + halfTileGridSize, Width = halfTileGridSize, Height = halfTileGridSize, }, 0x00, 0x00, 0x80); } else { byte blue = (byte)(((i / reductionRatio + j / reductionRatio) % 2) == 0 ? 0x80 : 0x40); this.DrawRectOffscreen(new Rectangle { X = x, Y = y, Width = tileGridSize, Height = tileGridSize, }, 0x00, 0x00, blue); } } } } if (layerMode == LayerMode.Event) { int yMin = tileStartJ * tileGridSize + offset.Y; int yMax = tileEndJ * tileGridSize + offset.Y; for (int i = tileStartI; i < tileEndI; i++) { int x1 = i * tileGridSize + offset.X; int x2 = i * tileGridSize + offset.X + tileGridSize - 1; this.DrawGrayLineOnOffscreen(x1, x1, yMin, yMax); this.DrawGrayLineOnOffscreen(x2, x2, yMin, yMax); } int xMin = tileStartI * tileGridSize + offset.X; int xMax = tileEndI * tileGridSize + offset.X; for (int j = tileStartJ; j < tileEndJ; j++) { int y1 = j * tileGridSize + offset.Y; int y2 = j * tileGridSize + offset.Y + tileGridSize - 1; this.DrawGrayLineOnOffscreen(xMin, xMax, y1, y1); this.DrawGrayLineOnOffscreen(xMin, xMax, y2, y2); } } if (editorState.LayerMode == LayerMode.Layer2 && layer == 0) { this.DarkenOffscreen(new Rectangle { X = tileStartI * tileGridSize + offset.X, Y = tileStartJ * tileGridSize + offset.Y, Width = (tileEndI - tileStartI) * tileGridSize, Height = (tileEndJ - tileStartJ) * tileGridSize, }); } } } finally { if (bdHash != null) { foreach (var pair in bdHash) { pair.Key.UnlockBits(pair.Value); } bdHash.Clear(); bdHash = null; } } } }
public void Update(EditorState editorState, TileSetCollection tileSetCollection, Map map, int gridSize) { Rectangle rect = new Rectangle(new Point(0, 0), this.Size); this.Update(editorState, tileSetCollection, map, gridSize, rect); }