diff options
author | Travis Howell | 2009-07-13 07:55:11 +0000 |
---|---|---|
committer | Travis Howell | 2009-07-13 07:55:11 +0000 |
commit | 01624bbb28a96376701c8afcfcb7fb651ac2d8bd (patch) | |
tree | 9189e2fa8d10cee94e4bbf07d60d57924cd9cdf3 /engines | |
parent | 93c91945045b738fb098403228d91bce40b469f7 (diff) | |
download | scummvm-rg350-01624bbb28a96376701c8afcfcb7fb651ac2d8bd.tar.gz scummvm-rg350-01624bbb28a96376701c8afcfcb7fb651ac2d8bd.tar.bz2 scummvm-rg350-01624bbb28a96376701c8afcfcb7fb651ac2d8bd.zip |
Fix bug #2820472 - MAZE: Keyboard input fault.
svn-id: r42434
Diffstat (limited to 'engines')
-rw-r--r-- | engines/scumm/he/intern_he.h | 3 | ||||
-rw-r--r-- | engines/scumm/input.cpp | 272 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 5 |
4 files changed, 157 insertions, 125 deletions
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index c2079fa5fe..4c2da19cc5 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -359,6 +359,8 @@ protected: virtual void setupScummVars(); virtual void resetScummVars(); + virtual void parseEvent(Common::Event event); + virtual void initCharset(int charset); virtual void clearDrawQueues(); @@ -386,6 +388,7 @@ protected: byte VAR_PLATFORM; byte VAR_PLATFORM_VERSION; byte VAR_CURRENT_CHARSET; + byte VAR_KEY_STATE; byte VAR_COLOR_DEPTH; }; diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index f378f2225e..42b48a3f3d 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -55,145 +55,173 @@ enum MouseButtonStatus { msClicked = 2 }; -void ScummEngine::parseEvents() { - Common::Event event; - - while (_eventMan->pollEvent(event)) { - - switch (event.type) { - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9' - && (event.kbd.flags == Common::KBD_ALT || - event.kbd.flags == Common::KBD_CTRL)) { - _saveLoadSlot = event.kbd.keycode - '0'; - - // don't overwrite autosave (slot 0) - if (_saveLoadSlot == 0) - _saveLoadSlot = 10; - - sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot); - _saveLoadFlag = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2; - _saveTemporaryState = false; - } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'f') { - _fastMode ^= 1; - } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'g') { - _fastMode ^= 2; - } else if ((event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'd') || - event.kbd.ascii == '~' || event.kbd.ascii == '#') { - _debugger->attach(); - } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 's') { - _res->resourceStats(); - } else { - // Normal key press, pass on to the game. - _keyPressed = event.kbd; - } +#ifdef ENABLE_HE +void ScummEngine_v80he::parseEvent(Common::Event event) { + ScummEngine::parseEvent(event); - if (_game.heversion >= 80) { - // FIXME: Move this code & VAR_KEY_STATE to class ScummEngine_v80he + // Keyboard is controlled via variable + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_LEFT) + VAR(VAR_KEY_STATE) |= 1; - // Keyboard is controlled via variable - int keyState = 0; + if (event.kbd.keycode == Common::KEYCODE_RIGHT) + VAR(VAR_KEY_STATE) |= 2; - if (event.kbd.keycode == Common::KEYCODE_LEFT) // Left - keyState = 1; + if (event.kbd.keycode == Common::KEYCODE_UP) + VAR(VAR_KEY_STATE) |= 4; - if (event.kbd.keycode == Common::KEYCODE_RIGHT) // Right - keyState |= 2; + if (event.kbd.keycode == Common::KEYCODE_DOWN) + VAR(VAR_KEY_STATE) |= 8; - if (event.kbd.keycode == Common::KEYCODE_UP) // Up - keyState |= 4; + if (event.kbd.keycode == Common::KEYCODE_LSHIFT || event.kbd.keycode == Common::KEYCODE_RSHIFT) + VAR(VAR_KEY_STATE) |= 16; - if (event.kbd.keycode == Common::KEYCODE_DOWN) // Down - keyState |= 8; + if (event.kbd.keycode == Common::KEYCODE_LCTRL || event.kbd.keycode == Common::KEYCODE_RCTRL) + VAR(VAR_KEY_STATE) |= 32; + break; - if (event.kbd.flags == Common::KBD_SHIFT) - keyState |= 16; + case Common::EVENT_KEYUP: + if (event.kbd.keycode == Common::KEYCODE_LEFT) + VAR(VAR_KEY_STATE) &= ~1; - if (event.kbd.flags == Common::KBD_CTRL) - keyState |= 32; + if (event.kbd.keycode == Common::KEYCODE_RIGHT) + VAR(VAR_KEY_STATE) &= ~2; - VAR(VAR_KEY_STATE) = keyState; - } + if (event.kbd.keycode == Common::KEYCODE_UP) + VAR(VAR_KEY_STATE) &= ~4; - // FIXME: We are using ASCII values to index the _keyDownMap here, - // yet later one code which checks _keyDownMap will use KEYCODEs - // to do so. That is, we are mixing ascii and keycode values here, - // which is bad. We probably should be only using keycodes, but at - // least INSANE checks for "Shift-V" by looking for the 'V' key - // being pressed. It would be easy to solve that by also storing - // the modifier flags. However, since getKeyState() is also called - // by scripts, we have to be careful with semantic changes. - if (_keyPressed.ascii >= 512) - debugC(DEBUG_GENERAL, "_keyPressed > 512 (%d)", _keyPressed.ascii); - else - _keyDownMap[_keyPressed.ascii] = true; - break; + if (event.kbd.keycode == Common::KEYCODE_DOWN) + VAR(VAR_KEY_STATE) &= ~8; - case Common::EVENT_KEYUP: - if (event.kbd.ascii >= 512) { - debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii); - } else { - _keyDownMap[event.kbd.ascii] = false; - - // Due to some weird bug with capslock key pressed - // generated keydown event is for lower letter but - // keyup is for upper letter - // On most (all?) keyboards it is safe to assume that - // both upper and lower letters are unpressed on keyup event - // - // Fixes bug #1709430: "FT: CAPSLOCK + V enables cheating for all fights" - // - // Fingolfin remarks: This wouldn't be a problem if we used keycodes. - _keyDownMap[toupper(event.kbd.ascii)] = false; - } - break; + if (event.kbd.keycode == Common::KEYCODE_LSHIFT || event.kbd.keycode == Common::KEYCODE_RSHIFT) + VAR(VAR_KEY_STATE) &= ~16; + if (event.kbd.keycode == Common::KEYCODE_LCTRL || event.kbd.keycode == Common::KEYCODE_RCTRL) + VAR(VAR_KEY_STATE) &= ~32; + break; - // We update the mouse position whenever the mouse moves or a click occurs. - // The latter is done to accomodate systems with a touchpad / pen controller. - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_RBUTTONDOWN: - case Common::EVENT_MOUSEMOVE: - if (event.type == Common::EVENT_LBUTTONDOWN) - _leftBtnPressed |= msClicked|msDown; - else if (event.type == Common::EVENT_RBUTTONDOWN) - _rightBtnPressed |= msClicked|msDown; - _mouse.x = event.mouse.x; - _mouse.y = event.mouse.y; - - if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { - _mouse.x -= (Common::kHercW - _screenWidth * 2) / 2; - _mouse.x >>= 1; - _mouse.y = _mouse.y * 4 / 7; - } else if (_useCJKMode && _textSurfaceMultiplier == 2) { - _mouse.x >>= 1; - _mouse.y >>= 1; - } - break; - case Common::EVENT_LBUTTONUP: - _leftBtnPressed &= ~msDown; - break; + default: + break; + } +} +#endif - case Common::EVENT_RBUTTONUP: - _rightBtnPressed &= ~msDown; - break; +void ScummEngine::parseEvent(Common::Event event) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9' + && (event.kbd.flags == Common::KBD_ALT || + event.kbd.flags == Common::KBD_CTRL)) { + _saveLoadSlot = event.kbd.keycode - '0'; + + // don't overwrite autosave (slot 0) + if (_saveLoadSlot == 0) + _saveLoadSlot = 10; + + sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot); + _saveLoadFlag = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2; + _saveTemporaryState = false; + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'f') { + _fastMode ^= 1; + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'g') { + _fastMode ^= 2; + } else if ((event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'd') || + event.kbd.ascii == '~' || event.kbd.ascii == '#') { + _debugger->attach(); + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 's') { + _res->resourceStats(); + } else { + // Normal key press, pass on to the game. + _keyPressed = event.kbd; + } - // The following two cases enable dialog choices to be scrolled - // through in the SegaCD version of MI. Values are taken from script-14. - // See bug report #1193185 for details. - case Common::EVENT_WHEELDOWN: - if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) - _keyPressed = Common::KeyState(Common::KEYCODE_7, 55); // '7' - break; + // FIXME: We are using ASCII values to index the _keyDownMap here, + // yet later one code which checks _keyDownMap will use KEYCODEs + // to do so. That is, we are mixing ascii and keycode values here, + // which is bad. We probably should be only using keycodes, but at + // least INSANE checks for "Shift-V" by looking for the 'V' key + // being pressed. It would be easy to solve that by also storing + // the modifier flags. However, since getKeyState() is also called + // by scripts, we have to be careful with semantic changes. + if (_keyPressed.ascii >= 512) + debugC(DEBUG_GENERAL, "_keyPressed > 512 (%d)", _keyPressed.ascii); + else + _keyDownMap[_keyPressed.ascii] = true; + break; + + case Common::EVENT_KEYUP: + if (event.kbd.ascii >= 512) { + debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii); + } else { + _keyDownMap[event.kbd.ascii] = false; + + // Due to some weird bug with capslock key pressed + // generated keydown event is for lower letter but + // keyup is for upper letter + // On most (all?) keyboards it is safe to assume that + // both upper and lower letters are unpressed on keyup event + // + // Fixes bug #1709430: "FT: CAPSLOCK + V enables cheating for all fights" + // + // Fingolfin remarks: This wouldn't be a problem if we used keycodes. + _keyDownMap[toupper(event.kbd.ascii)] = false; + } + break; + + + // We update the mouse position whenever the mouse moves or a click occurs. + // The latter is done to accomodate systems with a touchpad / pen controller. + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_MOUSEMOVE: + if (event.type == Common::EVENT_LBUTTONDOWN) + _leftBtnPressed |= msClicked|msDown; + else if (event.type == Common::EVENT_RBUTTONDOWN) + _rightBtnPressed |= msClicked|msDown; + _mouse.x = event.mouse.x; + _mouse.y = event.mouse.y; + + if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { + _mouse.x -= (Common::kHercW - _screenWidth * 2) / 2; + _mouse.x >>= 1; + _mouse.y = _mouse.y * 4 / 7; + } else if (_useCJKMode && _textSurfaceMultiplier == 2) { + _mouse.x >>= 1; + _mouse.y >>= 1; + } + break; + case Common::EVENT_LBUTTONUP: + _leftBtnPressed &= ~msDown; + break; + + case Common::EVENT_RBUTTONUP: + _rightBtnPressed &= ~msDown; + break; + + // The following two cases enable dialog choices to be scrolled + // through in the SegaCD version of MI. Values are taken from script-14. + // See bug report #1193185 for details. + case Common::EVENT_WHEELDOWN: + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) + _keyPressed = Common::KeyState(Common::KEYCODE_7, 55); // '7' + break; + + case Common::EVENT_WHEELUP: + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) + _keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6' + break; + + default: + break; + } +} - case Common::EVENT_WHEELUP: - if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) - _keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6' - break; +void ScummEngine::parseEvents() { + Common::Event event; - default: - break; - } + while (_eventMan->pollEvent(event)) { + parseEvent(event); } } diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index dcbf95ef4b..143c550180 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -442,7 +442,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) VAR_SCRIPT_CYCLE = 0xFF; VAR_NUM_GLOBAL_OBJS = 0xFF; - VAR_KEY_STATE = 0xFF; // Use g_scumm from error() ONLY g_scumm = this; @@ -784,6 +783,7 @@ ScummEngine_v80he::ScummEngine_v80he(OSystem *syst, const DetectorResult &dr) VAR_PLATFORM = 0xFF; VAR_PLATFORM_VERSION = 0xFF; VAR_CURRENT_CHARSET = 0xFF; + VAR_KEY_STATE = 0xFF; VAR_COLOR_DEPTH = 0xFF; } diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index e3be053810..3d16bea2b1 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -28,6 +28,7 @@ #include "engines/engine.h" #include "common/endian.h" +#include "common/events.h" #include "common/file.h" #include "common/savefile.h" #include "common/keyboard.h" @@ -498,6 +499,8 @@ protected: public: void parseEvents(); // Used by IMuseDigital::startSound protected: + virtual void parseEvent(Common::Event event); + void waitForTimer(int msec_delay); virtual void processInput(); virtual void processKeyboard(Common::KeyState lastKeyHit); @@ -1374,8 +1377,6 @@ public: byte VAR_SCRIPT_CYCLE; // Used in runScript()/runObjectScript() byte VAR_NUM_SCRIPT_CYCLES; // Used in runAllScripts() - byte VAR_KEY_STATE; // Used in parseEvents() - // Exists both in V7 and in V72HE: byte VAR_NUM_GLOBAL_OBJS; }; |