/* 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 "startrek/console.h" #include "startrek/startrek.h" namespace StarTrek { void StarTrekEngine::pollEvents(bool queueEvents) { Common::Event event; TrekEvent trekEvent; while (_eventMan->pollEvent(event)) { trekEvent.mouse = event.mouse; trekEvent.kbd = event.kbd; switch (event.type) { case Common::EVENT_QUIT: _system->quit(); break; case Common::EVENT_MOUSEMOVE: if (queueEvents) { trekEvent.type = TREKEVENT_MOUSEMOVE; addEventToQueue(trekEvent); } // WORKAROUND: this improves the responsiveness of the mouse. _system->updateScreen(); _system->delayMillis(10); break; case Common::EVENT_LBUTTONDOWN: if (queueEvents) { trekEvent.type = TREKEVENT_LBUTTONDOWN; addEventToQueue(trekEvent); } break; case Common::EVENT_RBUTTONDOWN: if (queueEvents) { trekEvent.type = TREKEVENT_RBUTTONDOWN; addEventToQueue(trekEvent); } break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) _console->attach(); if (queueEvents) { trekEvent.type = TREKEVENT_KEYDOWN; addEventToQueue(trekEvent); } break; default: break; } } } void StarTrekEngine::waitForNextTick(bool queueEvents) { pollEvents(queueEvents); uint nextFrame = _frameStartMillis + 1000 / 18.206; uint millis = _system->getMillis(); if (millis < nextFrame) _system->delayMillis(nextFrame - millis); _clockTicks++; _frameStartMillis = nextFrame; if (queueEvents) { TrekEvent tickEvent; tickEvent.type = TREKEVENT_TICK; tickEvent.tick = _clockTicks; addEventToQueue(tickEvent); } } void StarTrekEngine::initializeEventsAndMouse() { _mouseMoveEventInQueue = false; _tickEventInQueue = false; _frameStartMillis = _system->getMillis(); // TODO: mouse } bool StarTrekEngine::getNextEvent(TrekEvent *e, bool poll) { while (poll && _eventQueue.empty()) { pollEvents(true); // Check for tick event uint nextFrame = _frameStartMillis + 1000 / 18.206; uint millis = _system->getMillis(); if (millis >= nextFrame) { _clockTicks++; _frameStartMillis = millis; TrekEvent tickEvent; tickEvent.type = TREKEVENT_TICK; tickEvent.tick = _clockTicks; addEventToQueue(tickEvent); } if (!_eventQueue.empty()) break; // Still no events; wait a 60th of a second before checking for events again int delay = 1000 / 60; millis = _system->getMillis(); if (millis + delay > nextFrame) delay = nextFrame - millis; if (delay > 0) _system->delayMillis(delay); } if (_eventQueue.empty()) return false; *e = _eventQueue.front(); return true; } void StarTrekEngine::removeNextEvent() { if (_eventQueue.empty()) return; const TrekEvent &e = _eventQueue.front(); if (e.type == TREKEVENT_MOUSEMOVE) _mouseMoveEventInQueue = false; if (e.type == TREKEVENT_TICK) _tickEventInQueue = false; _eventQueue.pop_front(); } bool StarTrekEngine::popNextEvent(TrekEvent *e, bool poll) { if (!getNextEvent(e, poll)) return false; removeNextEvent(); return true; } void StarTrekEngine::addEventToQueue(const TrekEvent &e) { if (e.type == TREKEVENT_MOUSEMOVE && _mouseMoveEventInQueue) { // Only allow one mouse move event at once for (Common::List::iterator i = _eventQueue.begin(); i != _eventQueue.end(); ++i) { if (i->type == TREKEVENT_MOUSEMOVE) { *i = e; return; } } error("Couldn't find mouse move event in eventQueue"); } if (e.type == TREKEVENT_TICK) { // Only allow one tick event at once if (_tickEventInQueue) return; _tickEventInQueue = true; } if (e.type == TREKEVENT_MOUSEMOVE) _mouseMoveEventInQueue = true; assert(_eventQueue.size() < 0x40); _eventQueue.push_back(e); } } // End of namespace StarTrek