aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/events.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/events.cpp')
-rw-r--r--engines/mads/events.cpp272
1 files changed, 272 insertions, 0 deletions
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
new file mode 100644
index 0000000000..7ba9098935
--- /dev/null
+++ b/engines/mads/events.cpp
@@ -0,0 +1,272 @@
+/* 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.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "graphics/cursorman.h"
+#include "common/events.h"
+#include "engines/util.h"
+#include "mads/mads.h"
+#include "mads/events.h"
+#include "mads/scene.h"
+
+namespace MADS {
+
+EventsManager::EventsManager(MADSEngine *vm) {
+ _vm = vm;
+ _cursorSprites = nullptr;
+ _cursorId = CURSOR_NONE;
+ _newCursorId = CURSOR_NONE;
+ _frameCounter = 10;
+ _priorFrameTime = 0;
+ _mouseClicked = false;
+ _mouseReleased = false;
+ _mouseButtons = 0;
+ _mouseStatus = 0;
+ _strokeGoing = 0;
+ _mouseStatusCopy = 0;
+ _mouseMoved = false;
+ _rightMousePressed = false;
+ _eventTarget = nullptr;
+}
+
+EventsManager::~EventsManager() {
+ freeCursors();
+}
+
+void EventsManager::loadCursors(const Common::String &spritesName) {
+ delete _cursorSprites;
+ _cursorSprites = new SpriteAsset(_vm, spritesName, 0x4000);
+}
+
+void EventsManager::setCursor(CursorType cursorId) {
+ _cursorId = cursorId;
+ changeCursor();
+}
+
+void EventsManager::setCursor2(CursorType cursorId) {
+ _cursorId = cursorId;
+ _newCursorId = cursorId;
+ changeCursor();
+}
+
+void EventsManager::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void EventsManager::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
+bool EventsManager::isCursorVisible() {
+ return CursorMan.isVisible();
+}
+
+void EventsManager::waitCursor() {
+ CursorType cursorId = (CursorType)MIN(_cursorSprites->getCount(), (int)CURSOR_WAIT);
+ _newCursorId = cursorId;
+ if (_cursorId != _newCursorId) {
+ _cursorId = _newCursorId;
+ changeCursor();
+ }
+}
+
+void EventsManager::changeCursor() {
+ if (_cursorSprites) {
+ MSprite *cursor = _cursorSprites->getFrame(_cursorId - 1);
+ assert(cursor->w == cursor->h);
+ byte transIndex = cursor->getTransparencyIndex();
+
+ // Check for hotspot indication pixels along the right-hand and bottom
+ // row. Put together, these give the cursor's hotspot x,y
+ int hotspotX = 0, hotspotY = 0;
+ byte *cursorData = cursor->getData();
+ for (int idx = 0; idx < cursor->w; ++idx) {
+ if (cursorData[(cursor->h - 1) * cursor->w + idx] != transIndex)
+ hotspotX = idx;
+
+ if (cursorData[(idx + 1) * cursor->w - 1] != transIndex)
+ hotspotY = idx;
+ }
+
+ // Reduce the cursor data to remove the last column from each row, since
+ // the cursor routines don't have a pitch option
+ byte *destCursor = new byte[(cursor->w - 1) * (cursor->h - 1)];
+ byte *srcP = cursorData;
+ byte *destP = destCursor;
+
+ for (int idx = 0; idx < (cursor->h - 1); ++idx) {
+ Common::copy(srcP, srcP + cursor->w - 1, destP);
+ srcP += cursor->w;
+ destP += cursor->w - 1;
+ }
+
+ // Set the raw cursor data to use
+ CursorMan.replaceCursor(destCursor, cursor->w - 1, cursor->h - 1,
+ hotspotX, hotspotY, transIndex);
+ showCursor();
+ delete[] destCursor;
+ }
+}
+
+void EventsManager::freeCursors() {
+ delete _cursorSprites;
+ _cursorSprites = nullptr;
+}
+
+void EventsManager::pollEvents() {
+ checkForNextFrameCounter();
+ _mouseMoved = false;
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ // If an event target is specified, pass the event to it
+ if (_eventTarget) {
+ _eventTarget->onEvent(event);
+ continue;
+ }
+
+ // Handle keypress
+ switch (event.type) {
+ case Common::EVENT_QUIT:
+ case Common::EVENT_RTL:
+ return;
+
+ case Common::EVENT_KEYDOWN:
+ // Check for debugger
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _vm->_debugger->attach();
+ _vm->_debugger->onFrame();
+ } else {
+ _pendingKeys.push(event.kbd);
+ }
+ return;
+ case Common::EVENT_KEYUP:
+ return;
+ case Common::EVENT_WHEELUP:
+ _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEUP));
+ return;
+ case Common::EVENT_WHEELDOWN:
+ _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEDOWN));
+ return;
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseClicked = true;
+ _mouseButtons = 1;
+ _mouseMoved = true;
+ if (event.type == Common::EVENT_RBUTTONDOWN) {
+ _rightMousePressed = true;
+ _mouseStatus |= 2;
+ } else {
+ _mouseStatus |= 1;
+ }
+ return;
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONUP:
+ _mouseClicked = false;
+ _mouseReleased = true;
+ _mouseMoved = true;
+ _rightMousePressed = false;
+ if (event.type == Common::EVENT_RBUTTONUP) {
+ _mouseStatus &= ~2;
+ } else {
+ _mouseStatus &= ~1;
+ }
+ return;
+ case Common::EVENT_MOUSEMOVE:
+ _mousePos = event.mouse;
+ _currentPos = event.mouse;
+ _mouseMoved = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool EventsManager::checkForNextFrameCounter() {
+ // Check for next game frame
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
+ ++_frameCounter;
+ _priorFrameTime = milli;
+
+ // Do any palette cycling
+ _vm->_game->_scene.animatePalette();
+
+ // Give time to the debugger
+ _vm->_debugger->onFrame();
+
+ // Display the frame
+ _vm->_screen.updateScreen();
+
+ // Signal the ScummVM debugger
+ _vm->_debugger->onFrame();
+
+ return true;
+ }
+
+ return false;
+}
+
+void EventsManager::delay(int cycles) {
+ uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE;
+ uint32 delayEnd = g_system->getMillis() + totalMilli;
+
+ while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) {
+ g_system->delayMillis(10);
+
+ pollEvents();
+ }
+}
+
+void EventsManager::waitForNextFrame() {
+ _mouseClicked = false;
+ _mouseReleased = false;
+ _mouseButtons = 0;
+
+ bool mouseClicked = false;
+ bool mouseReleased = false;
+ int mouseButtons = 0;
+
+ uint32 frameCtr = getFrameCounter();
+ while (!_vm->shouldQuit() && frameCtr == _frameCounter) {
+ delay(1);
+
+ mouseClicked |= _mouseClicked;
+ mouseReleased |= _mouseReleased;
+ mouseButtons |= _mouseButtons;
+ }
+
+ _mouseClicked = mouseClicked;
+ _mouseReleased = mouseReleased;
+ _mouseButtons = mouseButtons;
+ _mouseMoved |= _mouseClicked || _mouseReleased;
+}
+
+void EventsManager::initVars() {
+ _mousePos = Common::Point(-1, -1);
+ _mouseStatusCopy = _mouseStatus;
+ _strokeGoing = 0;
+}
+
+} // End of namespace MADS