diff options
Diffstat (limited to 'backends/timer/default')
| -rw-r--r-- | backends/timer/default/default-timer.cpp | 130 | ||||
| -rw-r--r-- | backends/timer/default/default-timer.h | 59 | 
2 files changed, 189 insertions, 0 deletions
| diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp new file mode 100644 index 0000000000..907c715a07 --- /dev/null +++ b/backends/timer/default/default-timer.cpp @@ -0,0 +1,130 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + */ + +#include "common/stdafx.h" +#include "common/scummsys.h" +#include "backends/timer/default/default-timer.h" +#include "common/util.h" +#include "common/system.h" + +namespace Common { +// FIXME: Hack: This global variable shouldn't be declared here; in fact it  +// probably shouldn't be declared at all but rather a different method to +// query the TimerManager object should be invented. +TimerManager *g_timer = NULL; +} + +DefaultTimerManager::DefaultTimerManager(OSystem *system) : +	_system(system), +	_timerHandler(0), +	_lastTime(0) { + +	Common::g_timer = this; + +	for (int i = 0; i < MAX_TIMERS; i++) { +		_timerSlots[i].procedure = NULL; +		_timerSlots[i].interval = 0; +		_timerSlots[i].counter = 0; +	} + +	_thisTime = _system->getMillis(); + +	// Set the timer last, after everything has been initialised +	_system->setTimerCallback(&timer_handler, 10); + +} + +DefaultTimerManager::~DefaultTimerManager() { +	// Remove the timer callback. +	// Note: backends *must* gurantee that after this method call returns, +	// the handler is not in use anymore; else race condtions could occur. +	_system->setTimerCallback(0, 0); + +	{ +		Common::StackLock lock(_mutex); +		for (int i = 0; i < MAX_TIMERS; i++) { +			_timerSlots[i].procedure = NULL; +			_timerSlots[i].interval = 0; +			_timerSlots[i].counter = 0; +		} +	} +} + +int DefaultTimerManager::timer_handler(int t) { +	if (Common::g_timer) +		return ((DefaultTimerManager *)Common::g_timer)->handler(t); +	return 0; +} + +int DefaultTimerManager::handler(int t) { +	Common::StackLock lock(_mutex); +	uint32 interval, l; + +	_lastTime = _thisTime; +	_thisTime = _system->getMillis(); +	interval = 1000 * (_thisTime - _lastTime); + +	for (l = 0; l < MAX_TIMERS; l++) { +		if (_timerSlots[l].procedure && _timerSlots[l].interval > 0) { +			_timerSlots[l].counter -= interval; +			while (_timerSlots[l].counter <= 0) { +				// A small paranoia check which catches the case where +				// a timer removes itself (which it never should do). +				assert(_timerSlots[l].procedure && _timerSlots[l].interval > 0); +				_timerSlots[l].counter += _timerSlots[l].interval; +				_timerSlots[l].procedure(_timerSlots[l].refCon); +			} +		} +	} + +	return t; +} + +bool DefaultTimerManager::installTimerProc(TimerProc procedure, int32 interval, void *refCon) { +	assert(interval > 0); +	Common::StackLock lock(_mutex); + +	for (int l = 0; l < MAX_TIMERS; l++) { +		if (!_timerSlots[l].procedure) { +			_timerSlots[l].procedure = procedure; +			_timerSlots[l].interval = interval; +			_timerSlots[l].counter = interval; +			_timerSlots[l].refCon = refCon; +			return true; +		} +	} + +	warning("Couldn't find free timer slot"); +	return false; +} + +void DefaultTimerManager::removeTimerProc(TimerProc procedure) { +	Common::StackLock lock(_mutex); + +	for (int l = 0; l < MAX_TIMERS; l++) { +		if (_timerSlots[l].procedure == procedure) { +			_timerSlots[l].procedure = 0; +			_timerSlots[l].interval = 0; +			_timerSlots[l].counter = 1;	// Work around a problem when a timer proc removes itself +			_timerSlots[l].refCon = 0; +		} +	} +} diff --git a/backends/timer/default/default-timer.h b/backends/timer/default/default-timer.h new file mode 100644 index 0000000000..12779cc59c --- /dev/null +++ b/backends/timer/default/default-timer.h @@ -0,0 +1,59 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + */ + +#ifndef BACKENDS_TIMER_DEFAULT_H +#define BACKENDS_TIMER_DEFAULT_H + +#include "common/timer.h" +#include "common/mutex.h" + +class OSystem; + +class DefaultTimerManager : public Common::TimerManager { +private: +	enum { +		MAX_TIMERS = 8 +	}; +	OSystem *_system; +	Common::Mutex _mutex; +	void *_timerHandler; +	int32 _thisTime; +	int32 _lastTime; + +	struct TimerSlots { +		TimerProc procedure; +		int32 interval; +		int32 counter; +		void *refCon; +	} _timerSlots[MAX_TIMERS]; + +public: +	DefaultTimerManager(OSystem *system); +	~DefaultTimerManager(); +	bool installTimerProc(TimerProc proc, int32 interval, void *refCon); +	void removeTimerProc(TimerProc proc); + +protected: +	static int timer_handler(int t); +	int handler(int t); +}; + +#endif | 
