Beispiel #1
0
        private void HandleKeyPress(ScummInputState kbd, StringBuilder textBuf)
        {
            if (kbd.IsKeyDown(KeyCode.Backspace))
            { // backspace
                if (textBuf.Length > 0)
                    textBuf.Remove(textBuf.Length - 1, 1);
            }
            else
            {
                // TODO: do this in ScummInputState ?
                var key = (char?)kbd.GetKeys().Where(k => k >= (KeyCode)32 && k <= (KeyCode)126).Select(k => (KeyCode?)k).FirstOrDefault();
                if (!key.HasValue)
                    return;

                // Cannot enter text wider than the save/load panel
                if (_enteredTextWidth >= PanLineWidth - 10)
                    return;

                // Cannot enter text longer than MaxTextLen-1 chars, since
                // the storage is only so big. Note: The code used to incorrectly
                // allow up to MaxTextLen, which caused an out of bounds access,
                // overwriting the next entry in the list of savegames partially.
                // This could be triggered by e.g. entering lots of periods ".".
                if (textBuf.Length >= MaxTextLen - 1)
                    return;

                // Allow the key only if is a letter, a digit, or one of a selected
                // list of extra characters

                if (char.IsLetterOrDigit(key.Value) || " ,().='-&+!?\"".Contains(key.Value.ToString()))
                {
                    textBuf.Append(key);
                }
            }
        }
