diff options
author | Nicola Mettifogo | 2008-05-14 14:34:01 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2008-05-14 14:34:01 +0000 |
commit | 40ff1537a9a428753b0d2fe2c3716372818d8207 (patch) | |
tree | 94902c2151f5c172025f380e705890eb52e83271 /engines/parallaction/input.cpp | |
parent | 05a45b17b8cd88387a58dc61dd91ff128ff7d24d (diff) | |
download | scummvm-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.cpp | 349 |
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 |