public int DrawCostume(VirtScreen vs, int numStrips, Actor actor, bool drawToBackBuf) { var pixelsNavigator = new PixelNavigator(vs.Surfaces[drawToBackBuf ? 1 : 0]); pixelsNavigator.OffsetX(vs.XStart); ActorX += (vs.XStart & 7); _w = vs.Width; _h = vs.Height; pixelsNavigator.OffsetX(-(vs.XStart & 7)); startNav = new PixelNavigator(pixelsNavigator); if (_vm.Game.Version <= 1) { _xmove = 0; _ymove = 0; } else if (_vm.Game.IsOldBundle) { _xmove = -72; _ymove = -100; } else { _xmove = _ymove = 0; } int result = 0; for (int i = 0; i < 16; i++) { result |= DrawLimb(actor, i); } return(result); }
public int DrawCostume(VirtScreen vs, int numStrips, Actor actor, bool drawToBackBuf) { var pixelsNavigator = new PixelNavigator(vs.Surfaces[drawToBackBuf ? 1 : 0]); pixelsNavigator.OffsetX(vs.XStart); ActorX += (vs.XStart & 7); _w = vs.Width; _h = vs.Height; pixelsNavigator.OffsetX(-(vs.XStart & 7)); startNav = new PixelNavigator(pixelsNavigator); if (_vm.Game.Version <= 1) { _xmove = 0; _ymove = 0; } else if (_vm.Game.IsOldBundle) { _xmove = -72; _ymove = -100; } else { _xmove = _ymove = 0; } int result = 0; for (int i = 0; i < 16; i++) result |= DrawLimb(actor, i); return result; }
protected void FadeOut(int effect) { _mainVirtScreen.SetDirtyRange(0, 0); if (Game.Version < 7) { Camera.LastPosition.X = Camera.CurrentPosition.X; } if (Game.Version == 3 && _game.Platform == Platform.FMTowns) { Gdi.Fill(TextSurface, new Rect(0, MainVirtScreen.TopLine * _textSurfaceMultiplier, _textSurface.Pitch, (MainVirtScreen.TopLine + MainVirtScreen.Height) * _textSurfaceMultiplier), 0); } if ((Game.Version == 7 || _screenEffectFlag) && effect != 0) { // Fill screen 0 with black var pixNav = new PixelNavigator(_mainVirtScreen.Surfaces[0]); pixNav.OffsetX(_mainVirtScreen.XStart); Gdi.Fill(pixNav, 0, _mainVirtScreen.Width, _mainVirtScreen.Height); // Fade to black with the specified effect, if any. switch (effect) { case 1: case 2: case 3: case 4: case 5: case 6: DoTransitionEffect(effect - 1); break; case 128: UnkScreenEffect6(); break; case 129: // Just blit screen 0 to the display (i.e. display will be black) _mainVirtScreen.SetDirtyRange(0, _mainVirtScreen.Height); UpdateDirtyScreen(_mainVirtScreen); if (_townsScreen != null) { _townsScreen.Update(); } break; default: throw new NotImplementedException(string.Format("fadeOut: case {0}", effect)); } } // Update the palette at the end (once we faded to black) to avoid // some nasty effects when the palette is changed UpdatePalette(); _screenEffectFlag = false; }
void RestoreCharsetBg() { _nextLeft = _string[0].Position.X; _nextTop = _string[0].Position.Y + ScreenTop; if (_charset.HasMask) { _charset.HasMask = false; _charset.Str.Left = -1; _charset.Left = -1; // Restore background on the whole text area. This code is based on // restoreBackground(), but was changed to only restore those parts which are // currently covered by the charset mask. var vs = _charset.TextScreen; if (vs.Height == 0) { return; } MarkRectAsDirty(vs, 0, vs.Width, 0, vs.Height, Gdi.UsageBitRestored); if (vs.HasTwoBuffers && _currentRoom != 0 && IsLightOn()) { if (vs != MainVirtScreen) { // Restore from back buffer var screenBufNav = new PixelNavigator(vs.Surfaces[0]); screenBufNav.OffsetX(vs.XStart); var backNav = new PixelNavigator(vs.Surfaces[1]); backNav.OffsetX(vs.XStart); Gdi.Blit(screenBufNav, backNav, vs.Width, vs.Height); } } else { // Clear area var screenBuf = vs.Surfaces[0].Pixels; Array.Clear(screenBuf, 0, screenBuf.Length); } if (vs.HasTwoBuffers) { // Clean out the charset mask ClearTextSurface(); } } }
static byte[] Capture(VirtScreen screen, int x, int y, int w, int h) { var pixels = new byte[w * h]; var nav = new PixelNavigator(screen.Surfaces[0]); nav.GoTo(x, y); for (int height = 0; height < h; height++) { for (int width = 0; width < w; width++) { pixels[height * w + width] = nav.Read(); nav.OffsetX(1); } nav.Offset(-w, 1); } return(pixels); }
protected void TownsDrawStripToScreen(VirtScreen vs, int dstX, int dstY, int srcX, int srcY, int width, int height) { if (width <= 0 || height <= 0) { return; } int m = _textSurfaceMultiplier; var src1 = new PixelNavigator(vs.Surfaces[0]); src1.GoTo(vs.XStart + srcX, srcY); var src2 = new PixelNavigator(_textSurface); src2.GoTo(srcX * m, (srcY + vs.TopLine - ScreenTop) * m); var dst1 = new PixelNavigator(_townsScreen.GetLayerPixels(0, dstX, dstY).Value); var dst2 = new PixelNavigator(_townsScreen.GetLayerPixels(1, dstX * m, dstY * m).Value); int dp1 = _townsScreen.GetLayerPitch(0) - width * _townsScreen.GetLayerBpp(0); int dp2 = _townsScreen.GetLayerPitch(1) - width * m * _townsScreen.GetLayerBpp(1); int sp1 = vs.Pitch - (width * Surface.GetBytesPerPixel(vs.PixelFormat)); int sp2 = _textSurface.Pitch - width * m; if (vs == MainVirtScreen || Game.GameId == GameId.Indy3 || Game.GameId == GameId.Zak) { for (int h = 0; h < height; ++h) { if (Surface.GetBytesPerPixel(_gfxManager.PixelFormat) == 2) { for (int w = 0; w < width; ++w) { dst1.WriteUInt16(_16BitPalette[src1.Read()]); src1.OffsetX(1); dst1.OffsetX(1); } src1.OffsetX(sp1 / src1.BytesByPixel); dst1.OffsetX(dp1 / dst1.BytesByPixel); } else { for (int i = 0; i < width; i++) { dst1.Write(src1.Read()); dst1.OffsetX(1); src1.OffsetX(1); } } for (int sH = 0; sH < m; ++sH) { for (int i = 0; i < width * m; i++) { dst2.Write(src2.Read()); src2.OffsetX(1); dst2.OffsetX(1); } src2.OffsetX(_textSurface.Width - (width * m)); dst2.OffsetX(dst2.Width - (width * m)); } } } else { dst1 = new PixelNavigator(dst2); for (int h = 0; h < height; ++h) { for (int w = 0; w < width; ++w) { var t = (src1.Read()) & 0x0f; src1.OffsetX(1); for (int i = 0; i < m; i++) { dst1.Write((byte)((t << 4) | t)); dst1.OffsetX(1); } } dst1 = new PixelNavigator(dst2); var src3 = new PixelNavigator(src2); if (m == 2) { dst2.OffsetY(1); src3.OffsetY(1); } for (int w = 0; w < width * m; ++w) { dst2.Write((byte)(src3.Read() | dst1.Read() & _townsLayer2Mask[src3.Read()])); dst2.OffsetX(1); dst1.Write((byte)(src2.Read() | dst1.Read() & _townsLayer2Mask[src2.Read()])); src2.OffsetX(1); src3.OffsetX(1); dst1.OffsetX(1); } src1.OffsetX(sp1 / src1.BytesByPixel); src2 = new PixelNavigator(src3); src2.OffsetX(sp2 / src2.BytesByPixel); dst1 = new PixelNavigator(dst2); dst1.OffsetX(dp2 / dst1.BytesByPixel); dst2.OffsetX(dp2 / dst2.BytesByPixel); } } _townsScreen.AddDirtyRect(dstX * m, dstY * m, width * m, height * m); }
/// <summary> /// Blit the specified rectangle from the given virtual screen to the display. /// Note: t and b are in *virtual screen* coordinates, while x is relative to /// the *real screen*. This is due to the way tdirty/vdirty work: they are /// arrays which map 'strips' (sections of the real screen) to dirty areas as /// specified by top/bottom coordinate in the virtual screen. /// </summary> /// <param name="vs"></param> /// <param name="x"></param> /// <param name="width"></param> /// <param name="top"></param> /// <param name="bottom"></param> void DrawStripToScreen(VirtScreen vs, int x, int width, int top, int bottom) { // Short-circuit if nothing has to be drawn if (bottom <= top || top >= vs.Height) { return; } // Perform some clipping if (width > vs.Width - x) { width = vs.Width - x; } if (top < ScreenTop) { top = ScreenTop; } if (bottom > ScreenTop + ScreenHeight) { bottom = ScreenTop + ScreenHeight; } // Convert the vertical coordinates to real screen coords int y = vs.TopLine + top - ScreenTop; int height = bottom - top; if (width <= 0 || height <= 0) { return; } byte[] src; if (Game.Version < 7) { if (Game.Platform == Platform.FMTowns) { TownsDrawStripToScreen(vs, x, y, x, top, width, height); return; } var srcNav = new PixelNavigator(vs.Surfaces[0]); srcNav.GoTo(vs.XStart + x, top); var compNav = new PixelNavigator(_composite); var txtNav = new PixelNavigator(_textSurface); int m = _textSurfaceMultiplier; txtNav.GoTo(x * m, y * m); var vsPitch = vs.Pitch - width * vs.BytesPerPixel; var textPitch = _textSurface.Pitch - width * m; for (int h = height * m; h > 0; --h) { for (int w = width * m; w > 0; w--) { var temp = txtNav.Read(); int mask = temp ^ CharsetMaskTransparency; mask = (((mask & 0x7f) + 0x7f) | mask) & 0x80; mask = ((mask >> 7) + 0x7f) ^ 0x80; var dst = ((temp ^ srcNav.Read()) & mask) ^ temp; compNav.Write((byte)dst); srcNav.OffsetX(1); txtNav.OffsetX(1); compNav.OffsetX(1); } srcNav.OffsetX(vsPitch); txtNav.OffsetX(textPitch); } src = _composite.Pixels; } else { src = new byte[width * height * vs.BytesPerPixel]; var srcNav = new PixelNavigator(vs.Surfaces[0]); srcNav.GoTo(vs.XStart + x, top); for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { src[h * width + w] = srcNav.Read(); srcNav.OffsetX(1); } srcNav.Offset(-width, 1); } } // Finally blit the whole thing to the screen _gfxManager.CopyRectToScreen(src, width * vs.BytesPerPixel, x, y, width, height); }