aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/input.cpp')
-rw-r--r--engines/parallaction/input.cpp189
1 files changed, 163 insertions, 26 deletions
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index 19747c007e..98198b88f7 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
@@ -78,9 +130,9 @@ void Input::readInput() {
case Common::EVENT_MOUSEMOVE:
_mousePos = e.mouse;
break;
- case Common::EVENT_RTL:
+
case Common::EVENT_QUIT:
- _vm->_quit = true;
+ _engineFlags |= kEngineQuit;
return;
default:
@@ -127,9 +179,9 @@ void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) {
}
-void Input::updateGameInput() {
+int Input::updateGameInput() {
- readInput();
+ int event = kEvNone;
if (!isMouseEnabled() ||
(_engineFlags & kEngineWalking) ||
@@ -141,44 +193,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 +258,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 +298,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 +314,7 @@ bool Input::translateGameInput() {
}
_vm->beep();
- _vm->setArrowCursor();
+ setArrowCursor();
return true;
}
@@ -285,7 +330,7 @@ void Input::enterInventoryMode() {
_activeItem._index = (_activeItem._id >> 16) & 0xFFFF;
_engineFlags |= kEngineDragging;
} else {
- _vm->setArrowCursor();
+ setArrowCursor();
}
}
@@ -320,12 +365,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 +418,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