aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/engine/timer.cpp
diff options
context:
space:
mode:
authorathrxx2019-01-26 01:31:34 +0100
committerathrxx2019-03-06 20:48:15 +0100
commit1dfdcc7252ac83643cae7a7447c025da2af63843 (patch)
treeb6736d006bf67d5264dd171c336f0915695d1f88 /engines/kyra/engine/timer.cpp
parent8b53d20b51771680c3d31aa02c0285b7a8be4e85 (diff)
downloadscummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.tar.gz
scummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.tar.bz2
scummvm-rg350-1dfdcc7252ac83643cae7a7447c025da2af63843.zip
KYRA: cleanup dir
Reorganize all files in sub directories. The file placement isn't as intuitive as it might be for other engines, which is probably the reason why this hasn't been done before.
Diffstat (limited to 'engines/kyra/engine/timer.cpp')
-rw-r--r--engines/kyra/engine/timer.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/engines/kyra/engine/timer.cpp b/engines/kyra/engine/timer.cpp
new file mode 100644
index 0000000000..9728838015
--- /dev/null
+++ b/engines/kyra/engine/timer.cpp
@@ -0,0 +1,304 @@
+/* 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 "kyra/engine/timer.h"
+
+#include "common/system.h"
+
+namespace Kyra {
+
+namespace {
+struct TimerResync : public Common::UnaryFunction<TimerEntry&, void> {
+ uint32 _tickLength, _curTime;
+ TimerResync(KyraEngine_v1 *vm, uint32 curTime) : _tickLength(vm->tickLength()), _curTime(curTime) {}
+
+ void operator()(TimerEntry &entry) const {
+ if (entry.lastUpdate < 0) {
+ if ((uint32)(ABS(entry.lastUpdate)) >= entry.countdown * _tickLength)
+ entry.nextRun = 0;
+ else
+ entry.nextRun = _curTime + entry.lastUpdate + entry.countdown * _tickLength;
+ } else {
+ uint32 nextRun = entry.lastUpdate + entry.countdown * _tickLength;
+ if (_curTime < nextRun)
+ nextRun = 0;
+ entry.nextRun = nextRun;
+ }
+ }
+};
+
+struct TimerEqual : public Common::UnaryFunction<const TimerEntry&, bool> {
+ uint8 _id;
+
+ TimerEqual(uint8 id) : _id(id) {}
+
+ bool operator()(const TimerEntry &entry) const {
+ return entry.id == _id;
+ }
+};
+} // end of anonymous namespace
+
+void TimerManager::pause(bool p) {
+ if (p) {
+ ++_isPaused;
+
+ if (_isPaused == 1) {
+ _isPaused = true;
+ _pauseStart = _system->getMillis();
+ }
+ } else if (!p && _isPaused > 0) {
+ --_isPaused;
+
+ if (_isPaused == 0) {
+ const uint32 pausedTime = _system->getMillis() - _pauseStart;
+ _nextRun += pausedTime;
+
+ for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ pos->lastUpdate += pausedTime;
+ pos->nextRun += pausedTime;
+ }
+ }
+ }
+}
+
+void TimerManager::reset() {
+ for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos)
+ delete pos->func;
+
+ _timers.clear();
+}
+
+void TimerManager::addTimer(uint8 id, TimerFunc *func, int countdown, bool enabled) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ warning("Adding already existing timer %d", id);
+ return;
+ }
+
+ TimerEntry newTimer;
+
+ newTimer.id = id;
+ newTimer.countdown = countdown;
+ newTimer.enabled = enabled ? 1 : 0;
+ newTimer.lastUpdate = newTimer.nextRun = 0;
+ newTimer.func = func;
+ newTimer.pauseStartTime = 0;
+
+ _timers.push_back(newTimer);
+}
+
+void TimerManager::update() {
+ if (_system->getMillis() < _nextRun || _isPaused)
+ return;
+
+ _nextRun += 99999;
+
+ for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ if (pos->enabled == 1 && pos->countdown >= 0) {
+ if (pos->nextRun <= _system->getMillis()) {
+ if (pos->func && pos->func->isValid()) {
+ (*pos->func)(pos->id);
+ }
+
+ uint32 curTime = _system->getMillis();
+ pos->lastUpdate = curTime;
+ pos->nextRun = curTime + pos->countdown * _vm->tickLength();
+ }
+
+ _nextRun = MIN(_nextRun, pos->nextRun);
+ }
+ }
+}
+
+void TimerManager::resync() {
+ const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis();
+
+ _nextRun = 0; // force rerun
+ Common::for_each(_timers.begin(), _timers.end(), TimerResync(_vm, curTime));
+}
+
+void TimerManager::resetNextRun() {
+ _nextRun = 0;
+}
+
+void TimerManager::setCountdown(uint8 id, int32 countdown) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ timer->countdown = countdown;
+
+ if (countdown >= 0) {
+ uint32 curTime = _system->getMillis();
+ timer->lastUpdate = curTime;
+ timer->nextRun = curTime + countdown * _vm->tickLength();
+ if (timer->enabled & 2)
+ timer->pauseStartTime = curTime;
+
+ _nextRun = MIN(_nextRun, timer->nextRun);
+ }
+ } else {
+ warning("TimerManager::setCountdown: No timer %d", id);
+ }
+}
+
+void TimerManager::setDelay(uint8 id, int32 countdown) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->countdown = countdown;
+ else
+ warning("TimerManager::setDelay: No timer %d", id);
+}
+
+int32 TimerManager::getDelay(uint8 id) const {
+ CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ return timer->countdown;
+
+ warning("TimerManager::getDelay: No timer %d", id);
+ return -1;
+}
+
+void TimerManager::setNextRun(uint8 id, uint32 nextRun) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ if (timer->enabled & 2)
+ timer->pauseStartTime = _system->getMillis();
+ timer->nextRun = nextRun;
+ return;
+ }
+
+ warning("TimerManager::setNextRun: No timer %d", id);
+}
+
+uint32 TimerManager::getNextRun(uint8 id) const {
+ CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ return timer->nextRun;
+
+ warning("TimerManager::getNextRun: No timer %d", id);
+ return 0xFFFFFFFF;
+}
+
+void TimerManager::pauseSingleTimer(uint8 id, bool p) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+
+ if (timer == _timers.end()) {
+ warning("TimerManager::pauseSingleTimer: No timer %d", id);
+ return;
+ }
+
+ if (p) {
+ timer->pauseStartTime = _system->getMillis();
+ timer->enabled |= 2;
+ } else if (timer->pauseStartTime) {
+ int32 elapsedTime = _system->getMillis() - timer->pauseStartTime;
+ timer->enabled &= (~2);
+ timer->lastUpdate += elapsedTime;
+ timer->nextRun += elapsedTime;
+ resetNextRun();
+ timer->pauseStartTime = 0;
+ }
+}
+
+bool TimerManager::isEnabled(uint8 id) const {
+ CIterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ return (timer->enabled & 1);
+
+ warning("TimerManager::isEnabled: No timer %d", id);
+ return false;
+}
+
+void TimerManager::enable(uint8 id) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->enabled |= 1;
+ else
+ warning("TimerManager::enable: No timer %d", id);
+}
+
+void TimerManager::disable(uint8 id) {
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end())
+ timer->enabled &= (~1);
+ else
+ warning("TimerManager::disable: No timer %d", id);
+}
+
+void TimerManager::loadDataFromFile(Common::SeekableReadStream &file, int version) {
+ const uint32 loadTime = _isPaused ? _pauseStart : _system->getMillis();
+
+ if (version <= 7) {
+ _nextRun = 0;
+ for (int i = 0; i < 32; ++i) {
+ uint8 enabled = file.readByte();
+ int32 countdown = file.readSint32BE();
+ uint32 nextRun = file.readUint32BE();
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(i));
+ if (timer != _timers.end()) {
+ timer->enabled = enabled;
+ timer->countdown = countdown;
+
+ if (nextRun) {
+ timer->nextRun = nextRun + loadTime;
+ timer->lastUpdate = timer->nextRun - countdown * _vm->tickLength();
+ } else {
+ timer->nextRun = loadTime;
+ timer->lastUpdate = loadTime - countdown * _vm->tickLength();
+ }
+ } else {
+ warning("Loading timer data for non existing timer %d", i);
+ }
+ }
+ } else {
+ int entries = file.readByte();
+ for (int i = 0; i < entries; ++i) {
+ uint8 id = file.readByte();
+
+ Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
+ if (timer != _timers.end()) {
+ timer->enabled = file.readByte();
+ timer->countdown = file.readSint32BE();
+ timer->lastUpdate = file.readSint32BE();
+ } else {
+ warning("Loading timer data for non existing timer %d", id);
+ file.seek(7, SEEK_CUR);
+ }
+ }
+
+ resync();
+ }
+}
+
+void TimerManager::saveDataToFile(Common::WriteStream &file) const {
+ const uint32 saveTime = _isPaused ? _pauseStart : _system->getMillis();
+
+ file.writeByte(count());
+ for (CIterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
+ file.writeByte(pos->id);
+ file.writeByte(pos->enabled);
+ file.writeSint32BE(pos->countdown);
+ file.writeSint32BE(pos->lastUpdate - saveTime);
+ }
+}
+
+} // End of namespace Kyra