Beispiel #2
0
        private ushort SaveRestorePanel(bool allowSave)
        {
            _keyPressed = new ScummInputState();
            _system.InputManager.ResetKeys();
            _mouseWheel = 0;
            ButtonControl(null);
            _text.DrawToScreen(WithMask); // flush text restore buffer

            ConResource[] lookList;
            ushort cnt;
            byte lookListLen;
            if (allowSave)
            {
                lookList = _savePanLookList;
                lookListLen = 6;
                _system.InputManager.ShowVirtualKeyboard();
            }
            else
            {
                lookList = _restorePanLookList;
                if (AutoSaveExists())
                    lookListLen = 7;
                else
                    lookListLen = 6;
            }
            bool withAutoSave = lookListLen == 7;

            var textSprites = new byte[MaxOnScreen + 1][];
            _firstText = 0;

            var saveGameTexts = LoadDescriptions().Select(s => new StringBuilder(s)).ToArray();
            _selectedGame = 0;

            bool quitPanel = false;
            bool refreshNames = true;
            bool refreshAll = true;
            ushort clickRes = 0;
            while (!quitPanel && !SkyEngine.ShouldQuit)
            {
                clickRes = 0;
                if (refreshNames || refreshAll)
                {
                    if (refreshAll)
                    {
                        _text.FlushForRedraw();
                        _savePanel.DrawToScreen(NoMask);
                        _quitButton.DrawToScreen(NoMask);
                        if (withAutoSave)
                            _autoSaveButton.DrawToScreen(NoMask);
                        refreshAll = false;
                    }
                    for (cnt = 0; cnt < MaxOnScreen; cnt++)
                        if (textSprites[cnt] != null)
                            textSprites[cnt] = null;
                    SetUpGameSprites(saveGameTexts, textSprites, _firstText, _selectedGame);
                    ShowSprites(textSprites, allowSave);
                    refreshNames = false;
                }

                _text.DrawToScreen(WithMask);
                _system.GraphicsManager.UpdateScreen();
                _mouseClicked = false;
                Delay(50);
                if (_controlPanel == null)
                    return clickRes;
                if (_keyPressed.IsKeyDown(KeyCode.Escape))
                { // escape pressed
                    _mouseClicked = false;
                    clickRes = CancelPressed;
                    quitPanel = true;
                }
                else if (_keyPressed.IsKeyDown(KeyCode.Return)) // TODO: || _keyPressed.IsKeyDown(KeyCode.Enter)
                {
                    clickRes = HandleClick(lookList[0]);
                    if (_controlPanel == null) //game state was destroyed
                        return clickRes;
                    if (clickRes == GameSaved)
                        SaveDescriptions(saveGameTexts);
                    else if (clickRes == NoDiskSpace)
                    {
                        // TODO: DisplayMessage(0, "Could not save the game. (%s)", _saveFileMan.popErrorDesc().c_str());
                    }
                    quitPanel = true;
                    _mouseClicked = false;
                    _keyPressed = new ScummInputState();
                    _system.InputManager.ResetKeys();
                }
                if (allowSave && _keyPressed.GetKeys().Count > 0)
                {
                    HandleKeyPress(_keyPressed, saveGameTexts[_selectedGame]);
                    refreshNames = true;
                    _keyPressed = new ScummInputState();
                    _system.InputManager.ResetKeys();
                }

                if (_mouseWheel != 0)
                {
                    if (_mouseWheel < 0)
                        clickRes = ShiftUp(Slow);
                    else if (_mouseWheel > 0)
                        clickRes = ShiftDown(Slow);
                    _mouseWheel = 0;
                    if (clickRes == Shifted)
                    {
                        _selectedGame = _firstText;
                        refreshNames = true;
                    }
                }

                bool haveButton = false;
                var mouse = _system.InputManager.GetMousePosition();
                for (cnt = 0; cnt < lookListLen; cnt++)
                    if (lookList[cnt].IsMouseOver((uint)mouse.X, (uint)mouse.Y))
                    {
                        ButtonControl(lookList[cnt]);
                        haveButton = true;

                        if (_mouseClicked && lookList[cnt].OnClick != 0)
                        {
                            _mouseClicked = false;

                            clickRes = HandleClick(lookList[cnt]);
                            if (_controlPanel == null) //game state was destroyed
                                return clickRes;

                            if (clickRes == Shifted)
                            {
                                _selectedGame = _firstText;
                                refreshNames = true;
                            }
                            if (clickRes == NoDiskSpace)
                            {
                                // TODO: DisplayMessage(0, "Could not save the game. (%s)", _saveFileMan.popErrorDesc().c_str());
                                quitPanel = true;
                            }
                            if ((clickRes == CancelPressed) || (clickRes == GameRestored))
                                quitPanel = true;

                            if (clickRes == GameSaved)
                            {
                                SaveDescriptions(saveGameTexts);
                                quitPanel = true;
                            }
                            if (clickRes == RestoreFailed)
                                refreshAll = true;
                        }
                    }

                if (_mouseClicked)
                {
                    if ((mouse.X >= GameNameX) && (mouse.X <= GameNameX + PanLineWidth) &&
                        (mouse.Y >= GameNameY) && (mouse.Y <= GameNameY + PanCharHeight * MaxOnScreen))
                    {

                        _selectedGame = (ushort)((mouse.Y - GameNameY) / PanCharHeight + _firstText);
                        refreshNames = true;
                    }
                }
                if (!haveButton)
                    ButtonControl(null);
            }

            for (cnt = 0; cnt < MaxOnScreen + 1; cnt++)
                textSprites[cnt] = null;

            if (allowSave)
            {
                _system.InputManager.HideVirtualKeyboard();
            }

            return clickRes;
        }
