protected void DrawBoxCore(int x, int y, int x2, int y2, int color) { VirtScreen vs; if ((vs = FindVirtScreen(y)) == null) { return; } if (x > x2) { ScummHelper.Swap(ref x, ref x2); } if (y > y2) { ScummHelper.Swap(ref y, ref y2); } x2++; y2++; // Adjust for the topline of the VirtScreen y -= vs.TopLine; y2 -= vs.TopLine; // Clip the coordinates if (x < 0) { x = 0; } else if (x >= vs.Width) { return; } if (x2 < 0) { return; } if (x2 > vs.Width) { x2 = vs.Width; } if (y < 0) { y = 0; } else if (y > vs.Height) { return; } if (y2 < 0) { return; } if (y2 > vs.Height) { y2 = vs.Height; } int width = x2 - x; int height = y2 - y; // This will happen in the Sam & Max intro - see bug #1039162 - where // it would trigger an assertion in blit(). if (width <= 0 || height <= 0) { return; } MarkRectAsDirty(vs, x, x2, y, y2); var backbuff = new PixelNavigator(vs.Surfaces[0]); backbuff.GoTo(vs.XStart + x, y); // A check for -1 might be wrong in all cases since o5_drawBox() in its current form // is definitely not capable of passing a parameter of -1 (color range is 0 - 255). // Just to make sure I don't break anything I restrict the code change to FM-Towns // version 5 games where this change is necessary to fix certain long standing bugs. if (color == -1 || (color >= 254 && Game.Platform == Platform.FMTowns && (Game.GameId == GameId.Monkey2 || Game.GameId == GameId.Indy4))) { if (_game.Platform == Platform.FMTowns) { if (color == 254) { TownsSetupPalCycleField(x, y, x2, y2); } } else { if (vs != MainVirtScreen) { Debug.WriteLine("can only copy bg to main window"); } var bgbuff = new PixelNavigator(vs.Surfaces[1]); bgbuff.GoTo(vs.XStart + x, y); Gdi.Blit(backbuff, bgbuff, width, height); if (_charset.HasMask) { var mask = new PixelNavigator(_textSurface); mask.GoToIgnoreBytesByPixel(x * _textSurfaceMultiplier, (y - ScreenTop) * _textSurfaceMultiplier); Gdi.Fill(mask, CharsetMaskTransparency, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); } } } else { if (_game.Features.HasFlag(GameFeatures.Is16BitColor)) { Gdi.Fill(backbuff, _16BitPalette[color], width, height); } else { if (_game.Platform == Platform.FMTowns) { color = ((color & 0x0f) << 4) | (color & 0x0f); var mask = new PixelNavigator(_textSurface); mask.GoTo(x * _textSurfaceMultiplier, (y - ScreenTop + vs.TopLine) * _textSurfaceMultiplier); Gdi.Fill(mask, (byte)color, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier); if (Game.GameId == GameId.Monkey2 || Game.GameId == GameId.Indy4 || ((Game.GameId == GameId.Indy3 || Game.GameId == GameId.Zak) && vs != TextVirtScreen) || (_game.GameId == GameId.Loom && vs == MainVirtScreen)) { return; } } Gdi.Fill(backbuff, (byte)color, width, height); } } }