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 | |
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')
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 20 | ||||
-rw-r--r-- | engines/parallaction/dialogue.cpp | 16 | ||||
-rw-r--r-- | engines/parallaction/exec_br.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 3 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 5 | ||||
-rw-r--r-- | engines/parallaction/gui_br.cpp | 15 | ||||
-rw-r--r-- | engines/parallaction/gui_ns.cpp | 44 | ||||
-rw-r--r-- | engines/parallaction/input.cpp | 349 | ||||
-rw-r--r-- | engines/parallaction/input.h | 114 | ||||
-rw-r--r-- | engines/parallaction/inventory.cpp | 23 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 462 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 68 | ||||
-rw-r--r-- | engines/parallaction/parallaction_br.cpp | 3 | ||||
-rw-r--r-- | engines/parallaction/parallaction_ns.cpp | 11 |
14 files changed, 640 insertions, 499 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index d5defda8cf..402f69c99d 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -30,6 +30,7 @@ #include "graphics/primitives.h" // for Graphics::drawLine +#include "parallaction/input.h" #include "parallaction/parallaction.h" #include "parallaction/sound.h" @@ -303,14 +304,14 @@ void Parallaction_ns::_c_trasformata(void *parm) { } void Parallaction_ns::_c_offMouse(void *parm) { - showCursor(false); + _input->showCursor(false); _engineFlags |= kEngineBlockInput; return; } void Parallaction_ns::_c_onMouse(void *parm) { _engineFlags &= ~kEngineBlockInput; - showCursor(true); + _input->showCursor(true); return; } @@ -339,7 +340,7 @@ void Parallaction_ns::_c_endComment(void *param) { g_system->delayMillis(20); } - waitUntilLeftClick(); + _input->waitUntilLeftClick(); _gfx->freeBalloons(); return; @@ -395,7 +396,7 @@ void Parallaction_ns::_c_finito(void *parm) { _gfx->showLabel(id[1], CENTER_LABEL_HORIZONTAL, 100); _gfx->showLabel(id[2], CENTER_LABEL_HORIZONTAL, 130); _gfx->showLabel(id[3], CENTER_LABEL_HORIZONTAL, 160); - waitUntilLeftClick(); + _input->waitUntilLeftClick(); _gfx->freeLabels(); @@ -467,6 +468,7 @@ void Parallaction_ns::_c_endIntro(void *parm) { debugC(1, kDebugExec, "endIntro()"); + uint32 event; uint id[2]; for (uint16 _si = 0; _si < 6; _si++) { id[0] = _gfx->createLabel(_menuFont, _credits[_si]._role, 1); @@ -478,9 +480,9 @@ void Parallaction_ns::_c_endIntro(void *parm) { _gfx->updateScreen(); for (uint16 v2 = 0; v2 < 100; v2++) { - _mouseButtons = kMouseNone; - readInput(); - if (_mouseButtons == kMouseLeftUp) + _input->readInput(); + event = _input->getLastButtonEvent(); + if (event == kMouseLeftUp) break; waitTime( 1 ); @@ -497,7 +499,7 @@ void Parallaction_ns::_c_endIntro(void *parm) { id[0] = _gfx->createLabel(_menuFont, "CLICK MOUSE BUTTON TO START", 1); _gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 80); - waitUntilLeftClick(); + _input->waitUntilLeftClick(); _gfx->freeLabels(); @@ -507,7 +509,7 @@ void Parallaction_ns::_c_endIntro(void *parm) { cleanupGame(); } else { - waitUntilLeftClick(); + _input->waitUntilLeftClick(); } return; diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 2e3ecb590f..70db637699 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -24,6 +24,8 @@ */ #include "common/events.h" + +#include "parallaction/input.h" #include "parallaction/parallaction.h" @@ -195,7 +197,7 @@ void DialogueManager::displayQuestion() { _vm->_gfx->setItemFrame(id, _q->_mood & 0xF); _vm->_gfx->updateScreen(); - waitUntilLeftClick(); + _vm->_input->waitUntilLeftClick(); _vm->_gfx->hideDialogueStuff(); return; @@ -254,7 +256,7 @@ int16 DialogueManager::selectAnswer() { if (numAvailableAnswers == 1) { _vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 0); - waitUntilLeftClick(); + _vm->_input->waitUntilLeftClick(); _vm->_gfx->hideDialogueStuff(); return 0; } @@ -262,10 +264,14 @@ int16 DialogueManager::selectAnswer() { int oldSelection = -1; int selection; + uint32 event; + Common::Point p; while (true) { - _vm->readInput(); - selection = _vm->_gfx->hitTestDialogueBalloon(_vm->_mousePos.x, _vm->_mousePos.y); + _vm->_input->readInput(); + _vm->_input->getCursorPos(p); + event = _vm->_input->getLastButtonEvent(); + selection = _vm->_gfx->hitTestDialogueBalloon(p.x, p.y); if (selection != oldSelection) { if (oldSelection != -1) { @@ -278,7 +284,7 @@ int16 DialogueManager::selectAnswer() { } } - if ((selection != -1) && (_mouseButtons == kMouseLeftUp)) { + if ((selection != -1) && (event == kMouseLeftUp)) { break; } diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 9484c99585..07ed3f5d78 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -23,7 +23,7 @@ * */ - +#include "parallaction/input.h" #include "parallaction/parallaction.h" namespace Parallaction { @@ -184,12 +184,12 @@ DECLARE_COMMAND_OPCODE(followme) { DECLARE_COMMAND_OPCODE(onmouse) { - showCursor(true); + _input->showCursor(true); } DECLARE_COMMAND_OPCODE(offmouse) { - showCursor(false); + _input->showCursor(false); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 9ed56827b5..68ae91c73e 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -23,6 +23,7 @@ * */ +#include "parallaction/input.h" #include "parallaction/parallaction.h" #include "parallaction/sound.h" @@ -480,7 +481,7 @@ void Parallaction::displayComment(ExamineData *data) { _gfx->setItemFrame(id, 0); } - _inputMode = kInputModeComment; + _input->_inputMode = Input::kInputModeComment; } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index f92a58cdb0..9110731a04 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -27,6 +27,7 @@ #include "common/file.h" #include "graphics/primitives.h" +#include "parallaction/input.h" #include "parallaction/parallaction.h" @@ -781,9 +782,9 @@ void Gfx::updateFloatingLabel() { int16 _si, _di; Common::Point cursor; - _vm->getCursorPos(cursor); + _vm->_input->getCursorPos(cursor); - if (_vm->_activeItem._id != 0) { + if (_vm->_input->_activeItem._id != 0) { _si = cursor.x + 16 - _floatingLabel->_cnv.w/2; _di = cursor.y + 34; } else { diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp index 8ce559e644..c515299a34 100644 --- a/engines/parallaction/gui_br.cpp +++ b/engines/parallaction/gui_br.cpp @@ -25,6 +25,8 @@ #include "common/system.h" + +#include "parallaction/input.h" #include "parallaction/parallaction.h" namespace Parallaction { @@ -164,15 +166,20 @@ int Parallaction_br::guiShowMenu() { setMousePointer(0); + uint32 event; + Common::Point p; while (true) { - if ((_mouseButtons == kMouseLeftUp) && selectedItem >= 0) + _input->readInput(); + + event = _input->getLastButtonEvent(); + if ((event == kMouseLeftUp) && selectedItem >= 0) break; - readInput(); + _input->getCursorPos(p); - if ((_mousePos.x > MENUITEMS_X) && (_mousePos.x < (MENUITEMS_X+MENUITEM_WIDTH)) && (_mousePos.y > MENUITEMS_Y)) { - selectedItem = (_mousePos.y - MENUITEMS_Y) / MENUITEM_HEIGHT; + if ((p.x > MENUITEMS_X) && (p.x < (MENUITEMS_X+MENUITEM_WIDTH)) && (p.y > MENUITEMS_Y)) { + selectedItem = (p.y - MENUITEMS_Y) / MENUITEM_HEIGHT; if (!(selectedItem < availItems)) selectedItem = -1; diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp index fec5695413..91cc77e823 100644 --- a/engines/parallaction/gui_ns.cpp +++ b/engines/parallaction/gui_ns.cpp @@ -25,6 +25,7 @@ #include "common/system.h" +#include "parallaction/input.h" #include "parallaction/parallaction.h" #include "parallaction/sound.h" @@ -206,20 +207,22 @@ int Parallaction_ns::guiNewGame() { _gfx->showLabel(id[2], CENTER_LABEL_HORIZONTAL, 100); _gfx->showLabel(id[3], CENTER_LABEL_HORIZONTAL, 120); - showCursor(false); + _input->showCursor(false); _gfx->updateScreen(); - _mouseButtons = kMouseNone; + _input->waitForButtonEvent(kMouseLeftUp | kMouseRightUp); + uint32 event = _input->getLastButtonEvent(); +/* do { - readInput(); + _input->readInput(); } while (_mouseButtons != kMouseLeftUp && _mouseButtons != kMouseRightUp); - - showCursor(true); +*/ + _input->showCursor(true); _gfx->freeLabels(); - if (_mouseButtons != kMouseRightUp) { + if (event != kMouseRightUp) { return START_INTRO; } @@ -267,11 +270,14 @@ uint16 Parallaction_ns::guiChooseLanguage() { setArrowCursor(); + Common::Point p; + int selection = -1; while (selection == -1) { - waitUntilLeftClick(); + _input->waitUntilLeftClick(); + _input->getCursorPos(p); for (uint16 i = 0; i < 4; i++) { - if (blocks[i].contains(_mousePos)) { + if (blocks[i].contains(p)) { selection = i; break; } @@ -299,12 +305,18 @@ uint16 Parallaction_ns::guiSelectGame() { id0 = _gfx->createLabel(_introFont, loadGameMsg[_language], 1); id1 = _gfx->createLabel(_introFont, newGameMsg[_language], 1); - _mouseButtons = kMouseNone; - while (_mouseButtons != kMouseLeftUp) { + Common::Point p; + + _input->readInput(); + uint32 event = _input->getLastButtonEvent(); - readInput(); + while (event != kMouseLeftUp) { - _si = (_mousePos.x > 160) ? 1 : 0; + _input->readInput(); + _input->getCursorPos(p); + event = _input->getLastButtonEvent(); + + _si = (p.x > 160) ? 1 : 0; if (_si != _di) { if (_si != 0) { @@ -409,6 +421,8 @@ int Parallaction_ns::guiSelectCharacter() { Graphics::Surface block; block.create(BLOCK_WIDTH, BLOCK_HEIGHT, 1); + Common::Point p; + while (true) { points[0] = 0; @@ -422,8 +436,10 @@ int Parallaction_ns::guiSelectCharacter() { _di = 0; while (_di < PASSWORD_LEN) { - waitUntilLeftClick(); - int _si = guiGetSelectedBlock(_mousePos); + _input->waitUntilLeftClick(); + _input->getCursorPos(p); + + int _si = guiGetSelectedBlock(p); if (_si != -1) { _gfx->grabBackground(codeTrueBlocks[_si], block); 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 diff --git a/engines/parallaction/input.h b/engines/parallaction/input.h new file mode 100644 index 0000000000..411bb2d2cc --- /dev/null +++ b/engines/parallaction/input.h @@ -0,0 +1,114 @@ +/* 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$ + * + */ + +#ifndef PARALLACTION_INPUT_H +#define PARALLACTION_INPUT_H + +#include "parallaction/objects.h" +#include "parallaction/inventory.h" + +namespace Parallaction { + +enum { + kMouseNone = 0, + kMouseLeftUp = 1, + kMouseLeftDown = 2, + kMouseRightUp = 4, + kMouseRightDown = 8 +}; + +struct InputData { + uint16 _event; + Common::Point _mousePos; + int16 _inventoryIndex; + ZonePtr _zone; + Label* _label; +}; + +class Input { + void updateGameInput(); + void updateCommentInput(); + + // input-only + InputData _inputData; + bool _actionAfterWalk; // actived when the character needs to move before taking an action + // these two could/should be merged as they carry on the same duty in two member functions, + // respectively processInput and translateInput + int16 _transCurrentHoverItem; + + InputData *translateInput(); + bool translateGameInput(); + bool translateInventoryInput(); + + Parallaction *_vm; + + Common::Point _mousePos; + uint16 _mouseButtons; + + bool _mouseHidden; + +public: + enum { + kInputModeGame = 0, + kInputModeComment = 1 + }; + + + Input(Parallaction *vm) : _vm(vm) { + _transCurrentHoverItem = 0; + _actionAfterWalk = false; // actived when the character needs to move before taking an action + _mouseHidden = false; + _activeItem._index = 0; + _activeItem._id = 0; + _mouseButtons = 0; + } + + virtual ~Input() { } + + + void showCursor(bool visible); + void getCursorPos(Common::Point& p) { + p = _mousePos; + } + + int _inputMode; + ZonePtr _hoverZone; + InventoryItem _activeItem; + + uint16 readInput(); + InputData* updateInput(); + void waitUntilLeftClick(); + void waitForButtonEvent(uint32 buttonEventMask); + uint32 getLastButtonEvent() { return _mouseButtons; } + + void Input::stopHovering() { + _hoverZone = nullZonePtr; + } + +}; + +} // namespace Parallaction + +#endif diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp index 05202809a9..58848196d7 100644 --- a/engines/parallaction/inventory.cpp +++ b/engines/parallaction/inventory.cpp @@ -23,7 +23,7 @@ * */ - +#include "parallaction/input.h" #include "parallaction/parallaction.h" @@ -52,8 +52,18 @@ int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) { return _inventoryRenderer->hitTest(Common::Point(x,y)); } -void Parallaction::highlightInventoryItem(ItemPosition pos, byte color) { - _inventoryRenderer->highlightItem(pos, color); +void Parallaction::highlightInventoryItem(ItemPosition pos) { + static ItemPosition lastHighlightedPos = -1; + + if (lastHighlightedPos != -1) { + _inventoryRenderer->highlightItem(lastHighlightedPos, 12); + } + + if (pos != -1) { + _inventoryRenderer->highlightItem(pos, 19); + } + + lastHighlightedPos = pos; } int Parallaction::addInventoryItem(ItemName item) { @@ -125,8 +135,11 @@ void InventoryRenderer::showInventory() { uint16 lines = getNumLines(); - _pos.x = CLIP(_vm->_mousePos.x - (INVENTORY_WIDTH / 2), 0, (int)(_vm->_screenWidth - INVENTORY_WIDTH)); - _pos.y = CLIP(_vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, (int)(_vm->_screenHeight - lines * INVENTORYITEM_HEIGHT)); + Common::Point p; + _vm->_input->getCursorPos(p); + + _pos.x = CLIP(p.x - (INVENTORY_WIDTH / 2), 0, (int)(_vm->_screenWidth - INVENTORY_WIDTH)); + _pos.y = CLIP(p.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, (int)(_vm->_screenHeight - lines * INVENTORYITEM_HEIGHT)); refresh(); } diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 3907098b0f..eb766661c3 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -31,6 +31,8 @@ #include "sound/mididrv.h" #include "sound/mixer.h" + +#include "parallaction/input.h" #include "parallaction/parallaction.h" #include "parallaction/debug.h" #include "parallaction/sound.h" @@ -44,9 +46,6 @@ Parallaction *_vm = NULL; // public stuff -uint16 _mouseButtons = 0; - - char _saveData1[30] = { '\0' }; uint16 _language = 0; uint32 _engineFlags = 0; @@ -67,8 +66,6 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam // FIXME _vm = this; - _mouseHidden = false; - Common::File::addDefaultDirectory( _gameDataPath ); Common::addSpecialDebugLevel(kDebugDialogue, "dialogue", "Dialogues debug level"); @@ -111,11 +108,6 @@ int Parallaction::init() { _objectsNames = NULL; _globalTable = NULL; _location._hasSound = false; - _transCurrentHoverItem = 0; - _actionAfterWalk = false; // actived when the character needs to move before taking an action - _activeItem._index = 0; - _activeItem._id = 0; - _procCurrentHoverItem = -1; _baseTime = 0; _numLocations = 0; _location._startPosition.x = -1000; @@ -134,6 +126,8 @@ int Parallaction::init() { initInventory(); // needs to be pushed into subclass + _input = new Input(this); + _gfx = new Gfx(this); _debugger = new Debugger(this); @@ -147,111 +141,6 @@ int Parallaction::init() { -// 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 Parallaction::readInput() { - - Common::Event e; - uint16 KeyDown = 0; - - _mouseButtons = kMouseNone; - - Common::EventManager *eventMan = _system->getEventManager(); - while (eventMan->pollEvent(e)) { - - switch (e.type) { - case Common::EVENT_KEYDOWN: - if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd') - _debugger->attach(); - if (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 (_debugger->isAttached()) - _debugger->onFrame(); - - return KeyDown; - -} - -// FIXME: see comment for readInput() -void waitUntilLeftClick() { - - do { - _vm->readInput(); - _vm->_gfx->updateScreen(); - g_system->delayMillis(30); - } while (_mouseButtons != kMouseLeftUp); - - return; -} - -void Parallaction::runGame() { - - updateInput(); - - runPendingZones(); - - if (_engineFlags & kEngineChangeLocation) { - changeLocation(_location._name); - } - - - _gfx->beginFrame(); - - if (_inputMode == kInputModeGame) { - runScripts(); - walk(); - drawAnimations(); - } - - // change this to endFrame? - updateView(); - -} - void Parallaction::updateView() { if ((_engineFlags & kEnginePauseJobs) && (_engineFlags & kEngineInventory) == 0) { @@ -264,271 +153,6 @@ void Parallaction::updateView() { } -void Parallaction::processInput(InputData *data) { - - switch (data->_event) { - case kEvEnterZone: - debugC(2, kDebugInput, "processInput: kEvEnterZone"); - _gfx->setFloatingLabel(data->_label); - break; - - case kEvExitZone: - debugC(2, kDebugInput, "processInput: kEvExitZone"); - _gfx->setFloatingLabel(0); - break; - - case kEvAction: - debugC(2, kDebugInput, "processInput: kEvAction"); - _procCurrentHoverItem = -1; - _hoverZone = nullZonePtr; - pauseJobs(); - runZone(data->_zone); - resumeJobs(); - break; - - case kEvOpenInventory: - _procCurrentHoverItem = -1; - _hoverZone = nullZonePtr; - _gfx->setFloatingLabel(0); - if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) == 0) { - setArrowCursor(); - } - pauseJobs(); - openInventory(); - break; - - case kEvCloseInventory: // closes inventory and possibly select item - closeInventory(); - setInventoryCursor(data->_inventoryIndex); - resumeJobs(); - break; - - case kEvHoverInventory: - highlightInventoryItem(_procCurrentHoverItem, 12); // disable - highlightInventoryItem(data->_inventoryIndex, 19); // enable - _procCurrentHoverItem = data->_inventoryIndex; - break; - - case kEvWalk: - debugC(2, kDebugInput, "processInput: kEvWalk"); - _hoverZone = nullZonePtr; - setArrowCursor(); - _char.scheduleWalk(data->_mousePos.x, data->_mousePos.y); - break; - - case kEvQuitGame: - _engineFlags |= kEngineQuit; - break; - - case kEvSaveGame: - _hoverZone = nullZonePtr; - saveGame(); - setArrowCursor(); - break; - - case kEvLoadGame: - _hoverZone = nullZonePtr; - loadGame(); - setArrowCursor(); - break; - - } - - return; -} - - - - - -void Parallaction::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) { - _input._event = kEvQuitGame; - } else - if (keyDown == kEvSaveGame) { - _input._event = kEvSaveGame; - } else - if (keyDown == kEvLoadGame) { - _input._event = kEvLoadGame; - } else { - _input._mousePos = _mousePos; - _input._event = kEvNone; - if (!translateGameInput()) { - translateInventoryInput(); - } - } - - if (_input._event != kEvNone) - processInput(&_input); - -} - -void Parallaction::updateCommentInput() { - waitUntilLeftClick(); - - _gfx->hideDialogueStuff(); - _gfx->setHalfbriteMode(false); - - _inputMode = kInputModeGame; -} - -void Parallaction::updateInput() { - - switch (_inputMode) { - case kInputModeComment: - updateCommentInput(); - break; - - case kInputModeGame: - updateGameInput(); - break; - } - - return; -} - -bool Parallaction::translateGameInput() { - - if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) { - return false; - } - - if (_actionAfterWalk) { - // if walking is over, then take programmed action - _input._event = kEvAction; - _actionAfterWalk = false; - return true; - } - - if (_mouseButtons == kMouseRightDown) { - // right button down shows inventory - - if (hitZone(kZoneYou, _mousePos.x, _mousePos.y) && (_activeItem._id != 0)) { - _activeItem._index = (_activeItem._id >> 16) & 0xFFFF; - _engineFlags |= kEngineDragging; - } - - _input._event = kEvOpenInventory; - _transCurrentHoverItem = -1; - return true; - } - - // test if mouse is hovering on an interactive zone for the currently selected inventory item - ZonePtr z = hitZone(_activeItem._id, _mousePos.x, _mousePos.y); - - if (((_mouseButtons == kMouseLeftUp) && (_activeItem._id == 0) && ((_engineFlags & kEngineWalking) == 0)) && ((!z) || ((z->_type & 0xFFFF) != kZoneCommand))) { - _input._event = kEvWalk; - return true; - } - - if ((z != _hoverZone) && (_hoverZone)) { - _hoverZone = nullZonePtr; - _input._event = kEvExitZone; - return true; - } - - if (!z) { - _input._event = kEvNone; - return true; - } - - if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) { - _hoverZone = z; - _input._event = kEvEnterZone; - _input._label = z->_label; - return true; - } - - if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) { - - _input._zone = z; - if (z->_flags & kFlagsNoWalk) { - // character doesn't need to walk to take specified action - _input._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 - _input._event = kEvWalk; - _actionAfterWalk = true; - if (z->_moveTo.y != 0) { - _input._mousePos = z->_moveTo; - } - } - - beep(); - setArrowCursor(); - return true; - } - - return true; - -} - -bool Parallaction::translateInventoryInput() { - - if ((_engineFlags & kEngineInventory) == 0) { - return false; - } - - // in inventory - int16 _si = getHoverInventoryItem(_mousePos.x, _mousePos.y); - - if (_mouseButtons == kMouseRightUp) { - // right up hides inventory - - _input._event = kEvCloseInventory; - _input._inventoryIndex = getHoverInventoryItem(_mousePos.x, _mousePos.y); - highlightInventoryItem(_transCurrentHoverItem, 12); // disable - - if ((_engineFlags & kEngineDragging) == 0) { - return true; - } - - _engineFlags &= ~kEngineDragging; - ZonePtr z = hitZone(kZoneMerge, _activeItem._index, getInventoryItemIndex(_input._inventoryIndex)); - - if (z) { - dropItem(z->u.merge->_obj1); - dropItem(z->u.merge->_obj2); - addInventoryItem(z->u.merge->_obj3); - runCommands(z->_commands); - } - - return true; - } - - if (_si == _transCurrentHoverItem) { - _input._event = kEvNone; - return true; - } - - _transCurrentHoverItem = _si; - _input._event = kEvHoverInventory; - _input._inventoryIndex = _si; - return true; - -} - - uint32 Parallaction::getElapsedTime() { return g_system->getMillis() - _baseTime; } @@ -553,13 +177,6 @@ void Parallaction::waitTime(uint32 t) { } -void Parallaction::showCursor(bool visible) { - _mouseHidden = !visible; - g_system->showMouse(visible); -} - - - void Parallaction::freeCharacter() { debugC(1, kDebugExec, "freeCharacter()"); @@ -684,6 +301,75 @@ void Parallaction::showLocationComment(const char *text, bool end) { } +void Parallaction::processInput(InputData *data) { + + switch (data->_event) { + case kEvEnterZone: + debugC(2, kDebugInput, "processInput: kEvEnterZone"); + _gfx->setFloatingLabel(data->_label); + break; + + case kEvExitZone: + debugC(2, kDebugInput, "processInput: kEvExitZone"); + _gfx->setFloatingLabel(0); + break; + + case kEvAction: + debugC(2, kDebugInput, "processInput: kEvAction"); + _input->stopHovering(); + pauseJobs(); + runZone(data->_zone); + resumeJobs(); + break; + + case kEvOpenInventory: + _input->stopHovering(); + _gfx->setFloatingLabel(0); + if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) { + setArrowCursor(); + } + pauseJobs(); + openInventory(); + break; + + case kEvCloseInventory: // closes inventory and possibly select item + closeInventory(); + setInventoryCursor(data->_inventoryIndex); + resumeJobs(); + break; + + case kEvHoverInventory: + highlightInventoryItem(data->_inventoryIndex); // enable + break; + + case kEvWalk: + debugC(2, kDebugInput, "processInput: kEvWalk"); + _input->stopHovering(); + setArrowCursor(); + _char.scheduleWalk(data->_mousePos.x, data->_mousePos.y); + break; + + case kEvQuitGame: + _engineFlags |= kEngineQuit; + break; + + case kEvSaveGame: + _input->stopHovering(); + saveGame(); + setArrowCursor(); + break; + + case kEvLoadGame: + _input->stopHovering(); + loadGame(); + setArrowCursor(); + break; + + } + + return; +} + @@ -716,7 +402,7 @@ void Parallaction::doLocationEnterTransition() { _gfx->updateScreen(); showLocationComment(_location._comment, false); - waitUntilLeftClick(); + _input->waitUntilLeftClick(); _gfx->freeBalloons(); // fades maximum intensity palette towards approximation of main palette diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 367ee93f80..4a14201164 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -33,6 +33,7 @@ #include "engines/engine.h" +#include "parallaction/input.h" #include "parallaction/inventory.h" #include "parallaction/parser.h" #include "parallaction/objects.h" @@ -96,14 +97,6 @@ enum { kPriority21 = 21 }; -enum { - kMouseNone = 0, - kMouseLeftUp = 1, - kMouseLeftDown = 2, - kMouseRightUp = 3, - kMouseRightDown = 4 -}; - enum EngineFlags { kEngineQuit = (1 << 0), kEnginePauseJobs = (1 << 1), @@ -163,7 +156,6 @@ extern const char *_minidoughName; extern const char *_minidrkiName; -void waitUntilLeftClick(); @@ -171,7 +163,7 @@ void waitUntilLeftClick(); class Debugger; class Gfx; class SoundMan; - +class Input; struct Location { @@ -246,7 +238,6 @@ public: - #define DECLARE_UNQUALIFIED_COMMAND_OPCODE(op) void cmdOp_##op() #define DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(op) void instOp_##op() @@ -266,21 +257,10 @@ public: virtual bool loadGame() = 0; virtual bool saveGame() = 0; - uint16 readInput(); - void updateInput(); + Input *_input; void waitTime(uint32 t); - enum { - kInputModeGame = 0, - kInputModeComment = 1 - }; - - int _inputMode; - - void updateGameInput(); - void updateCommentInput(); - OpcodeSet _commandOpcodes; struct ParallactionStruct1 { @@ -298,8 +278,7 @@ public: bool suspend; } _instRunCtxt; - - void showCursor(bool visible); + void processInput(InputData* data); void pauseJobs(); void resumeJobs(); @@ -363,13 +342,6 @@ public: uint16 _numLocations; Location _location; - InventoryItem _activeItem; - - Common::Point _mousePos; - void getCursorPos(Common::Point& p) { - p = _mousePos; - } - ZonePtr _activeZone; @@ -380,38 +352,16 @@ public: Common::RandomSource _rnd; -protected: // data - Debugger *_debugger; - struct InputData { - uint16 _event; - Common::Point _mousePos; - int16 _inventoryIndex; - ZonePtr _zone; - Label* _label; - }; - - bool _mouseHidden; - - // input-only - InputData _input; - bool _actionAfterWalk; // actived when the character needs to move before taking an action - - // these two could/should be merged as they carry on the same duty in two member functions, - // respectively processInput and translateInput - int16 _procCurrentHoverItem; - int16 _transCurrentHoverItem; +protected: // data uint32 _baseTime; char _characterName1[50]; // only used in changeCharacter Common::String _saveFileName; - ZonePtr _hoverZone; - - protected: // members bool detectGame(void); @@ -421,12 +371,6 @@ protected: // members uint32 getElapsedTime(); void resetTimer(); - InputData *translateInput(); - bool translateGameInput(); - bool translateInventoryInput(); - void processInput(InputData*); - - void scheduleLocationSwitch(const char *location); void doLocationEnterTransition(); virtual void changeLocation(char *location) = 0; @@ -468,7 +412,7 @@ public: const char **_callableNamesRes; const char **_instructionNamesRes; - void highlightInventoryItem(ItemPosition pos, byte color); + void highlightInventoryItem(ItemPosition pos); int16 getHoverInventoryItem(int16 x, int16 y); int addInventoryItem(ItemName item); int addInventoryItem(ItemName item, uint32 value); diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 779a7f72b1..f07d201ae9 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -27,6 +27,7 @@ #include "common/util.h" #include "parallaction/parallaction.h" +#include "parallaction/input.h" #include "parallaction/sound.h" namespace Parallaction { @@ -108,7 +109,7 @@ int Parallaction_br::go() { // initCharacter(); - _inputMode = kInputModeGame; + _input->_inputMode = Input::kInputModeGame; while ((_engineFlags & (kEngineReturn | kEngineQuit)) == 0) { runGame(); } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index 197f99d723..81141454b6 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -28,6 +28,7 @@ #include "common/config-manager.h" #include "parallaction/parallaction.h" +#include "parallaction/input.h" #include "parallaction/sound.h" @@ -191,7 +192,7 @@ void Parallaction_ns::setArrowCursor() { // this stuff is needed to avoid artifacts with labels and selected items when switching cursors _gfx->setFloatingLabel(0); - _activeItem._id = 0; + _input->_activeItem._id = 0; _system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0); _system->showMouse(true); @@ -207,7 +208,7 @@ void Parallaction_ns::setInventoryCursor(int pos) { if (item->_index == 0) return; - _activeItem._id = item->_id; + _input->_activeItem._id = item->_id; byte *v8 = _mouseComposedArrow->getData(0); @@ -243,7 +244,7 @@ int Parallaction_ns::go() { changeLocation(_location._name); - _inputMode = kInputModeGame; + _input->_inputMode = Input::kInputModeGame; while ((_engineFlags & kEngineQuit) == 0) { runGame(); } @@ -298,7 +299,7 @@ void Parallaction_ns::changeLocation(char *location) { _gfx->setFloatingLabel(0); _gfx->freeLabels(); - _hoverZone = nullZonePtr; + _input->_hoverZone = nullZonePtr; if (_engineFlags & kEngineBlockInput) { setArrowCursor(); } @@ -314,7 +315,7 @@ void Parallaction_ns::changeLocation(char *location) { showSlide(locname.slide()); uint id = _gfx->createLabel(_menuFont, _location._slideText[0], 1); _gfx->showLabel(id, CENTER_LABEL_HORIZONTAL, 14); - waitUntilLeftClick(); + _input->waitUntilLeftClick(); _gfx->freeLabels(); freeBackground(); } |