Пример #1
0
        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;
        }
Пример #2
0
        System.Drawing.Color ToColor(byte[] pixels, Palette palette, VirtScreen screen, int x, int y)
        {
            var index = pixels[y * screen.Width + x];
            var c     = palette.Colors[index];

            return(System.Drawing.Color.FromArgb(c.R, c.G, c.B));
        }
Пример #3
0
        void UpdateDirtyScreen(VirtScreen vs)
        {
            // Do nothing for unused virtual screens
            if (vs.Height == 0)
            {
                return;
            }

            int i;
            int w     = 8;
            int start = 0;

            for (i = 0; i < Gdi.NumStrips; i++)
            {
                if (vs.BDirty[i] != 0)
                {
                    int top    = vs.TDirty[i];
                    int bottom = vs.BDirty[i];
                    vs.TDirty[i] = vs.Height;
                    vs.BDirty[i] = 0;
                    if (i != (Gdi.NumStrips - 1) && vs.BDirty[i + 1] == bottom && vs.TDirty[i + 1] == top)
                    {
                        // Simple optimizations: if two or more neighboring strips
                        // form one bigger rectangle, coalesce them.
                        w += 8;
                        continue;
                    }
                    DrawStripToScreen(vs, start * 8, w, top, bottom);
                    w = 8;
                }
                start = i + 1;
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        System.Drawing.Color ToColor(Room room, VirtScreen screen, int x, int y)
        {
            var index = screen.Surfaces[0].Pixels[y * screen.Width + x];
            var c     = Game.Features.HasFlag(GameFeatures.SixteenColors) ?
                        Palette.Cga.Colors[index] : room.Palette.Colors[index];

            return(System.Drawing.Color.FromArgb(c.R, c.G, c.B));
        }
Пример #6
0
        void DumpRoomObjectImages(Room room, ObjectData obj, Gdi gdi)
        {
            var text = new ScummText(obj.Name);
            var sb   = new StringBuilder();

            sb.Append("Object #" + obj.Number).Append(" ");

            var decoder = new TextDecoder(sb);

            text.Decode(decoder);

            sb.AppendFormat(" size: {0}x{1}", obj.Width, obj.Height);
            Console.WriteLine(sb);

            var j = 0;

            foreach (var img in obj.Images)
            {
//                try
//                {
                var screen = new VirtScreen(0, obj.Width, obj.Height, PixelFormat.Indexed8, 2);
                if (img.IsBomp)
                {
                    var bdd = new BompDrawData();
                    bdd.Src = img.Data;
                    bdd.Dst = new PixelNavigator(screen.Surfaces[0]);
                    bdd.X   = 0;
                    bdd.Y   = 0;

                    bdd.Width  = obj.Width;
                    bdd.Height = obj.Height;

                    bdd.ScaleX = 255;
                    bdd.ScaleY = 255;
                    bdd.DrawBomp();
                }
                else
                {
                    gdi.DrawBitmap(img, screen, new Point(0, 0), obj.Width, obj.Height & 0xFFF8, 0, obj.Width / 8, room.Header.Width, DrawBitmaps.None, true);
                }

                using (var bmp = ToBitmap(room, screen))
                {
                    bmp.Save("obj_" + obj.Number + "_" + (++j) + ".png");
                }
//                }
//                catch (Exception e)
//                {
//                    Console.ForegroundColor = ConsoleColor.Red;
//                    Console.WriteLine(e);
//                    Console.ResetColor();
//                    Console.ReadLine();
//                }
            }
        }
Пример #7
0
        System.Drawing.Bitmap ToBitmap(Room room, VirtScreen screen)
        {
            var bmp = new System.Drawing.Bitmap(screen.Width, screen.Height);
//            DitherCGA(screen.Surfaces[0].Pixels, screen.Surfaces[0].Pitch, 0, 0, screen.Width, screen.Height);
            var palette = Game.Features.HasFlag(GameFeatures.SixteenColors) ? Palette.Ega : room.Palette;

            for (int x = 0; x < screen.Width; x++)
            {
                for (int y = 0; y < screen.Height; y++)
                {
                    bmp.SetPixel(x, y, ToColor(screen.Surfaces[0].Pixels, palette, screen, x, y));
                }
            }
            return(bmp);
        }
Пример #8
0
        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);
        }
