/* 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 "titanic/events.h" #include "titanic/debugger.h" #include "titanic/game_manager.h" #include "titanic/main_game_window.h" #include "titanic/star_control/star_control.h" #include "titanic/titanic.h" #include "common/events.h" #include "common/scummsys.h" #include "common/system.h" #include "engines/util.h" #include "graphics/screen.h" namespace Titanic { Events::Events(TitanicEngine *vm): _vm(vm), _frameCounter(1), _totalFrames(0), _priorFrameTime(0), _specialButtons(0) { } #define MOVE_CHECK if (moved) eventTarget()->mouseMove(_mousePos) void Events::pollEvents() { checkForNextFrameCounter(); bool moved = false; Common::Event event; while (!_vm->shouldQuit() && g_system->getEventManager()->pollEvent(event)) { if (event.type != Common::EVENT_MOUSEMOVE) { MOVE_CHECK; } switch (event.type) { case Common::EVENT_MOUSEMOVE: _mousePos = event.mouse; moved = true; break; case Common::EVENT_LBUTTONDOWN: _specialButtons |= MK_LBUTTON; _mousePos = event.mouse; eventTarget()->leftButtonDown(_mousePos); return; case Common::EVENT_LBUTTONUP: _specialButtons &= ~MK_LBUTTON; _mousePos = event.mouse; eventTarget()->leftButtonUp(_mousePos); return; case Common::EVENT_MBUTTONDOWN: _specialButtons |= MK_MBUTTON; _mousePos = event.mouse; eventTarget()->middleButtonDown(_mousePos); return; case Common::EVENT_MBUTTONUP: _specialButtons &= ~MK_MBUTTON; _mousePos = event.mouse; eventTarget()->middleButtonUp(_mousePos); return; case Common::EVENT_RBUTTONDOWN: _specialButtons |= MK_LBUTTON | MK_SHIFT; _mousePos = event.mouse; eventTarget()->leftButtonDown(_mousePos); return; case Common::EVENT_RBUTTONUP: _specialButtons &= ~(MK_RBUTTON | MK_SHIFT); _mousePos = event.mouse; eventTarget()->leftButtonUp(_mousePos); return; case Common::EVENT_WHEELUP: case Common::EVENT_WHEELDOWN: _mousePos = event.mouse; eventTarget()->mouseWheel(_mousePos, event.type == Common::EVENT_WHEELUP); return; case Common::EVENT_KEYDOWN: handleKbdSpecial(event.kbd); eventTarget()->keyDown(event.kbd); return; case Common::EVENT_KEYUP: handleKbdSpecial(event.kbd); eventTarget()->keyUp(event.kbd); return; default: break; } } MOVE_CHECK; } #undef MOVE_CHECK void Events::pollEventsAndWait() { pollEvents(); g_system->delayMillis(10); CGameManager *gameManager = g_vm->_window->_gameManager; if (gameManager) { // Regularly update the sound mixer gameManager->_sound.updateMixer(); // WORKAROUND: If in the Star Control view, update the camera // frequently, to accomodate that the original had a higher // draw rate than the ScummVM implementation does CViewItem *view = gameManager->getView(); if (view->getFullViewName() == "Bridge.Node 4.N") { CStarControl *starControl = dynamic_cast( view->findChildInstanceOf(CStarControl::_type)); if (starControl && starControl->_visible) starControl->updateCamera(); } } } bool Events::checkForNextFrameCounter() { // Check for next game frame uint32 milli = g_system->getMillis(); if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { ++_frameCounter; ++_totalFrames; _priorFrameTime = milli; // Handle any idle updates eventTarget()->onIdle(); // Give time to the debugger _vm->_debugger->onFrame(); // Display the frame _vm->_screen->update(); return true; } return false; } uint32 Events::getTicksCount() const { return _frameCounter * GAME_FRAME_TIME; } uint32 Events::getTotalPlayTicks() const { return _totalFrames; } void Events::setTotalPlayTicks(uint frames) { _totalFrames = frames; } void Events::sleep(uint time) { uint32 delayEnd = g_system->getMillis() + time; while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) pollEventsAndWait(); } bool Events::waitForPress(uint expiry) { uint32 delayEnd = g_system->getMillis() + expiry; CPressTarget pressTarget; addTarget(&pressTarget); while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd && !pressTarget._pressed) { pollEventsAndWait(); } removeTarget(); return pressTarget._pressed; } void Events::setMousePos(const Common::Point &pt) { g_system->warpMouse(pt.x, pt.y); _mousePos = pt; eventTarget()->mouseMove(_mousePos); } void Events::handleKbdSpecial(Common::KeyState keyState) { if (keyState.flags & Common::KBD_CTRL) _specialButtons |= MK_CONTROL; else _specialButtons &= ~MK_CONTROL; if (keyState.flags & Common::KBD_SHIFT) _specialButtons |= MK_SHIFT; else _specialButtons &= ~MK_SHIFT; } } // End of namespace Titanic