From e532af93180c53a80bd4a7e96ab42e7e67e13e97 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 8 Sep 2011 23:04:28 -0400 Subject: [PATCH] PEGASUS: Add and hookup the InputHandler class --- engines/pegasus/input.cpp | 132 ++++++++++++++++++ engines/pegasus/input.h | 46 ++++++ engines/pegasus/neighborhood/neighborhood.cpp | 2 +- engines/pegasus/neighborhood/neighborhood.h | 4 +- engines/pegasus/pegasus.cpp | 4 +- engines/pegasus/pegasus.h | 12 +- 6 files changed, 191 insertions(+), 9 deletions(-) diff --git a/engines/pegasus/input.cpp b/engines/pegasus/input.cpp index bb147fb71627..37f9945634da 100755 --- a/engines/pegasus/input.cpp +++ b/engines/pegasus/input.cpp @@ -26,7 +26,9 @@ #include "common/events.h" #include "common/system.h" +#include "pegasus/cursor.h" #include "pegasus/input.h" +#include "pegasus/pegasus.h" namespace Pegasus { @@ -135,4 +137,134 @@ int operator!=(const Input &arg1, const Input &arg2) { return !operator==(arg1, arg2); } +InputHandler *InputHandler::_inputHandler = 0; +InputDevice InputHandler::_inputDevice; +bool InputHandler::_invalHotspots = false; +tInputBits InputHandler::_lastFilter = kFilterNoInput; + +InputHandler *InputHandler::setInputHandler(InputHandler *currentHandler) { + InputHandler *result = 0; + + if (_inputHandler != currentHandler && (!_inputHandler || _inputHandler->releaseInputFocus())) { + result = _inputHandler; + _inputHandler = currentHandler; + if (_inputHandler) + _inputHandler->grabInputFocus(); + } + + return result; +} + +void InputHandler::pollForInput() { + if (_inputHandler) { + Input input; + Hotspot *cursorSpot; + + InputHandler::getInput(input, cursorSpot); + if (_inputHandler->isClickInput(input, cursorSpot)) + _inputHandler->clickInHotspot(input, cursorSpot); + else + _inputHandler->handleInput(input, cursorSpot); + } +} + +void InputHandler::getInput(Input &input, Hotspot *&cursorSpot) { + Cursor *cursor = ((PegasusEngine *)g_engine)->_cursor; + + if (_inputHandler) + _lastFilter = _inputHandler->getInputFilter(); + else + _lastFilter = kFilterAllInput; + + _inputDevice.getInput(input, _lastFilter); + + if (_inputHandler && _inputHandler->wantsCursor() && (_lastFilter & _inputHandler->getClickFilter()) != 0) { + if (cursor->isVisible()) { + g_allHotspots.deactivateAllHotspots(); + _inputHandler->activateHotspots(); + + Common::Point cursorLocation; + cursor->getCursorLocation(cursorLocation); + cursorSpot = g_allHotspots.findHotspot(cursorLocation); + + if (_inputHandler) + _inputHandler->updateCursor(cursorLocation, cursorSpot); + } else { + cursor->hideUntilMoved(); + } + } else { + cursor->hide(); + } +} + +void InputHandler::readInputDevice(Input &input) { + _inputDevice.getInput(input, kFilterAllInput); +} + +InputHandler::InputHandler(InputHandler *nextHandler) { + _nextHandler = nextHandler; + allowInput(true); +} + +InputHandler::~InputHandler() { + if (_inputHandler == this) + setInputHandler(_nextHandler); +} + +void InputHandler::handleInput(const Input &input, const Hotspot *cursorSpot) { + if (_nextHandler) + _nextHandler->handleInput(input, cursorSpot); +} + +void InputHandler::clickInHotspot(const Input &input, const Hotspot *cursorSpot) { + if (_nextHandler) + _nextHandler->clickInHotspot(input, cursorSpot); +} + +bool InputHandler::isClickInput(const Input &input, const Hotspot *cursorSpot) { + if (_nextHandler) + return _nextHandler->isClickInput(input, cursorSpot); + + return false; +} + +void InputHandler::activateHotspots() { + if (_nextHandler) + _nextHandler->activateHotspots(); +} + +tInputBits InputHandler::getInputFilter() { + if (_allowInput) { + if (_nextHandler) + return _nextHandler->getInputFilter(); + else + return kFilterAllInput; + } + + return kFilterNoInput; +} + +tInputBits InputHandler::getClickFilter() { + if (_allowInput && _nextHandler) + return _nextHandler->getClickFilter(); + + return kFilterNoInput; +} + +void InputHandler::updateCursor(const Common::Point cursorLocation, const Hotspot *cursorSpot) { + if (_nextHandler) + _nextHandler->updateCursor(cursorLocation, cursorSpot); +} + +bool InputHandler::wantsCursor() { + if (_allowInput) { + if (_nextHandler) + return _nextHandler->wantsCursor(); + else + return true; + } + + return false; +} + } // End of namespace Pegasus diff --git a/engines/pegasus/input.h b/engines/pegasus/input.h index 463e3d024bbe..432ff8098b57 100755 --- a/engines/pegasus/input.h +++ b/engines/pegasus/input.h @@ -368,6 +368,52 @@ friend class InputDevice; Common::Point _inputLocation; }; +class InputHandler { +public: + static InputHandler *setInputHandler(InputHandler*); + static InputHandler *getCurrentHandler() { return _inputHandler; } + static InputDevice *getCurrentInputDevice() { return &_inputDevice; } + static void pollForInput(); + static void getInput(Input&, Hotspot*&); + static void readInputDevice(Input&); + static void invalHotspots() { _invalHotspots = true; } + static tInputBits getCurrentFilter() { return _lastFilter; } + + InputHandler(InputHandler*); + virtual ~InputHandler(); + + virtual void setNextHandler(InputHandler *nextHandler) { _nextHandler = nextHandler; } + virtual InputHandler *getNextHandler() { return _nextHandler; } + + virtual void handleInput(const Input&, const Hotspot*); + virtual void clickInHotspot(const Input&, const Hotspot*); + + virtual void activateHotspots(); + virtual void updateCursor(const Common::Point, const Hotspot*); + virtual bool isClickInput(const Input&, const Hotspot*); + virtual bool wantsCursor(); + + virtual bool releaseInputFocus() { return true; } + virtual void grabInputFocus() {} + + // This returns bits set for what kinds of input to accept. + virtual tInputBits getInputFilter(); + + // This returns bits defining what input constitutes a "click." + virtual tInputBits getClickFilter(); + + virtual void allowInput(const bool allow) { _allowInput = allow; } + +protected: + static InputHandler *_inputHandler; + static InputDevice _inputDevice; // TODO: Remove global constructor + static bool _invalHotspots; + static tInputBits _lastFilter; + + InputHandler *_nextHandler; + bool _allowInput; +}; + } // End of namespace Pegasus #endif diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp index 461f4b01493b..75a8df9028ba 100644 --- a/engines/pegasus/neighborhood/neighborhood.cpp +++ b/engines/pegasus/neighborhood/neighborhood.cpp @@ -33,7 +33,7 @@ namespace Pegasus { -Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : IDObject(id), _vm(vm), _resName(resName) { +Neighborhood::Neighborhood(InputHandler *nextHandler, PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : InputHandler(nextHandler), IDObject(id), _vm(vm), _resName(resName) { GameState.setOpenDoorLocation(kNoRoomID, kNoDirection); _currentAlternate = 0; _interruptionFilter = kFilterAllInput; diff --git a/engines/pegasus/neighborhood/neighborhood.h b/engines/pegasus/neighborhood/neighborhood.h index baeed7d12420..d294ffe7f04f 100644 --- a/engines/pegasus/neighborhood/neighborhood.h +++ b/engines/pegasus/neighborhood/neighborhood.h @@ -84,9 +84,9 @@ bool operator!=(const tQueueRequest &arg1, const tQueueRequest &arg2); typedef Common::Queue NeighborhoodActionQueue; -class Neighborhood : public IDObject, public NotificationReceiver { +class Neighborhood : public IDObject, public NotificationReceiver, public InputHandler { public: - Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id); + Neighborhood(InputHandler *nextHandler, PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id); virtual ~Neighborhood(); virtual void init(); diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index f604a2488acd..39eb7d50c4b8 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -48,7 +48,7 @@ namespace Pegasus { -PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamedesc) : Engine(syst), _gameDescription(gamedesc) { +PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamedesc) : Engine(syst), InputHandler(0), _gameDescription(gamedesc) { } PegasusEngine::~PegasusEngine() { @@ -279,7 +279,7 @@ void PegasusEngine::changeLocation(tNeighborhoodID neighborhood) { GameState.setCurrentNeighborhood(neighborhood); // Just a test... - Neighborhood *neighborhoodPtr = new Neighborhood(this, getTimeZoneDesc(neighborhood), neighborhood); + Neighborhood *neighborhoodPtr = new Neighborhood(this, this, getTimeZoneDesc(neighborhood), neighborhood); neighborhoodPtr->init(); delete neighborhoodPtr; } diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index 35ee117ed44a..8ab891df9cf3 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -33,6 +33,7 @@ #include "engines/engine.h" #include "pegasus/graphics.h" +#include "pegasus/input.h" #include "pegasus/video.h" #include "pegasus/neighborhood/neighborhood.h" @@ -64,9 +65,8 @@ enum GameMode { kQuitMode }; -class PegasusEngine : public ::Engine { -protected: - Common::Error run(); +class PegasusEngine : public ::Engine, public InputHandler { +friend class InputHandler; public: PegasusEngine(OSystem *syst, const PegasusGameDescription *gamedesc); @@ -85,6 +85,11 @@ class PegasusEngine : public ::Engine { void addIdler(Idler *idler); void removeIdler(Idler *idler); +protected: + Common::Error run(); + + Cursor *_cursor; + private: // Intro void runIntro(); @@ -132,7 +137,6 @@ class PegasusEngine : public ::Engine { // Idlers Common::List _idlers; void giveIdleTime(); - Cursor *_cursor; // Items void createItems();