diff options
author | Benjamin Haisch | 2009-01-25 01:58:16 +0000 |
---|---|---|
committer | Benjamin Haisch | 2009-01-25 01:58:16 +0000 |
commit | 6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4 (patch) | |
tree | b7db06751dff7c16b5dc238ca68b26dae716bf26 | |
parent | b93db9f30f9dca7398f56c3be1a5f04cbdbd3e8d (diff) | |
download | scummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.tar.gz scummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.tar.bz2 scummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.zip |
- Implemented sound decompression for Manhole EGA
svn-id: r36048
-rw-r--r-- | engines/made/made.cpp | 19 | ||||
-rw-r--r-- | engines/made/resource.cpp | 12 | ||||
-rw-r--r-- | engines/made/sound.cpp | 107 | ||||
-rw-r--r-- | engines/made/sound.h | 19 |
4 files changed, 147 insertions, 10 deletions
diff --git a/engines/made/made.cpp b/engines/made/made.cpp index a7be211ada..e225f41c17 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -112,7 +112,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng _soundRate = 11025; break; case GID_MANHOLE: - _soundRate = getVersion() == 2 ? 11025 : 4000; + _soundRate = 11025; break; case GID_LGOP2: _soundRate = 8000; @@ -249,6 +249,23 @@ void MadeEngine::handleEvents() { Common::Error MadeEngine::go() { +/* + byte source[200000], dest[500000]; + + int size; + FILE *f = fopen("Q:\\OldGames\\scummvm\\00000003.snd", "rb"); + size = fread(source, 1, 200000, f); + fclose(f); + + ManholeEgaSoundDecompressor dec; + dec.decompress(source, dest, size); + + FILE *x = fopen("Q:\\OldGames\\scummvm\\test.0", "wb"); + fwrite(dest, size * 4, 1, x); + fclose(x); + + return Common::kNoError; +*/ resetAllTimers(); if (getGameID() == GID_RTZ) { diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index c3c9195204..b44c2d100c 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -265,16 +265,10 @@ Audio::AudioStream *SoundResource::getAudioStream(int soundRate, bool loop) { } void SoundResourceV1::load(byte *source, int size) { - // TODO: This is all wrong. Seems like the sound is compressed - // but where is the compression info? (chunks, chunk size) - - _soundSize = size; + _soundSize = size * 4; _soundData = new byte[_soundSize]; - - // TODO: We set the audio to silent for now - //memcpy(_soundData, source, _soundSize); - memset(_soundData, 0x80, _soundSize); - + ManholeEgaSoundDecompressor dec; + dec.decompress(source, _soundData, size); } /* MenuResource */ diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp index 9c59232dd2..5af514d3bc 100644 --- a/engines/made/sound.cpp +++ b/engines/made/sound.cpp @@ -31,6 +31,113 @@ namespace Made { +void ManholeEgaSoundDecompressor::decompress(byte *source, byte *dest, uint32 size) { + /* Some kind of ADPCM compression. I hope this works on BE machines. */ + int newmode; + _source = source; + _dest = dest; + _size = size; + _bitBuffer = 0; + _bitsLeft = 0; + _writeFlag = false; + _eof = false; + _sample1 = 0x80000; + _sample2 = 0x800000; + _sample3 = 0x800000; + _sample4 = 0x800000; + _mode = getBit(); + while (!_eof) { + update1(); + update3(); + update0(); + newmode = getBit(); + if (_eof) + break; + if (newmode == _mode) { + update1(); + update3(); + do { + update0(); + newmode = getBit(); + if (_eof || newmode != _mode) + break; + update2(); + update3(); + } while (1); + } + _mode = newmode; + } +} + +int ManholeEgaSoundDecompressor::getBit() { + if (_bitsLeft == 0) { + if (_size == 0) { + _eof = true; + return 0; + } + _bitBuffer = READ_BE_UINT16(_source); + _source += 2; + _bitsLeft = 16; + _size -= 2; + } + int temp = _bitBuffer & 0x8000; + _bitBuffer <<= 1; + _bitsLeft--; + return temp; +} + +void ManholeEgaSoundDecompressor::update0() { + SWAP(_sample1, _sample3); + if (_sample2 & 0x80000000) { + _sample2 -= (_sample2 >> 8) | 0xFF000000; + } else { + _sample2 -= _sample2 >> 8; + } + _sample2 += 0x8000; + if (_sample2 & 0x80000000) { + _sample2 = 0; + } else if ((_sample2 & 0xFFFF0000) > 0x00FF0000) { + _sample2 = 0xFF0000; + } + _sample1 += _sample2; + _sample1 >>= 1; + _sample1 -= _sample4; + _sample1 >>= 2; + _sample4 += _sample1; + if (_writeFlag) { + *_dest++ = (_sample4 & 0xFF0000) >> 16; + } + _writeFlag = !_writeFlag; + _sample1 = _sample2; + SWAP(_sample1, _sample3); +} + +void ManholeEgaSoundDecompressor::update1() { + if (_sample1 & 0x80000000) { + _sample1 -= (_sample1 >> 8) | 0xFF000000; + } else { + _sample1 -= _sample1 >> 8; + } + _sample1 += 500; +} + +void ManholeEgaSoundDecompressor::update2() { + uint32 temp = (_sample1 >> 6) | ((_sample1 & 0xFF) << 27) | ((_sample1 & 0xC0) >> 5); + if (_sample1 & 0x80000000) { + _sample1 += temp | 0xFC000000; + } else { + _sample1 += temp & 0x03FFFFFF; + } + _sample1 += 500; +} + +void ManholeEgaSoundDecompressor::update3() { + if (_mode) + _sample2 -= _sample1; + else + _sample2 += _sample1; +} + void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray) { int16 prevSample = 0, workSample = 0; diff --git a/engines/made/sound.h b/engines/made/sound.h index 02e046ed2e..eb2157bd42 100644 --- a/engines/made/sound.h +++ b/engines/made/sound.h @@ -33,6 +33,25 @@ namespace Made { +class ManholeEgaSoundDecompressor { +public: + void decompress(byte *source, byte *dest, uint32 size); +protected: + byte *_source, *_dest; + uint32 _size; + uint16 _bitBuffer; + int _bitsLeft; + int32 _sample1, _sample2, _sample3, _sample4; + bool _writeFlag; + bool _eof; + int _mode; + int getBit(); + void update0(); + void update1(); + void update2(); + void update3(); +}; + struct SoundEnergyItem { uint32 position; byte energy; |