aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Kołodziejski2002-08-04 16:30:59 +0000
committerPaweł Kołodziejski2002-08-04 16:30:59 +0000
commit9fa6145d9081e03c9bd89e20ad93d24ad625ab96 (patch)
tree9ebda135174a091c1174d973e19105230c70ec1b
parentac7e6a15c166127bf79d55738854bb6a9c5d46d5 (diff)
downloadscummvm-rg350-9fa6145d9081e03c9bd89e20ad93d24ad625ab96.tar.gz
scummvm-rg350-9fa6145d9081e03c9bd89e20ad93d24ad625ab96.tar.bz2
scummvm-rg350-9fa6145d9081e03c9bd89e20ad93d24ad625ab96.zip
DIG: preliminarily support for music in the game
svn-id: r4701
-rw-r--r--Makefile.common2
-rw-r--r--bundle.cpp69
-rw-r--r--bundle.h5
-rw-r--r--gui/ListWidget.cpp1
-rw-r--r--init.cpp2
-rw-r--r--morphos/Makefile2
-rw-r--r--scumm.h13
-rw-r--r--scummvm.cpp8
-rw-r--r--scummvm.dsp17
-rw-r--r--sound.cpp140
-rw-r--r--sound/mixer.cpp2
-rw-r--r--timer.cpp174
-rw-r--r--timer.h62
13 files changed, 461 insertions, 36 deletions
diff --git a/Makefile.common b/Makefile.common
index 0fce38f34b..183540d78b 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -16,7 +16,7 @@ OBJS += util.o newgui.o gui/widget.o gui/dialog.o \
v3/resource_v3.o v4/resource_v4.o scaler.o main.o \
simon/midi.o simon/simon.o simon/simonsys.o simon/simonvga.o \
simon/simondebug.o simon/simonres.o simon/simonitems.o simon/simonverb.o \
- sound/mididrv.o config-file.o bundle.o
+ sound/mididrv.o config-file.o bundle.o timer.o
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
debugrl.h whatsnew.txt readme.txt copying.txt \
diff --git a/bundle.cpp b/bundle.cpp
index ca695c9c2b..67eade6ea6 100644
--- a/bundle.cpp
+++ b/bundle.cpp
@@ -27,6 +27,7 @@ Bundle::Bundle(Scumm * parent) {
_voiceFile = NULL;
_musicFile = NULL;
_scumm = parent;
+ _lastSong = -1;
}
Bundle::~Bundle() {
@@ -37,7 +38,7 @@ Bundle::~Bundle() {
fclose (_musicFile);
}
-int32 Bundle::openVoiceFile(char * filename) {
+bool Bundle::openVoiceFile(char * filename) {
int32 tag, offset;
if (_voiceFile != NULL) {
@@ -79,7 +80,7 @@ int32 Bundle::openVoiceFile(char * filename) {
return true;
}
-int32 Bundle::openMusicFile(char * filename) {
+bool Bundle::openMusicFile(char * filename) {
int32 tag, offset;
if (_musicFile != NULL) {
@@ -113,9 +114,9 @@ int32 Bundle::openMusicFile(char * filename) {
if ((c = _scumm->fileReadByte(_musicFile)) != 0)
name[z++] = c;
name[z] = '\0';
- strcpy(_bundleVoiceTable[i].filename, name);
- _bundleVoiceTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
- _bundleVoiceTable[i].size = _scumm->fileReadDwordBE(_musicFile);
+ strcpy(_bundleMusicTable[i].filename, name);
+ _bundleMusicTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
+ _bundleMusicTable[i].size = _scumm->fileReadDwordBE(_musicFile);
}
return true;
@@ -177,32 +178,36 @@ int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte * com
return 0;
}
- _scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset, SEEK_SET);
- tag = _scumm->fileReadDwordBE(_musicFile);
- num = _scumm->fileReadDwordBE(_musicFile);
- _scumm->fileReadDwordBE(_musicFile);
- _scumm->fileReadDwordBE(_musicFile);
+ if (_lastSong != index) {
+ _scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset, SEEK_SET);
+ tag = _scumm->fileReadDwordBE(_musicFile);
+ num = _scumm->fileReadDwordBE(_musicFile);
+ _scumm->fileReadDwordBE(_musicFile);
+ _scumm->fileReadDwordBE(_musicFile);
- if (tag != MKID_BE('COMP')) {
- warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
- return 0;
- }
+ if (tag != MKID_BE('COMP')) {
+ warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
+ return 0;
+ }
- for (i = 0; i < num; i++) {
- _compMusicTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
- _compMusicTable[i].size = _scumm->fileReadDwordBE(_musicFile);
- _compMusicTable[i].codec = _scumm->fileReadDwordBE(_musicFile);
- _scumm->fileReadDwordBE(_musicFile);
+ for (i = 0; i < num; i++) {
+ _compMusicTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
+ _compMusicTable[i].size = _scumm->fileReadDwordBE(_musicFile);
+ _compMusicTable[i].codec = _scumm->fileReadDwordBE(_musicFile);
+ _scumm->fileReadDwordBE(_musicFile);
+ }
}
- comp_input = (byte *)malloc(_compMusicTable[i].size);
+ comp_input = (byte *)malloc(_compMusicTable[number].size);
- _scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset + _compMusicTable[i].offset, SEEK_SET);
- _scumm->fileRead(_musicFile, comp_input, _compMusicTable[i].size);
- final_size = decompressCodec(_compMusicTable[i].codec, comp_input, comp_final, _compMusicTable[i].size);
+ _scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset + _compMusicTable[number].offset, SEEK_SET);
+ _scumm->fileRead(_musicFile, comp_input, _compMusicTable[number].size);
+ final_size = decompressCodec(_compMusicTable[number].codec, comp_input, comp_final, _compMusicTable[number].size);
free(comp_input);
+ _lastSong = index;
+
return final_size;
}
@@ -339,23 +344,41 @@ int32 Bundle::decompressCodec(int32 codec, byte * comp_input, byte * comp_output
case 4:
output_size = compDecode(comp_input, comp_output);
+ p = comp_output;
+ for (z = 2; z < output_size; z++)
+ p[z] += p[z - 1];
+ for (z = 1; z < output_size; z++)
+ p[z] += p[z - 1];
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
+ output_size = 0;
break;
case 5:
output_size = compDecode(comp_input, comp_output);
+ p = comp_output;
+ for (z = 2; z < output_size; z++)
+ p[z] += p[z - 1];
+ for (z = 1; z < output_size; z++)
+ p[z] += p[z - 1];
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
+ output_size = 0;
break;
case 6:
output_size = compDecode(comp_input, comp_output);
+ p = comp_output;
+ for (z = 2; z < output_size; z++)
+ p[z] += p[z - 1];
+ for (z = 1; z < output_size; z++)
+ p[z] += p[z - 1];
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
+ output_size = 0;
break;
case 10:
diff --git a/bundle.h b/bundle.h
index 0a094b1021..a711f18ebb 100644
--- a/bundle.h
+++ b/bundle.h
@@ -52,13 +52,14 @@ private:
int32 _numVoiceFiles;
int32 _numMusicFiles;
Scumm * _scumm;
+ int32 _lastSong;
public:
Bundle(Scumm * parent);
~Bundle();
- int32 openVoiceFile(char * filename);
- int32 openMusicFile(char * filename);
+ bool openVoiceFile(char * filename);
+ bool openMusicFile(char * filename);
int32 decompressVoiceSampleByName(char * name, byte * comp_final);
int32 decompressVoiceSampleByIndex(int32 index, byte * comp_final);
int32 decompressMusicSampleByName(char * name, int32 number, byte * comp_final);
diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp
index d19833dbe8..13ce14e833 100644
--- a/gui/ListWidget.cpp
+++ b/gui/ListWidget.cpp
@@ -188,6 +188,7 @@ bool ListWidget::handleKeyUp(char key, int modifiers)
{
if (key == _currentKeyDown)
_currentKeyDown = 0;
+ return true;
}
void ListWidget::lostFocusWidget()
diff --git a/init.cpp b/init.cpp
index 050b3b5903..d966da06d7 100644
--- a/init.cpp
+++ b/init.cpp
@@ -28,10 +28,12 @@
Scumm::Scumm (void) {
_newgui = new NewGui(this);
_bundle = new Bundle(this);
+ _timer = new Timer(this);
}
Scumm::~Scumm (void) {
delete [] _actors;
delete _newgui;
delete _bundle;
+ delete _timer;
}
diff --git a/morphos/Makefile b/morphos/Makefile
index 82e5fa55a4..53909bec93 100644
--- a/morphos/Makefile
+++ b/morphos/Makefile
@@ -21,7 +21,7 @@ OBJS = actor.o akos.o boxes.o config-file.o costume.o gfx.o object.o resource.o
morphos.o morphos_sound.o morphos_start.o script_v1.o script_v2.o debug.o gui.o \
imuse.o fmopl.o mixer.o mididrv.o debugrl.o vars.o insane.o \
gameDetector.o init.o resource_v3.o resource_v4.o util.o main.o \
- bundle.o $(GUIOBJS) $(SIMONOBJS)
+ bundle.o timer.o $(GUIOBJS) $(SIMONOBJS)
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
windows.cpp debugrl.h whatsnew.txt readme.txt copying.txt \
diff --git a/scumm.h b/scumm.h
index 627081652f..bf54d89e69 100644
--- a/scumm.h
+++ b/scumm.h
@@ -27,6 +27,7 @@
#include "system.h"
#include "sound/mixer.h"
#include "bundle.h"
+#include "timer.h"
#define SCUMMVM_VERSION "0.2.2 CVS"
#define SCUMMVM_CVS "2002-08-03"
@@ -339,6 +340,7 @@ public:
ObjectData *_objs;
ScummDebugger *_debugger;
Bundle * _bundle;
+ Timer * _timer;
struct {
byte mode[rtNumTypes];
@@ -747,6 +749,14 @@ public:
bool _soundsPaused, _soundsPaused2;
bool _soundVolumePreset;
+ int32 _numberBundleMusic;
+ int32 _currentSampleBundleMusic;
+ int32 _numberSamplesBundleMusic;
+ int32 _offsetSampleBundleMusic;
+ int32 _offsetBufBundleMusic;
+ byte * _musicBundleBufFinal;
+ byte * _musicBundleBufOutput;
+
void setupSound();
void processSoundQues();
void playSound(int sound);
@@ -770,6 +780,9 @@ public:
void pauseSounds(bool pause);
bool isSfxFinished();
void playBundleSound(char *sound);
+ void playBundleMusic(int32 song);
+ void stopBundleMusic();
+ int bundleMusicHandler(int t);
void decompressBundleSound(int index);
int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned = false);
int playSfxSound_MP3(void *sound, uint32 size);
diff --git a/scummvm.cpp b/scummvm.cpp
index d1c60cc260..212dcf82cc 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -83,6 +83,8 @@ void Scumm::scummInit()
setShake(0);
setupCursor();
+
+ _timer->init();
/* Allocate and initilise actors */
_actors = new Actor[MAX_ACTORS];
@@ -190,8 +192,10 @@ void Scumm::scummInit()
#ifdef COMPRESSED_SOUND_FILE
_current_cache = 0;
#endif
-
- _system->set_timer(5 * 60 * 1000, &autosave);
+
+ _numberBundleMusic = -1;
+
+ _timer->installProcedure(&autosave, 5 * 60 * 1000);
}
diff --git a/scummvm.dsp b/scummvm.dsp
index 891380824e..f2a372e4bc 100644
--- a/scummvm.dsp
+++ b/scummvm.dsp
@@ -259,10 +259,6 @@ SOURCE=.\gui\widget.h
# End Group
# Begin Source File
-SOURCE=.\scaler.cpp
-# End Source File
-# Begin Source File
-
SOURCE=.\actor.cpp
!IF "$(CFG)" == "scummvm - Win32 Release"
@@ -404,6 +400,10 @@ SOURCE=.\saveload.cpp
# End Source File
# Begin Source File
+SOURCE=.\scaler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\script.cpp
!IF "$(CFG)" == "scummvm - Win32 Release"
@@ -526,6 +526,10 @@ SOURCE=.\sys.cpp
# End Source File
# Begin Source File
+SOURCE=.\timer.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\vars.cpp
# End Source File
# Begin Source File
@@ -611,6 +615,10 @@ SOURCE=.\StdAfx.h
SOURCE=.\system.h
# End Source File
+# Begin Source File
+
+SOURCE=.\timer.h
+# End Source File
# End Group
# Begin Source File
@@ -622,4 +630,3 @@ SOURCE=.\scummvm.ico
# End Source File
# End Target
# End Project
-
diff --git a/sound.cpp b/sound.cpp
index 0ef0244603..38703971f6 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -6,7 +6,6 @@
* 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
@@ -89,6 +88,10 @@ void Scumm::processSoundQues()
data[1], data[2], data[3], data[4], data[5], data[6], data[7]
);
#endif
+
+ if ((_gameId == GID_DIG) && (data[0] == 4096)){
+ playBundleMusic(data[1] - 1);
+ }
if ((_gameId == GID_DIG) && ((data[0] == 12) || (data[0] == 14))){
uint32 size = 0, rate = 0, tag, chan = 0, bits = 0;
uint8 * ptr = getResourceAddress(rtSound, data[1]);
@@ -771,6 +774,141 @@ bool Scumm::isSfxFinished()
return !_mixer->has_active_channel();
}
+static Scumm * h_scumm;
+
+static int music_handler (int t) {
+ h_scumm->bundleMusicHandler(t);
+ return t;
+}
+
+#define OUTPUT_SIZE 66150 // ((22050 * 2 * 2) / 4) * 3
+
+void Scumm::playBundleMusic(int32 song) {
+ char buf[256];
+
+ if (_numberBundleMusic == -1) {
+ sprintf(buf, "%s%smusic.bun", _gameDataPath, _exe_name);
+ if (_bundle->openMusicFile((char*)&buf) == false)
+ return;
+ h_scumm = this;
+ _musicBundleBufFinal = (byte*)malloc(OUTPUT_SIZE);
+ _musicBundleBufOutput = (byte*)malloc(10 * 0x2000);
+ _currentSampleBundleMusic = 0;
+ _offsetSampleBundleMusic = 0;
+ _offsetBufBundleMusic = 0;
+ _numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByIndex(song);
+ _numberBundleMusic = song;
+ _timer->installProcedure(&music_handler, 1000);
+ return;
+ }
+ if (_numberBundleMusic != song) {
+ _numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByIndex(song);
+ _numberBundleMusic = song;
+ _currentSampleBundleMusic = 0;
+ _offsetSampleBundleMusic = 0;
+ _offsetBufBundleMusic = 0;
+ }
+}
+
+void Scumm::stopBundleMusic() {
+ _numberBundleMusic = -1;
+ if (_musicBundleBufFinal)
+ free(_musicBundleBufFinal);
+ if (_musicBundleBufOutput)
+ free(_musicBundleBufOutput);
+}
+
+int Scumm::bundleMusicHandler(int t) {
+ byte * ptr;
+ int32 l, num = _numberSamplesBundleMusic, length, k;
+ int32 rate = 22050;
+ int32 tag, size = -1, header_size = 0;
+ if (_numberBundleMusic == -1)
+ _timer->releaseProcedure(&music_handler);
+
+ ptr = _musicBundleBufOutput;
+
+
+ for (k = 0, l = _currentSampleBundleMusic; l < num; k++) {
+ length = _bundle->decompressMusicSampleByIndex(_numberBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic)));
+ _offsetSampleBundleMusic += length;
+
+ if (l == 0) {
+ tag = READ_BE_UINT32(ptr); ptr += 4;
+ if (tag != MKID_BE('iMUS')) {
+ warning("Decompression of bundle sound failed");
+ _numberBundleMusic = -1;
+ return t;
+ }
+
+ ptr += 12;
+ while(tag != MKID_BE('DATA')) {
+ tag = READ_BE_UINT32(ptr); ptr += 4;
+ switch(tag) {
+ case MKID_BE('FRMT'):
+ size = READ_BE_UINT32(ptr); ptr += 24;
+ break;
+ case MKID_BE('TEXT'):
+ case MKID_BE('REGN'):
+ case MKID_BE('STOP'):
+ case MKID_BE('JUMP'):
+ size = READ_BE_UINT32(ptr); ptr += size + 4;
+ break;
+ case MKID_BE('DATA'):
+ size = READ_BE_UINT32(ptr); ptr += 4;
+ break;
+
+ default:
+ error("Unknown sound header %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
+ }
+ }
+ if (size < 0) {
+ warning("Decompression sound failed (no size field)");
+ _numberBundleMusic = -1;
+ return t;
+ }
+ header_size = (ptr - _musicBundleBufOutput);
+ }
+
+ l++;
+ _currentSampleBundleMusic = l;
+
+ if (_offsetSampleBundleMusic >= OUTPUT_SIZE + header_size) {
+ memcpy(_musicBundleBufFinal, (_musicBundleBufOutput + header_size), OUTPUT_SIZE);
+ _offsetBufBundleMusic = _offsetSampleBundleMusic - OUTPUT_SIZE - header_size;
+ memcpy(_musicBundleBufOutput, (_musicBundleBufOutput + (OUTPUT_SIZE + header_size)), _offsetBufBundleMusic);
+ _offsetSampleBundleMusic = _offsetBufBundleMusic;
+ break;
+ }
+ }
+
+ if (l == num)
+ l = 0;
+
+ size = OUTPUT_SIZE;
+ ptr = _musicBundleBufFinal;
+ uint32 s_size = (size * 4) / 3;
+ byte * buffer = (byte*)malloc (s_size + 4);
+ uint32 r = 0, tmp;
+ for (l = 0; l < size; l += 3) {
+ tmp = (ptr[l + 1] & 0x0f) << 8;
+ tmp = (tmp | ptr[l + 0]) << 4;
+ tmp -= 0x8000;
+ buffer[r++] = (uint8)((tmp >> 8) & 0xff);
+ buffer[r++] = (uint8)(tmp & 0xff);
+
+ tmp = (ptr[l + 1] & 0xf0) << 4;
+ tmp = (tmp | ptr[l + 2]) << 4;
+ tmp -= 0x8000;
+ buffer[r++] = (uint8)((tmp >> 8) & 0xff);
+ buffer[r++] = (uint8)(tmp & 0xff);
+ }
+
+ _mixer->play_raw(NULL, buffer, s_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO);
+
+ return t;
+}
+
void Scumm::playBundleSound(char *sound)
{
char buf[256];
diff --git a/sound/mixer.cpp b/sound/mixer.cpp
index 7cb75050cf..daa9ab842d 100644
--- a/sound/mixer.cpp
+++ b/sound/mixer.cpp
@@ -211,7 +211,7 @@ void SoundMixer::set_volume(int volume)
for (int i = 0; i < 128; i++)
_volume_table[i] = i * volume ;
- for (int i = -128; i < 0; i++)
+ for (i = -128; i < 0; i++)
_volume_table[i+256] = i * volume ;
}
diff --git a/timer.cpp b/timer.cpp
new file mode 100644
index 0000000000..a67e46bc09
--- /dev/null
+++ b/timer.cpp
@@ -0,0 +1,174 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header:
+ */
+
+#include "stdafx.h"
+#include "scumm.h"
+#include "scummsys.h"
+#include "timer.h"
+
+static Scumm * scumm;
+
+Timer::Timer(Scumm * parent) {
+ _initialized = false;
+ _timerRunning = false;
+ scumm = _scumm = parent;
+}
+
+Timer::~Timer() {
+ release ();
+}
+
+static int timer_handler (int t)
+{
+ scumm->_timer->handler (&t);
+ return t;
+}
+
+int Timer::handler(int * t) {
+ uint32 interval, l;
+ uint32 beginTime, endTime;
+
+ if (_timerRunning == false)
+ return *t;
+
+ _osystem->lock_mutex(_mutex);
+ beginTime = _osystem->get_msecs();
+
+ if (_timerRunning) {
+ _lastTime = _thisTime;
+ _thisTime = _osystem->get_msecs();
+ interval = _thisTime - _lastTime;
+
+ for (l = 0; l < MAX_TIMERS; l++) {
+ if ((_timerSlots[l].procedure) && (_timerSlots[l].interval > 0)) {
+ _timerSlots[l].counter -= interval;
+ if (_timerSlots[l].counter <= 0) {
+ _timerSlots[l].counter += _timerSlots[l].interval;
+ _timerSlots[l].procedure (0);
+ }
+ }
+ }
+ }
+
+ endTime = _osystem->get_msecs();
+ interval = endTime - beginTime;
+ if (interval < 10) interval = 10;
+ if (interval > 10000) interval = 10000;
+ _osystem->unlock_mutex(_mutex);
+
+ _osystem->set_timer (interval, &timer_handler);
+
+ return *t;
+}
+
+bool Timer::init() {
+ int32 l;
+
+ _osystem = _scumm->_system;
+ if (_osystem == NULL) {
+ printf("Timer: OSystem not initialized !\n");
+ return false;
+ }
+
+ if (_initialized == true)
+ return true;
+
+ for (l = 0; l < MAX_TIMERS; l++) {
+ _timerSlots[l].procedure = NULL;
+ _timerSlots[l].interval = 0;
+ _timerSlots[l].counter = 0;
+ }
+
+ _mutex = _osystem->create_mutex();
+ _thisTime = _osystem->get_msecs();
+ _osystem->set_timer (1000, &timer_handler);
+
+ _timerRunning = true;
+ _initialized = true;
+ return true;
+}
+
+void Timer::release() {
+ int32 l;
+
+ if (_initialized == false)
+ return;
+
+ _timerRunning = false;
+ _initialized = false;
+
+ for (l = 0; l < MAX_TIMERS; l++) {
+ _timerSlots[l].procedure = NULL;
+ _timerSlots[l].interval = 0;
+ _timerSlots[l].counter = 0;
+ }
+ _osystem->delete_mutex(_mutex);
+
+}
+
+bool Timer::installProcedure (int ((*procedure)(int)), int32 interval) {
+ int32 l;
+ bool found = false;
+
+ if (_initialized == false) {
+ printf ("Timer: is not initialized !");
+ return false;
+ }
+
+ _timerRunning = false;
+ for (l = 0; l < MAX_TIMERS; l++) {
+ if (!_timerSlots[l].procedure) {
+ _timerSlots[l].procedure = procedure;
+ _timerSlots[l].interval = interval;
+ _timerSlots[l].counter = interval;
+ found = true;
+ break;
+ }
+ }
+
+ _timerRunning = true;
+ if (!found) {
+ printf ("Can't find free slot !");
+ return false;
+ }
+
+ return true;
+}
+
+void Timer::releaseProcedure (int ((*procedure)(int))) {
+ int32 l;
+
+ if (_initialized == false) {
+ printf ("Timer: is not initialized !");
+ return;
+ }
+
+ _timerRunning = false;
+ for (l = 0; l < MAX_TIMERS; l++) {
+ if (_timerSlots[l].procedure == procedure) {
+ _timerSlots[l].procedure = 0;
+ _timerSlots[l].interval = 0;
+ _timerSlots[l].counter = 0;
+ }
+ }
+ _timerRunning = true;
+}
+
+
diff --git a/timer.h b/timer.h
new file mode 100644
index 0000000000..6ceeff0ca0
--- /dev/null
+++ b/timer.h
@@ -0,0 +1,62 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header:
+ */
+
+#ifndef TIMER_H
+#define TIMER_H
+
+#include "scummsys.h"
+
+#define MAX_TIMERS 5
+
+class OSystem;
+
+class Timer {
+
+protected:
+
+private:
+ OSystem * _osystem;
+ Scumm * _scumm;
+ bool _initialized;
+ bool _timerRunning;
+ void * _timerHandler;
+ int32 _thisTime;
+ int32 _lastTime;
+ void * _mutex;
+
+struct TimerSlots
+{
+ int ((*procedure)(int));
+ int32 interval;
+ int32 counter;
+} _timerSlots [MAX_TIMERS];
+
+public:
+ Timer(Scumm * system);
+ ~Timer();
+
+ int handler(int * t);
+ bool init();
+ void release();
+ bool installProcedure (int ((*procedure)(int)), int32 interval);
+ void releaseProcedure (int ((*procedure)(int)));
+};
+
+#endif