Beispiel #3
0
        internal protected virtual void ProcessInput()
        {
            //
            // Determine the mouse button state.
            //
            mouseAndKeyboardStat = 0;

            if (_leftBtnPressed.HasFlag(MouseButtonStatus.Clicked) && _rightBtnPressed.HasFlag(MouseButtonStatus.Clicked))
            {
                // Pressing both mouse buttons is treated as if you pressed
                // the cutscene exit key (ESC) in V4+ games. That mimicks
                // the behavior of the original engine where pressing both
                // mouse buttons also skips the current cutscene.
                mouseAndKeyboardStat = 0;
//                lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
            }
            else if (_rightBtnPressed.HasFlag(MouseButtonStatus.Clicked) && (Game.Version <= 3 && Game.GameId != GameId.Loom))
            {
                // Pressing right mouse button is treated as if you pressed
                // the cutscene exit key (ESC) in V0-V3 games. That mimicks
                // the behavior of the original engine where pressing right
                // mouse button also skips the current cutscene.
                mouseAndKeyboardStat = 0;
//                lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE);
            }
            else if (_leftBtnPressed.HasFlag(MouseButtonStatus.Clicked))
            {
                mouseAndKeyboardStat = (KeyCode)ScummMouseButtonState.LeftClick;
            }
            else if (_rightBtnPressed.HasFlag(MouseButtonStatus.Clicked))
            {
                mouseAndKeyboardStat = (KeyCode)ScummMouseButtonState.RightClick;
            }

            if (Game.Version >= 6)
            {
                Variables[VariableLeftButtonHold.Value]  = _leftBtnPressed.HasFlag(MouseButtonStatus.Down) ? 1 : 0;
                Variables[VariableRightButtonHold.Value] = _rightBtnPressed.HasFlag(MouseButtonStatus.Down) ? 1 : 0;

                // scumm7: left/right button down
                if (Game.Version >= 7)
                {
                    Variables[VariableLeftButtonDown.Value]  = _leftBtnPressed.HasFlag(MouseButtonStatus.Clicked) ? 1 : 0;
                    Variables[VariableRightButtonDown.Value] = _rightBtnPressed.HasFlag(MouseButtonStatus.Clicked) ? 1 : 0;
                }
            }

            _leftBtnPressed  &= ~MouseButtonStatus.Clicked;
            _rightBtnPressed &= ~MouseButtonStatus.Clicked;

            var cutsceneExitKeyEnabled = (!VariableCutSceneExitKey.HasValue || Variables[VariableCutSceneExitKey.Value] != 0);
            var mainmenuKeyEnabled     = !VariableMainMenu.HasValue || _variables[VariableMainMenu.Value] != 0;

            // For games which use VAR_MAINMENU_KEY, disable the mainmenu key if
            // requested by the scripts. We make an exception for COMI (i.e.
            // forcefully always enable it there), as that always disables it.
            if (Game.GameId == GameId.CurseOfMonkeyIsland)
            {
                mainmenuKeyEnabled = true;
            }

            if (cutsceneExitKeyEnabled && _inputState.IsKeyDown(KeyCode.Escape))
            {
                AbortCutscene();
                // VAR_CUTSCENEEXIT_KEY doesn't exist in SCUMM0
                if (VariableCutSceneExitKey.HasValue)
                {
                    mouseAndKeyboardStat = (KeyCode)Variables[VariableCutSceneExitKey.Value];
                }
            }

            if (mainmenuKeyEnabled && _inputState.IsKeyDown(KeyCode.F5))
            {
                if (VariableSaveLoadScript.HasValue && _currentRoom != 0)
                {
                    RunScript(Variables[VariableSaveLoadScript.Value], false, false, new int[0]);
                }

                ShowMenu();

                if (VariableSaveLoadScript2.HasValue && _currentRoom != 0)
                {
                    RunScript(Variables[VariableSaveLoadScript2.Value], false, false, new int[0]);
                }
            }

            for (var i = KeyCode.A; i <= KeyCode.Z; i++)
            {
                if (_inputState.IsKeyDown(i))
                {
                    mouseAndKeyboardStat = i;
                }
            }
            for (var i = KeyCode.F1; i <= KeyCode.F9; i++)
            {
                if (_inputState.IsKeyDown(i))
                {
                    mouseAndKeyboardStat = i;
                }
            }

            if (_inputState.IsKeyDown(KeyCode.Return))
            {
                mouseAndKeyboardStat = KeyCode.Return;
            }
            if (_inputState.IsKeyDown(KeyCode.Backspace))
            {
                mouseAndKeyboardStat = KeyCode.Backspace;
            }
            if (_inputState.IsKeyDown(KeyCode.Tab))
            {
                mouseAndKeyboardStat = KeyCode.Tab;
            }
            if (_inputState.IsKeyDown(KeyCode.Space))
            {
                mouseAndKeyboardStat = KeyCode.Space;
            }

            if ((Game.GameId == Scumm.IO.GameId.Indy4 || Game.GameId == Scumm.IO.GameId.Pass))
            {
                var numpad = new int[]
                {
                    '0',
                    335, 336, 337,
                    331, 332, 333,
                    327, 328, 329
                };

                for (var i = KeyCode.D0; i <= KeyCode.D9; i++)
                {
                    if (_inputState.IsKeyDown(i))
                    {
                        mouseAndKeyboardStat = (KeyCode)numpad[i - KeyCode.D0];
                    }
                }
            }
            else
            {
                for (var i = KeyCode.D0; i <= KeyCode.D9; i++)
                {
                    if (_inputState.IsKeyDown(i))
                    {
                        mouseAndKeyboardStat = i - (int)KeyCode.D0 + '0';
                    }
                }
            }

            _mousePos = _inputManager.GetMousePosition();
            if (_mousePos.X < 0)
            {
                _mousePos.X = 0;
            }
            if (_mousePos.X > ScreenWidth - 1)
            {
                _mousePos.X = (short)(ScreenWidth - 1);
            }
            if (_mousePos.Y < 0)
            {
                _mousePos.Y = 0;
            }
            if (_mousePos.Y > ScreenHeight - 1)
            {
                _mousePos.Y = (short)(ScreenHeight - 1);
            }

            var mouseX = (ScreenStartStrip * 8) + _mousePos.X;
            var mouseY = _mousePos.Y - MainVirtScreen.TopLine + ((_game.Version >= 7) ? ScreenTop : 0);

            if (Game.Version >= 3)
            {
                Variables[VariableMouseX.Value]        = _mousePos.X;
                Variables[VariableMouseY.Value]        = _mousePos.Y;
                Variables[VariableVirtualMouseX.Value] = mouseX;
                Variables[VariableVirtualMouseY.Value] = mouseY;
            }
            else if (Game.Version >= 1)
            {
                // We use shifts below instead of dividing by V12_X_MULTIPLIER resp.
                // V12_Y_MULTIPLIER to handle negative coordinates correctly.
                // This fixes e.g. bugs #1328131 and #1537595.
                Variables[VariableVirtualMouseX.Value] = mouseX >> V12_X_SHIFT;
                Variables[VariableVirtualMouseY.Value] = mouseY >> V12_Y_SHIFT;

                // Adjust mouse coordinates as narrow rooms in NES are centered
//                if (_game.platform == Common::kPlatformNES && _NESStartStrip > 0)
//                {
//                    VAR(VAR_VIRT_MOUSE_X) -= 2;
//                    if (VAR(VAR_VIRT_MOUSE_X) < 0)
//                        VAR(VAR_VIRT_MOUSE_X) = 0;
//                }
            }
        }
