mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-28 11:50:46 +00:00
DIG: preliminarily support for music in the game
svn-id: r4701
This commit is contained in:
parent
ac7e6a15c1
commit
9fa6145d90
@ -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 \
|
||||
|
71
bundle.cpp
71
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 (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);
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
|
5
bundle.h
5
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);
|
||||
|
@ -188,6 +188,7 @@ bool ListWidget::handleKeyUp(char key, int modifiers)
|
||||
{
|
||||
if (key == _currentKeyDown)
|
||||
_currentKeyDown = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ListWidget::lostFocusWidget()
|
||||
|
2
init.cpp
2
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;
|
||||
}
|
||||
|
@ -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 \
|
||||
|
13
scumm.h
13
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
17
scummvm.dsp
17
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
|
||||
|
||||
|
140
sound.cpp
140
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];
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
||||
|
174
timer.cpp
Normal file
174
timer.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
62
timer.h
Normal file
62
timer.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user