Пример #9
0
        protected void InitScreens(int b, int h)
        {
            if (_townsScreen != null)
            {
                if (_townsClearLayerFlag == 0 && MainVirtScreen != null && ((h - b) != MainVirtScreen.Height))
                {
                    _townsScreen.ClearLayer(0);
                }

                if (Game.GameId != GameId.Monkey1)
                {
                    Gdi.Fill(TextSurface,
                             new Rect(0, 0, _textSurface.Width * _textSurfaceMultiplier, _textSurface.Height * _textSurfaceMultiplier), 0);
                    _townsScreen.ClearLayer(1);
                }
            }

            var format = Game.Features.HasFlag(GameFeatures.Is16BitColor) ? PixelFormat.Rgb16 : PixelFormat.Indexed8;

            _mainVirtScreen = new VirtScreen(b, ScreenWidth, h - b, format, 2, true);
            _textVirtScreen = new VirtScreen(0, ScreenWidth, b, format, 1);
            _verbVirtScreen = new VirtScreen(h, ScreenWidth, ScreenHeight - h, format, 1);

            // Since the size of screen 3 is fixed, there is no need to reallocate
            // it if its size changed.
            // Not sure what it is good for, though. I think it may have been used
            // in pre-V7 for the games messages (like 'Pause', Yes/No dialogs,
            // version display, etc.). I don't know about V7, maybe the same is the
            // case there. If so, we could probably just remove it completely.
            if (_game.Version >= 7)
            {
                _unkVirtScreen = new VirtScreen((ScreenHeight / 2) - 10, ScreenWidth, 13, format, 1);
            }
            else
            {
                _unkVirtScreen = new VirtScreen(80, ScreenWidth, 13, format, 1);
            }

            _screenB = b;
            _screenH = h;

            Gdi.Init();
        }
Пример #10
0
        void DumpRoomImage(Room room, Gdi gdi)
        {
            var name = room.Name ?? "room_" + room.Number;

            var screen    = new VirtScreen(0, room.Header.Width, room.Header.Height, PixelFormat.Indexed8, 2);
            var numStrips = room.Header.Width / 8;

            gdi.NumStrips        = numStrips;
            gdi.IsZBufferEnabled = false;
            if (room.Header.Height > 0)
            {
                gdi.RoomChanged(room);
                gdi.DrawBitmap(room.Image, screen, new Point(), room.Header.Width, room.Header.Height, 0, numStrips, room.Header.Width, 0, true);

                using (var bmpRoom = ToBitmap(room, screen))
                {
                    bmpRoom.Save(name + ".png");
                }
            }

            DumpZPlanes(room, name);
        }
Пример #11
0
        internal void MarkRectAsDirty(VirtScreen vs, int left, int right, int top, int bottom, int dirtybit = 0)
        {
            int lp, rp;

            if (left > right || top > bottom)
            {
                return;
            }
            if (top > vs.Height || bottom < 0)
            {
                return;
            }

            if (top < 0)
            {
                top = 0;
            }
            if (bottom > vs.Height)
            {
                bottom = vs.Height;
            }

            if (vs == MainVirtScreen && dirtybit != 0)
            {
                lp = left / 8 + _screenStartStrip;
                if (lp < 0)
                {
                    lp = 0;
                }

                rp = (right + vs.XStart) / 8;
                if (_game.Version >= 7)
                {
                    if (rp > 409)
                    {
                        rp = 409;
                    }
                }
                else
                {
                    if (rp >= 200)
                    {
                        rp = 200;
                    }
                }
                for (; lp <= rp; lp++)
                {
                    Gdi.SetGfxUsageBit(lp, dirtybit);
                }
            }

            // The following code used to be in the separate method setVirtscreenDirty
            lp = left / 8;
            rp = right / 8;

            if ((lp >= Gdi.NumStrips) || (rp < 0))
            {
                return;
            }
            if (lp < 0)
            {
                lp = 0;
            }
            if (rp >= Gdi.NumStrips)
            {
                rp = Gdi.NumStrips - 1;
            }

            while (lp <= rp)
            {
                if (top < vs.TDirty[lp])
                {
                    vs.TDirty[lp] = top;
                }
                if (bottom > vs.BDirty[lp])
                {
                    vs.BDirty[lp] = bottom;
                }
                lp++;
            }
        }
