aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/input.cpp
diff options
context:
space:
mode:
authorNicola Mettifogo2008-05-14 14:34:01 +0000
committerNicola Mettifogo2008-05-14 14:34:01 +0000
commit40ff1537a9a428753b0d2fe2c3716372818d8207 (patch)
tree94902c2151f5c172025f380e705890eb52e83271 /engines/parallaction/input.cpp
parent05a45b17b8cd88387a58dc61dd91ff128ff7d24d (diff)
downloadscummvm-rg350-40ff1537a9a428753b0d2fe2c3716372818d8207.tar.gz
scummvm-rg350-40ff1537a9a428753b0d2fe2c3716372818d8207.tar.bz2
scummvm-rg350-40ff1537a9a428753b0d2fe2c3716372818d8207.zip
- Moved input code to its own class.
- Slightly simplified inventory highlight code thanks to changes in input code. svn-id: r32115
Diffstat (limited to 'engines/parallaction/input.cpp')
-rw-r--r--engines/parallaction/input.cpp349
1 files changed, 349 insertions, 0 deletions
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
new file mode 100644
index 0000000000..dc26debba7
--- /dev/null
+++ b/engines/parallaction/input.cpp
@@ -0,0 +1,349 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/events.h"
+
+#include "parallaction/input.h"
+#include "parallaction/parallaction.h"
+#include "parallaction/debug.h"
+
+namespace Parallaction {
+
+// FIXME: the engine has 3 event loops. The following routine hosts the main one,
+// and it's called from 8 different places in the code. There exist 2 more specialised
+// loops which could possibly be merged into this one with some effort in changing
+// caller code, i.e. adding condition checks.
+//
+uint16 Input::readInput() {
+
+ Common::Event e;
+ uint16 KeyDown = 0;
+
+ _mouseButtons = kMouseNone;
+
+ Common::EventManager *eventMan = _vm->_system->getEventManager();
+ while (eventMan->pollEvent(e)) {
+
+ switch (e.type) {
+ case Common::EVENT_KEYDOWN:
+ if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd')
+ _vm->_debugger->attach();
+ if (_vm->getFeatures() & GF_DEMO) break;
+ if (e.kbd.keycode == Common::KEYCODE_l) KeyDown = kEvLoadGame;
+ if (e.kbd.keycode == Common::KEYCODE_s) KeyDown = kEvSaveGame;
+ break;
+
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseButtons = kMouseLeftDown;
+ _mousePos = e.mouse;
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ _mouseButtons = kMouseLeftUp;
+ _mousePos = e.mouse;
+ break;
+
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseButtons = kMouseRightDown;
+ _mousePos = e.mouse;
+ break;
+
+ case Common::EVENT_RBUTTONUP:
+ _mouseButtons = kMouseRightUp;
+ _mousePos = e.mouse;
+ break;
+
+ case Common::EVENT_MOUSEMOVE:
+ _mousePos = e.mouse;
+ break;
+
+ case Common::EVENT_QUIT:
+ // TODO: don't quit() here, just have caller routines to check
+ // on kEngineQuit and exit gracefully to allow the engine to shut down
+ _engineFlags |= kEngineQuit;
+ g_system->quit();
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ if (_vm->_debugger->isAttached())
+ _vm->_debugger->onFrame();
+
+ return KeyDown;
+
+}
+
+// FIXME: see comment for readInput()
+void Input::waitForButtonEvent(uint32 buttonEventMask) {
+
+ if (buttonEventMask == kMouseNone) {
+ _mouseButtons = kMouseNone; // don't wait on nothing
+ return;
+ }
+
+ do {
+ readInput();
+ g_system->delayMillis(30);
+ } while ((_mouseButtons & buttonEventMask) == 0);
+
+}
+
+// FIXME: see comment for readInput()
+void Input::waitUntilLeftClick() {
+
+ do {
+ readInput();
+ _vm->_gfx->updateScreen();
+ g_system->delayMillis(30);
+ } while (_mouseButtons != kMouseLeftUp);
+
+ return;
+}
+
+void Parallaction::runGame() {
+
+ InputData *data = _input->updateInput();
+ if (data->_event != kEvNone) {
+ processInput(data);
+ }
+
+ runPendingZones();
+
+ if (_engineFlags & kEngineChangeLocation) {
+ changeLocation(_location._name);
+ }
+
+
+ _gfx->beginFrame();
+
+ if (_input->_inputMode == Input::kInputModeGame) {
+ runScripts();
+ walk();
+ drawAnimations();
+ }
+
+ // change this to endFrame?
+ updateView();
+
+}
+
+void Input::updateGameInput() {
+
+ int16 keyDown = readInput();
+
+ debugC(3, kDebugInput, "translateInput: input flags (%i, %i, %i, %i)",
+ !_mouseHidden,
+ (_engineFlags & kEngineBlockInput) == 0,
+ (_engineFlags & kEngineWalking) == 0,
+ (_engineFlags & kEngineChangeLocation) == 0
+ );
+
+ if ((_mouseHidden) ||
+ (_engineFlags & kEngineBlockInput) ||
+ (_engineFlags & kEngineWalking) ||
+ (_engineFlags & kEngineChangeLocation)) {
+
+ return;
+ }
+
+ if (keyDown == kEvQuitGame) {
+ _inputData._event = kEvQuitGame;
+ } else
+ if (keyDown == kEvSaveGame) {
+ _inputData._event = kEvSaveGame;
+ } else
+ if (keyDown == kEvLoadGame) {
+ _inputData._event = kEvLoadGame;
+ } else {
+ _inputData._mousePos = _mousePos;
+ _inputData._event = kEvNone;
+ if (!translateGameInput()) {
+ translateInventoryInput();
+ }
+ }
+
+}
+
+void Input::updateCommentInput() {
+ waitUntilLeftClick();
+
+ _vm->_gfx->hideDialogueStuff();
+ _vm->_gfx->setHalfbriteMode(false);
+
+ _inputMode = kInputModeGame;
+}
+
+InputData* Input::updateInput() {
+
+ _inputData._event = kEvNone;
+
+ switch (_inputMode) {
+ case kInputModeComment:
+ updateCommentInput();
+ break;
+
+ case kInputModeGame:
+ updateGameInput();
+ break;
+ }
+
+ return &_inputData;
+}
+
+bool Input::translateGameInput() {
+
+ if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) {
+ return false;
+ }
+
+ if (_actionAfterWalk) {
+ // if walking is over, then take programmed action
+ _inputData._event = kEvAction;
+ _actionAfterWalk = false;
+ return true;
+ }
+
+ if (_mouseButtons == kMouseRightDown) {
+ // right button down shows inventory
+
+ if (_vm->hitZone(kZoneYou, _mousePos.x, _mousePos.y) && (_activeItem._id != 0)) {
+ _activeItem._index = (_activeItem._id >> 16) & 0xFFFF;
+ _engineFlags |= kEngineDragging;
+ }
+
+ _inputData._event = kEvOpenInventory;
+ _transCurrentHoverItem = -1;
+ return true;
+ }
+
+ // test if mouse is hovering on an interactive zone for the currently selected inventory item
+ ZonePtr z = _vm->hitZone(_activeItem._id, _mousePos.x, _mousePos.y);
+
+ if (((_mouseButtons == kMouseLeftUp) && (_activeItem._id == 0) && ((_engineFlags & kEngineWalking) == 0)) && ((!z) || ((z->_type & 0xFFFF) != kZoneCommand))) {
+ _inputData._event = kEvWalk;
+ return true;
+ }
+
+ if ((z != _hoverZone) && (_hoverZone)) {
+ _hoverZone = nullZonePtr;
+ _inputData._event = kEvExitZone;
+ return true;
+ }
+
+ if (!z) {
+ _inputData._event = kEvNone;
+ return true;
+ }
+
+ if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) {
+ _hoverZone = z;
+ _inputData._event = kEvEnterZone;
+ _inputData._label = z->_label;
+ return true;
+ }
+
+ if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) {
+
+ _inputData._zone = z;
+ if (z->_flags & kFlagsNoWalk) {
+ // character doesn't need to walk to take specified action
+ _inputData._event = kEvAction;
+
+ } else {
+ // action delayed: if Zone defined a moveto position the character is programmed to move there,
+ // else it will move to the mouse position
+ _inputData._event = kEvWalk;
+ _actionAfterWalk = true;
+ if (z->_moveTo.y != 0) {
+ _inputData._mousePos = z->_moveTo;
+ }
+ }
+
+ _vm->beep();
+ _vm->setArrowCursor();
+ return true;
+ }
+
+ return true;
+
+}
+
+bool Input::translateInventoryInput() {
+
+ if ((_engineFlags & kEngineInventory) == 0) {
+ return false;
+ }
+
+ // in inventory
+ int16 _si = _vm->getHoverInventoryItem(_mousePos.x, _mousePos.y);
+
+ if (_mouseButtons == kMouseRightUp) {
+ // right up hides inventory
+
+ _inputData._event = kEvCloseInventory;
+ _inputData._inventoryIndex = _vm->getHoverInventoryItem(_mousePos.x, _mousePos.y);
+ _vm->highlightInventoryItem(-1); // disable
+
+ if ((_engineFlags & kEngineDragging) == 0) {
+ return true;
+ }
+
+ _engineFlags &= ~kEngineDragging;
+ ZonePtr z = _vm->hitZone(kZoneMerge, _activeItem._index, _vm->getInventoryItemIndex(_inputData._inventoryIndex));
+
+ if (z) {
+ _vm->dropItem(z->u.merge->_obj1);
+ _vm->dropItem(z->u.merge->_obj2);
+ _vm->addInventoryItem(z->u.merge->_obj3);
+ _vm->runCommands(z->_commands);
+ }
+
+ return true;
+ }
+
+ if (_si == _transCurrentHoverItem) {
+ _inputData._event = kEvNone;
+ return true;
+ }
+
+ _transCurrentHoverItem = _si;
+ _inputData._event = kEvHoverInventory;
+ _inputData._inventoryIndex = _si;
+ return true;
+
+}
+
+void Input::showCursor(bool visible) {
+ _mouseHidden = !visible;
+ _vm->_system->showMouse(visible);
+}
+
+
+} // namespace Parallaction