protected void RestoreBackground(Rect rect, byte backColor = 0) { VirtScreen vs; if (rect.Top < 0) rect.Top = 0; if (rect.Left >= rect.Right || rect.Top >= rect.Bottom) return; if ((vs = FindVirtScreen(rect.Top)) == null) return; if (rect.Left > vs.Width) return; // Convert 'rect' to local (virtual screen) coordinates rect.Top -= vs.TopLine; rect.Bottom -= vs.TopLine; rect.Clip(vs.Width, vs.Height); int height = rect.Height; int width = rect.Width; if (_game.Platform == Platform.FMTowns && Game.GameId == GameId.Monkey1 && vs == VerbVirtScreen && rect.Bottom <= 154) rect.Right = 319; MarkRectAsDirty(vs, rect.Left, rect.Right, rect.Top, rect.Bottom, Gdi.UsageBitRestored); var screenBuf = new PixelNavigator(vs.Surfaces[0]); screenBuf.GoTo(vs.XStart + rect.Left, rect.Top); if (height == 0) return; if (vs.HasTwoBuffers && _currentRoom != 0 && IsLightOn()) { var back = new PixelNavigator(vs.Surfaces[1]); back.GoTo(vs.XStart + rect.Left, rect.Top); Gdi.Blit(screenBuf, back, width, height); if (vs == MainVirtScreen && _charset.HasMask) { if (_game.Platform == Platform.FMTowns) { var mask = new PixelNavigator(_textSurface); mask.GoTo(rect.Left * _textSurfaceMultiplier, (rect.Top + vs.TopLine) * _textSurfaceMultiplier); Gdi.Fill(mask, 0, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); } else { var mask = new PixelNavigator(_textSurface); mask.GoTo(rect.Left, rect.Top - ScreenTop); Gdi.Fill(mask, CharsetMaskTransparency, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); } } } else { if (Game.Platform == Platform.FMTowns) { backColor |= (byte)(backColor << 4); var mask = new PixelNavigator(_textSurface); mask.GoTo(rect.Left * _textSurfaceMultiplier, (rect.Top + vs.TopLine) * _textSurfaceMultiplier); Gdi.Fill(mask, backColor, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); } if (Game.Features.HasFlag(GameFeatures.Is16BitColor)) Gdi.Fill(screenBuf, _16BitPalette[backColor], width, height); else Gdi.Fill(screenBuf, backColor, width, height); } }
public static void Fill(Surface surface, Rect r, int color) { r = new Rect(r.Left, r.Top, r.Right, r.Bottom); r.Clip(surface.Width, surface.Height); if (!r.IsValid) return; int width = r.Width; int lineLen = width; int height = r.Height; bool useMemset = true; var bpp = Surface.GetBytesPerPixel(surface.PixelFormat); if (bpp == 2) { lineLen *= 2; if ((ushort)color != ((color & 0xff) | (color & 0xff) << 8)) useMemset = false; } else if (bpp == 4) { useMemset = false; } else if (bpp != 1) { throw new InvalidOperationException("Surface::fillRect: bytesPerPixel must be 1, 2, or 4"); } if (useMemset) { var pn = new PixelNavigator(surface); pn.GoTo(r.Left, r.Top); for (int i = 0; i < height; i++) { pn.Set((byte)color, lineLen); pn.OffsetY(1); } } else { if (bpp == 2) { var pn = new PixelNavigator(surface); pn.GoTo(r.Left, r.Top); for (int i = 0; i < height; i++) { pn.Set((ushort)color, lineLen); pn.OffsetX(surface.Width); } } else { var pn = new PixelNavigator(surface); pn.GoTo(r.Left, r.Top); for (int i = 0; i < height; i++) { pn.Set((uint)color, lineLen); pn.OffsetX(surface.Width / 2); } } } }