aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorPaweł Kołodziejski2002-10-01 17:20:05 +0000
committerPaweł Kołodziejski2002-10-01 17:20:05 +0000
commite3cd40f700dce76229b7748cd1f3243528cc50e0 (patch)
tree0bd0773e83c718146d5faff242260bc76f076e05 /scumm
parent969a74720c33df8f4ba1717d07bff74187b25c0d (diff)
downloadscummvm-rg350-e3cd40f700dce76229b7748cd1f3243528cc50e0.tar.gz
scummvm-rg350-e3cd40f700dce76229b7748cd1f3243528cc50e0.tar.bz2
scummvm-rg350-e3cd40f700dce76229b7748cd1f3243528cc50e0.zip
synced with local sources - imuse
svn-id: r5060
Diffstat (limited to 'scumm')
-rw-r--r--scumm/imuse.cpp67
-rw-r--r--scumm/imuse.h20
2 files changed, 75 insertions, 12 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 1b5f848352..9325011df9 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -4867,18 +4867,23 @@ void IMuseDigital::handler() {
uint32 new_size = _channel[l]._mixerSize;
uint32 mixer_size = new_size;
- if (_channel[l]._offset + _channel[l]._mixerSize > _channel[l]._size) {
- new_size = _channel[l]._size - _channel[l]._offset;
- if(_channel[l]._isLoop == false) {
+
+ if(_channel[l]._isLoop == false) {
+ if (_channel[l]._offset + _channel[l]._mixerSize > _channel[l]._size) {
+ new_size = _channel[l]._size - _channel[l]._offset;
_channel[l]._toBeRemoved = true;
mixer_size = new_size;
}
+ } else {
+ if (_channel[l]._offset + _channel[l]._mixerSize >= _channel[l]._jump[0]._offset) {
+ new_size = _channel[l]._jump[0]._offset - _channel[l]._offset;
+ }
}
byte *buf = (byte*)malloc(mixer_size);
memcpy(buf, _channel[l]._data + _channel[l]._offset, new_size);
if ((new_size != _channel[l]._mixerSize) && (_channel[l]._isLoop == true)) {
- memcpy(buf + new_size, _channel[l]._data, _channel[l]._mixerSize - new_size);
+ memcpy(buf + new_size, _channel[l]._data + _channel[l]._jump[0]._dest, _channel[l]._mixerSize - new_size);
}
new_mixer = false;
@@ -4907,7 +4912,7 @@ void IMuseDigital::handler() {
_scumm->_system->unlock_mutex(_scumm->_mixer->_mutex);
if ((new_size != _channel[l]._mixerSize) && (_channel[l]._isLoop == true)) {
- _channel[l]._offset = _channel[l]._mixerSize - new_size;
+ _channel[l]._offset = _channel[l]._jump[0]._dest + (_channel[l]._mixerSize - new_size);
} else {
_channel[l]._offset += _channel[l]._mixerSize;
}
@@ -4922,12 +4927,15 @@ void IMuseDigital::startSound(int sound) {
for(l = 0; l < MAX_DIGITAL_CHANNELS; l++) {
if(_channel[l]._used == false) {
byte *ptr = _scumm->getResourceAddress(rtSound, sound);
+ byte *s_ptr = ptr;
if(ptr == NULL) {
warning("IMuseDigital::startSound(%d) NULL resource pointer", sound);
return;
}
_channel[l]._idSound = sound;
_channel[l]._offset = 0;
+ _channel[l]._numRegions = 0;
+ _channel[l]._numJumps = 0;
ptr += 16;
uint32 tag, size;
@@ -4945,17 +4953,33 @@ void IMuseDigital::startSound(int sound) {
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
case MKID_BE('REGN'):
- size = READ_BE_UINT32(ptr); ptr += size;
- _channel[l]._offsetRegion = READ_BE_UINT32(ptr); ptr += 4;
+ ptr += 4;
+ if (_channel[l]._numRegions >= MAX_IMUSE_REGIONS) {
+ warning("IMuseDigital::startSound(%d) Not enough space for Region");
+ ptr += 8;
+ break;
+ }
+ _channel[l]._region[_channel[l]._numRegions]._offset = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._region[_channel[l]._numRegions]._length = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._numRegions++;
break;
case MKID_BE('STOP'):
- size = READ_BE_UINT32(ptr); ptr += size;
+ ptr += 4;
_channel[l]._offsetStop = READ_BE_UINT32(ptr); ptr += 4;
break;
case MKID_BE('JUMP'):
- size = READ_BE_UINT32(ptr); ptr += size;
- _channel[l]._offsetJump = READ_BE_UINT32(ptr); ptr += 4;
+ ptr += 4;
+ if (_channel[l]._numJumps >= MAX_IMUSE_JUMPS) {
+ warning("IMuseDigital::startSound(%d) Not enough space for Jump");
+ ptr += 16;
+ break;
+ }
+ _channel[l]._jump[_channel[l]._numJumps]._offset = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._dest = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._id = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._unk = READ_BE_UINT32(ptr); ptr += 4;
_channel[l]._isLoop = true;
+ _channel[l]._numJumps++;
break;
case MKID_BE('DATA'):
size = READ_BE_UINT32(ptr); ptr += 4;
@@ -4966,6 +4990,29 @@ void IMuseDigital::startSound(int sound) {
if (tag == MKID_BE('DATA')) break;
}
+ uint32 header_size = ptr - s_ptr;
+ _channel[l]._offsetStop -= header_size;
+ if (_channel[l]._bits == 12) {
+ _channel[l]._offsetStop = (_channel[l]._offsetStop / 3) * 4;
+ }
+ uint32 r;
+ for (r = 0; r < _channel[l]._numRegions; r++) {
+ _channel[l]._region[r]._offset -= header_size;
+ if (_channel[l]._bits == 12) {
+ _channel[l]._region[r]._offset = (_channel[l]._region[r]._offset / 3) * 4;
+ _channel[l]._region[r]._length = (_channel[l]._region[r]._length / 3) * 4;
+ }
+ }
+ if (_channel[l]._numJumps > 0) {
+ for (r = 0; r < _channel[l]._numJumps; r++) {
+ _channel[l]._jump[r]._offset -= header_size;
+ _channel[l]._jump[r]._dest -= header_size;
+ if (_channel[l]._bits == 12) {
+ _channel[l]._jump[r]._offset = (_channel[l]._jump[r]._offset / 3) * 4;
+ _channel[l]._jump[r]._dest = (_channel[l]._jump[r]._dest / 3) * 4;
+ }
+ }
+ }
_channel[l]._mixerTrack = -1;
_channel[l]._mixerSize = 22050 / 5;
_channel[l]._mixerFlags = SoundMixer::FLAG_AUTOFREE;
diff --git a/scumm/imuse.h b/scumm/imuse.h
index a2a9e59a6c..1723d8e570 100644
--- a/scumm/imuse.h
+++ b/scumm/imuse.h
@@ -61,17 +61,33 @@ private:
};
#define MAX_DIGITAL_CHANNELS 10
+#define MAX_IMUSE_JUMPS 1
+#define MAX_IMUSE_REGIONS 3
class IMuseDigital {
private:
+ struct region {
+ uint32 _offset; // begin of region
+ uint32 _length; // lenght of region
+ };
+
+ struct jump {
+ uint32 _offset; // jump position
+ uint32 _dest; // jump to
+ uint32 _id; // id of jump
+ uint32 _unk; // allmost 500 except one value: 2
+ };
+
struct channel {
int8 _volumeLeft;
int8 _volumeRight;
bool _isLoop;
uint32 _offsetStop;
- uint32 _offsetJump;
- uint32 _offsetRegion;
+ jump _jump[MAX_IMUSE_JUMPS];
+ uint32 _numJumps;
+ region _region[MAX_IMUSE_REGIONS];
+ uint32 _numRegions;
uint32 _offset;
byte *_data;
uint32 _freq;