diff options
Diffstat (limited to 'engines/parallaction/input.cpp')
-rw-r--r-- | engines/parallaction/input.cpp | 188 |
1 files changed, 163 insertions, 25 deletions
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp index 287618e803..c91421e15e 100644 --- a/engines/parallaction/input.cpp +++ b/engines/parallaction/input.cpp @@ -31,6 +31,58 @@ namespace Parallaction { +#define MOUSEARROW_WIDTH_NS 16 +#define MOUSEARROW_HEIGHT_NS 16 + +#define MOUSECOMBO_WIDTH_NS 32 // sizes for cursor + selected inventory item +#define MOUSECOMBO_HEIGHT_NS 32 + +struct MouseComboProperties { + int _xOffset; + int _yOffset; + int _width; + int _height; +}; +/* +// TODO: improve NS's handling of normal cursor before merging cursor code. +MouseComboProperties _mouseComboProps_NS = { + 7, // combo x offset (the icon from the inventory will be rendered from here) + 7, // combo y offset (ditto) + 32, // combo (arrow + icon) width + 32 // combo (arrow + icon) height +}; +*/ +MouseComboProperties _mouseComboProps_BR = { + 8, // combo x offset (the icon from the inventory will be rendered from here) + 8, // combo y offset (ditto) + 68, // combo (arrow + icon) width + 68 // combo (arrow + icon) height +}; + +Input::Input(Parallaction *vm) : _vm(vm) { + _gameType = _vm->getGameType(); + _transCurrentHoverItem = 0; + _hasDelayedAction = false; // actived when the character needs to move before taking an action + _mouseState = MOUSE_DISABLED; + _activeItem._index = 0; + _activeItem._id = 0; + _mouseButtons = 0; + _delayedActionZone = nullZonePtr; + + initCursors(); +} + +Input::~Input() { + if (_gameType == GType_Nippon) { + delete _mouseArrow; + } + + delete _comboArrow; + delete _dinoCursor; + delete _dougCursor; + delete _donnaCursor; +} + // 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 @@ -79,8 +131,9 @@ void Input::readInput() { _mousePos = e.mouse; break; + case Common::EVENT_RTL: case Common::EVENT_QUIT: - _engineFlags |= kEngineQuit; + _vm->_quit = true; return; default: @@ -127,9 +180,9 @@ void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) { } -void Input::updateGameInput() { +int Input::updateGameInput() { - readInput(); + int event = kEvNone; if (!isMouseEnabled() || (_engineFlags & kEngineWalking) || @@ -141,44 +194,38 @@ void Input::updateGameInput() { (_engineFlags & kEngineChangeLocation) == 0 ); - return; + return event; } if (_hasKeyPressEvent && (_vm->getFeatures() & GF_DEMO) == 0) { - if (_keyPressed.keycode == Common::KEYCODE_l) _inputData._event = kEvLoadGame; - if (_keyPressed.keycode == Common::KEYCODE_s) _inputData._event = kEvSaveGame; + if (_keyPressed.keycode == Common::KEYCODE_l) event = kEvLoadGame; + if (_keyPressed.keycode == Common::KEYCODE_s) event = kEvSaveGame; } - if (_inputData._event == kEvNone) { - _inputData._mousePos = _mousePos; + if (event == kEvNone) { translateGameInput(); } + return event; } -InputData* Input::updateInput() { +int Input::updateInput() { - _inputData._event = kEvNone; + int event = kEvNone; + readInput(); switch (_inputMode) { - case kInputModeComment: - case kInputModeDialogue: - case kInputModeMenu: - readInput(); - break; - case kInputModeGame: - updateGameInput(); + event = updateGameInput(); break; case kInputModeInventory: - readInput(); updateInventoryInput(); break; } - return &_inputData; + return event; } void Input::trackMouse(ZonePtr z) { @@ -212,7 +259,7 @@ void Input::takeAction(ZonePtr z) { void Input::walkTo(const Common::Point &dest) { stopHovering(); - _vm->setArrowCursor(); + setArrowCursor(); _vm->_char.scheduleWalk(dest.x, dest.y); } @@ -252,7 +299,6 @@ bool Input::translateGameInput() { 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 takeAction(z); @@ -269,7 +315,7 @@ bool Input::translateGameInput() { } _vm->beep(); - _vm->setArrowCursor(); + setArrowCursor(); return true; } @@ -285,7 +331,7 @@ void Input::enterInventoryMode() { _activeItem._index = (_activeItem._id >> 16) & 0xFFFF; _engineFlags |= kEngineDragging; } else { - _vm->setArrowCursor(); + setArrowCursor(); } } @@ -320,12 +366,12 @@ void Input::exitInventoryMode() { _vm->closeInventory(); if (pos == -1) { - _vm->setArrowCursor(); + setArrowCursor(); } else { const InventoryItem *item = _vm->getInventoryItem(pos); if (item->_index != 0) { _activeItem._id = item->_id; - _vm->setInventoryCursor(item->_index); + setInventoryCursor(item->_index); } } _vm->resumeJobs(); @@ -373,4 +419,96 @@ bool Input::isMouseEnabled() { return (_mouseState == MOUSE_ENABLED_SHOW) || (_mouseState == MOUSE_ENABLED_HIDE); } + +void Input::initCursors() { + + _dinoCursor = _donnaCursor = _dougCursor = 0; + + switch (_gameType) { + case GType_Nippon: + _comboArrow = _vm->_disk->loadPointer("pointer"); + _mouseArrow = new Cnv(1, MOUSEARROW_WIDTH_NS, MOUSEARROW_HEIGHT_NS, _resMouseArrow_NS, false); + break; + + case GType_BRA: + if (_vm->getPlatform() == Common::kPlatformPC) { + _dinoCursor = _vm->_disk->loadPointer("pointer1"); + _dougCursor = _vm->_disk->loadPointer("pointer2"); + _donnaCursor = _vm->_disk->loadPointer("pointer3"); + + Graphics::Surface *surf = new Graphics::Surface; + surf->create(_mouseComboProps_BR._width, _mouseComboProps_BR._height, 1); + _comboArrow = new SurfaceToFrames(surf); + + // TODO: choose the pointer depending on the active character + // For now, we pick Donna's + _mouseArrow = _donnaCursor; + } else { + // TODO: Where are the Amiga cursors? + _mouseArrow = 0; + } + break; + + default: + warning("Input::initCursors: unknown gametype"); + } + +} + +void Input::setArrowCursor() { + + switch (_gameType) { + case GType_Nippon: + debugC(1, kDebugInput, "setting mouse cursor to arrow"); + // this stuff is needed to avoid artifacts with labels and selected items when switching cursors + stopHovering(); + _activeItem._id = 0; + _vm->_system->setMouseCursor(_mouseArrow->getData(0), MOUSEARROW_WIDTH_NS, MOUSEARROW_HEIGHT_NS, 0, 0, 0); + break; + + case GType_BRA: { + if (_vm->getPlatform() == Common::kPlatformAmiga) + return; + + Common::Rect r; + _mouseArrow->getRect(0, r); + _vm->_system->setMouseCursor(_mouseArrow->getData(0), r.width(), r.height(), 0, 0, 0); + _vm->_system->showMouse(true); + _activeItem._id = 0; + break; + } + + default: + warning("Input::setArrowCursor: unknown gametype"); + } + +} + +void Input::setInventoryCursor(ItemName name) { + assert(name > 0); + + switch (_gameType) { + case GType_Nippon: { + byte *v8 = _comboArrow->getData(0); + // FIXME: destination offseting is not clear + _vm->_inventoryRenderer->drawItem(name, v8 + 7 * MOUSECOMBO_WIDTH_NS + 7, MOUSECOMBO_WIDTH_NS); + _vm->_system->setMouseCursor(v8, MOUSECOMBO_WIDTH_NS, MOUSECOMBO_HEIGHT_NS, 0, 0, 0); + break; + } + + case GType_BRA: { + byte *src = _mouseArrow->getData(0); + byte *dst = _comboArrow->getData(0); + memcpy(dst, src, _comboArrow->getSize(0)); + // FIXME: destination offseting is not clear + _vm->_inventoryRenderer->drawItem(name, dst + _mouseComboProps_BR._yOffset * _mouseComboProps_BR._width + _mouseComboProps_BR._xOffset, _mouseComboProps_BR._width); + _vm->_system->setMouseCursor(dst, _mouseComboProps_BR._width, _mouseComboProps_BR._height, 0, 0, 0); + } + + default: + warning("Input::setInventoryCursor: unknown gametype"); + } + +} + } // namespace Parallaction |