diff options
Diffstat (limited to 'engines/mads/events.cpp')
-rw-r--r-- | engines/mads/events.cpp | 272 |
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 |