Пример #12
0
 internal void MarkRectAsDirty(VirtScreen vs, Rect r, int dirtybit = 0)
 {
     MarkRectAsDirty(vs, r.Left, r.Right, r.Top, r.Bottom, dirtybit);
 }
Пример #13
0
        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);
        }
Пример #14
0
        /// <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);
        }
Пример #15
0
 static bool VirtScreenContains(VirtScreen vs, int y)
 {
     return(y >= vs.TopLine && y < vs.TopLine + vs.Height);
 }
Пример #16
0
        internal void StartScene(byte room, Actor a = null, int objectNr = 0)
        {
            StopTalk();

            FadeOut(_switchRoomEffect2);
            _newEffect = _switchRoomEffect;

            if (CurrentScript != 0xFF)
            {
                if (_slots[CurrentScript].Where == WhereIsObject.Room || _slots[CurrentScript].Where == WhereIsObject.FLObject)
                {
                    //nukeArrays(CurrentScript);
                    CurrentScript = 0xFF;
                }
                else if (_slots[CurrentScript].Where == WhereIsObject.Local)
                {
                    //if (slots[CurrentScript].cutsceneOverride && _game.version >= 5)
                    //    error("Script %d stopped with active cutscene/override in exit", slots[CurrentScript].number);

                    //nukeArrays(CurrentScript);
                    CurrentScript = 0xFF;
                }
            }

            if (VariableNewRoom.HasValue)
            {
                _variables[VariableNewRoom.Value] = room;
            }

            RunExitScript();

            KillScriptsAndResources();

            if (_game.Version >= 4)
            {
                StopCycle(0);
            }

            for (var i = 1; i < Actors.Length; i++)
            {
                Actors[i].Hide();
            }

            if (Game.Version >= 7)
            {
                // Set the shadow palette(s) to all black. This fixes
                // bug #795940, and actually makes some sense (after all,
                // shadows tend to be rather black, don't they? ;-)
                Array.Clear(_shadowPalette, 0, _shadowPalette.Length);
            }
            else
            {
                for (var i = 0; i < 256; i++)
                {
                    Gdi.RoomPalette[i] = (byte)i;
                    if (_shadowPalette != null)
                    {
                        _shadowPalette[i] = (byte)i;
                    }
                }

                if (Game.Version < 5)
                {
                    SetDirtyColors(0, 255);
                }
            }

            Variables[VariableRoom.Value] = room;
            _fullRedraw = true;

            _currentRoom = room;

            if (room >= 0x80 && Game.Version < 7)
            {
                _roomResource = _resourceMapper[room & 0x7F];
            }
            else
            {
                _roomResource = room;
            }

            if (VariableRoomResource.HasValue)
            {
                Variables[VariableRoomResource.Value] = _roomResource;
            }

            if (room != 0)
            {
                ResourceManager.LoadRoom(room);
            }

            if (room != 0 && _game.Version == 5 && room == _roomResource)
            {
                Variables[VariableRoomFlag.Value] = 1;
            }

            ClearRoomObjects();

            if (_currentRoom == 0)
            {
                if (roomData != null)
                {
                    _ignoreEntryExitScript   = true;
                    roomData.ExitScript.Data = new byte[0];
                    //roomData.Objects.Clear();
                }
                return;
            }

            roomData = _resManager.GetRoom(_roomResource);
            _ignoreEntryExitScript = false;
            if (roomData.HasPalette)
            {
                SetCurrentPalette(0);
            }

            Gdi.NumZBuffer = GetNumZBuffers();

            Gdi.TransparentColor = roomData.TransparentColor;
            ResetRoomSubBlocks();
            ResetRoomObjects();
            _drawingObjects.Clear();

            if (Game.Version >= 7)
            {
                // Resize main virtual screen in V7 games. This is necessary
                // because in V7, rooms may be higher than one screen, so we have
                // to accomodate for that.
                _mainVirtScreen = new VirtScreen(MainVirtScreen.TopLine, ScreenWidth, roomData.Header.Height - MainVirtScreen.TopLine, MainVirtScreen.PixelFormat, 2, true);
            }
            Gdi.SetMaskHeight(roomData.Header.Height);

            if (VariableRoomWidth.HasValue && VariableRoomHeight.HasValue)
            {
                Variables[VariableRoomWidth.Value]  = roomData.Header.Width;
                Variables[VariableRoomHeight.Value] = roomData.Header.Height;
            }

            if (VariableCameraMinX.HasValue)
            {
                _variables[VariableCameraMinX.Value] = ScreenWidth / 2;
            }
            if (VariableCameraMaxX.HasValue)
            {
                _variables[VariableCameraMaxX.Value] = roomData.Header.Width - (ScreenWidth / 2);
            }

            if (Game.Version >= 7)
            {
                Variables[VariableCameraMinY.Value] = ScreenHeight / 2;
                Variables[VariableCameraMaxY.Value] = roomData.Header.Height - (ScreenHeight / 2);
                SetCameraAt(new Point((ScreenWidth / 2), (ScreenHeight / 2)));
            }
            else
            {
                _camera.Mode = CameraMode.Normal;
                _camera.CurrentPosition.X = _camera.DestinationPosition.X = (ScreenWidth / 2);
                _camera.CurrentPosition.Y = _camera.DestinationPosition.Y = (ScreenHeight / 2);
            }

            if (_roomResource == 0)
            {
                return;
            }

            Gdi.ClearGfxUsageBits();

            if (_game.Version >= 5 && a != null)
            {
                var where = GetWhereIsObject(objectNr);
                if (where != WhereIsObject.Room && where != WhereIsObject.FLObject)
                {
                    throw new NotSupportedException(string.Format("StartScene: Object {0} is not in room {1}", objectNr, _currentRoom));
                }

                Point pos;
                int   dir;
                GetObjectXYPos(objectNr, out pos, out dir);
                a.PutActor(pos, _currentRoom);
                a.SetDirection(dir + 180);
                a.StopActorMoving();

                if (Game.GameId == Scumm.IO.GameId.SamNMax)
                {
                    Camera.CurrentPosition.X = Camera.DestinationPosition.X = a.Position.X;
                    SetCameraAt(a.Position);
                }
            }

            ShowActors();

            EgoPositioned = false;

            TownsResetPalCycleFields();

            RunEntryScript();

            if (Game.Version >= 1 && Game.Version <= 2)
            {
                RunScript(5, false, false, new int[0]);
            }
            else if ((Game.Version >= 5) && (Game.Version <= 6))
            {
                if (a != null && !EgoPositioned)
                {
                    var pos = GetObjectXYPos(objectNr);
                    a.PutActor(pos, _currentRoom);
                    a.Moving = 0;
                }
            }
            else if (_game.Version >= 7)
            {
                if (Camera.ActorToFollow != 0)
                {
                    a = Actors[Camera.ActorToFollow];
                    SetCameraAt(a.Position);
                }
            }

            _doEffect = true;

            // Hint the backend about the virtual keyboard during copy protection screens
            if (_game.GameId == GameId.Monkey2)
            {
                if (room == 108)
                {
                    _inputManager.ShowVirtualKeyboard();
                }
                else
                {
                    _inputManager.HideVirtualKeyboard();
                }
            }
            else if (_game.GameId == GameId.Monkey1 && _game.Variant == "ega")
            {   // this is my estimation that the room code is 90 (untested)
                if (room == 90)
                {
                    _inputManager.ShowVirtualKeyboard();
                }
                else
                {
                    _inputManager.HideVirtualKeyboard();
                }
            }
        }