aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2009-07-13 07:55:11 +0000
committerTravis Howell2009-07-13 07:55:11 +0000
commit01624bbb28a96376701c8afcfcb7fb651ac2d8bd (patch)
tree9189e2fa8d10cee94e4bbf07d60d57924cd9cdf3 /engines
parent93c91945045b738fb098403228d91bce40b469f7 (diff)
downloadscummvm-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.h3
-rw-r--r--engines/scumm/input.cpp272
-rw-r--r--engines/scumm/scumm.cpp2
-rw-r--r--engines/scumm/scumm.h5
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;
};