Beispiel #4
0
        private byte MainLoop()
        {
            byte retCode = 0;

            System.InputManager.ResetKeys();

            while ((retCode == 0) && !ShouldQuit)
            {
                // do we need the section45-hack from sword.c here?
                CheckCd();

                _screen.NewScreen(Logic.ScriptVars[(int)ScriptVariableNames.NEW_SCREEN]);
                _logic.NewScreen(Logic.ScriptVars[(int)ScriptVariableNames.NEW_SCREEN]);
                _sound.NewScreen(Logic.ScriptVars[(int)ScriptVariableNames.NEW_SCREEN]);
                Logic.ScriptVars[(int)ScriptVariableNames.SCREEN] = Logic.ScriptVars[(int)ScriptVariableNames.NEW_SCREEN];

                do
                {
                    int  newTime;
                    bool scrollFrameShown = false;

                    int frameTime = Environment.TickCount;
                    _logic.Engine();
                    _logic.UpdateScreenParams(); // sets scrolling

                    _screen.Draw();
                    _mouse.Animate();
                    _sound.Engine();
                    _menu.Refresh(Menu.MENU_TOP);
                    _menu.Refresh(Menu.MENU_BOT);

                    newTime = Environment.TickCount;
                    if (newTime - frameTime < 1000 / FRAME_RATE)
                    {
                        scrollFrameShown = _screen.ShowScrollFrame();
                        Delay(1000 / (FRAME_RATE * 2) - (Environment.TickCount - frameTime));
                    }

                    newTime = Environment.TickCount;
                    if ((newTime - frameTime < 1000 / FRAME_RATE) || !scrollFrameShown)
                    {
                        _screen.UpdateScreen();
                    }
                    Delay(1000 / FRAME_RATE - (Environment.TickCount - frameTime));

                    _mouse.Engine((ushort)_mouseCoord.X, (ushort)_mouseCoord.Y, _mouseState);

                    if (SystemVars.ForceRestart)
                    {
                        retCode = Control.CONTROL_RESTART_GAME;
                    }

                    // The control panel is triggered by F5 or ESC.
                    else if (((_keyPressed.IsKeyDown(KeyCode.F5) || _keyPressed.IsKeyDown(KeyCode.Escape)) &&
                              (Logic.ScriptVars[(int)ScriptVariableNames.MOUSE_STATUS] & 1) != 0) ||
                             (SystemVars.ControlPanelMode != 0))
                    {
                        retCode = _control.RunPanel();
                        if (retCode == Control.CONTROL_NOTHING_DONE)
                        {
                            _screen.FullRefresh();
                        }
                    }

                    // TODO: Check for Debugger Activation
                    //if (_keyPressed.hasFlags(Common::KBD_CTRL) && _keyPressed.keycode == Common::KEYCODE_d)
                    //{
                    //    this.getDebugger().attach();
                    //    this.getDebugger().onFrame();
                    //}

                    _mouseState = 0;
                    _keyPressed = new ScummInputState();
                } while ((Logic.ScriptVars[(int)ScriptVariableNames.SCREEN] == Logic.ScriptVars[(int)ScriptVariableNames.NEW_SCREEN]) && (retCode == 0) && !ShouldQuit);

                if ((retCode == 0) && (Logic.ScriptVars[(int)ScriptVariableNames.SCREEN] != 53) && SystemVars.WantFade && !ShouldQuit)
                {
                    _screen.FadeDownPalette();
                    int relDelay = Environment.TickCount;
                    while (_screen.StillFading())
                    {
                        relDelay += 1000 / FRAME_RATE;
                        _screen.UpdateScreen();
                        Delay(relDelay - Environment.TickCount);
                    }
                }

                _sound.QuitScreen();
                _screen.QuitScreen();                                                       // close graphic resources
                _objectMan.CloseSection(Logic.ScriptVars[(int)ScriptVariableNames.SCREEN]); // close the section that PLAYER has just left, if it's empty now
            }
            return(retCode);
        }
Beispiel #5
0
 private void HandleSaveKey(ScummInputState kbd)
 {
     if (_selectedSavegame < 255)
     {
         var saveName = new StringBuilder(_saveNames[_selectedSavegame]);
         byte len = (byte)_saveNames[_selectedSavegame].Length;
         if (kbd.IsKeyDown(KeyCode.Backspace) && len != 0)  // backspace
             saveName.Remove(saveName.Length - 1, 1);
         else
         {
             var key = kbd.GetKeys().Select(k => (char?)k).LastOrDefault();
             if (key.HasValue && keyAccepted(key.Value) && (len < 31))
             {
                 saveName.Append(key.Value);
             }
         }
         _saveNames[_selectedSavegame] = saveName.ToString();
         ShowSavegameNames();
     }
 }