diff options
author | Eugene Sandulenko | 2009-02-28 10:46:33 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2009-02-28 10:46:33 +0000 |
commit | 5aa50ec889109864cbdd13298b4026c8ed78f484 (patch) | |
tree | f5cdded9d2cd6e5742152df99d176641551b03de /engines/sword1/sound.cpp | |
parent | c62834cc0c4033acb2d37a65dbcd6a998b88cc76 (diff) | |
download | scummvm-rg350-5aa50ec889109864cbdd13298b4026c8ed78f484.tar.gz scummvm-rg350-5aa50ec889109864cbdd13298b4026c8ed78f484.tar.bz2 scummvm-rg350-5aa50ec889109864cbdd13298b4026c8ed78f484.zip |
Patch #2638336: Broken Sword PSX Support
svn-id: r38956
Diffstat (limited to 'engines/sword1/sound.cpp')
-rw-r--r-- | engines/sword1/sound.cpp | 144 |
1 files changed, 122 insertions, 22 deletions
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index caf6d48613..cab3c2d2a4 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -34,6 +34,7 @@ #include "sword1/resman.h" #include "sword1/logic.h" #include "sword1/sword1.h" +#include "sword1/vag.h" #include "sound/flac.h" #include "sound/mp3.h" @@ -160,22 +161,29 @@ void Sound::playSample(QueueElement *elem) { if (_fxList[elem->id].roomVolList[cnt].roomNo) { if ((_fxList[elem->id].roomVolList[cnt].roomNo == (int)Logic::_scriptVars[SCREEN]) || (_fxList[elem->id].roomVolList[cnt].roomNo == -1)) { - + uint8 volL = (_fxList[elem->id].roomVolList[cnt].leftVol * 10 * _sfxVolL) / 255; uint8 volR = (_fxList[elem->id].roomVolList[cnt].rightVol * 10 * _sfxVolR) / 255; int8 pan = (volR - volL) / 2; uint8 volume = (volR + volL) / 2; - uint32 size = READ_LE_UINT32(sampleData + 0x28); - uint8 flags; - if (READ_LE_UINT16(sampleData + 0x22) == 16) - flags = Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN; - else - flags = Audio::Mixer::FLAG_UNSIGNED; - if (READ_LE_UINT16(sampleData + 0x16) == 2) - flags |= Audio::Mixer::FLAG_STEREO; - if (_fxList[elem->id].type == FX_LOOP) - flags |= Audio::Mixer::FLAG_LOOP; - _mixer->playRaw(Audio::Mixer::kSFXSoundType, &elem->handle, sampleData + 0x2C, size, 11025, flags, elem->id, volume, pan); + + if (SwordEngine::isPsx()) { ; + uint32 size = READ_LE_UINT32(sampleData); + Audio::AudioStream *audStream = new VagStream(new Common::MemoryReadStream(sampleData + 4, size-4), _fxList[elem->id].type == FX_LOOP); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &elem->handle, audStream, elem->id, volume, pan, false, false, false); + } else { + uint32 size = READ_LE_UINT32(sampleData + 0x28); + uint8 flags; + if (READ_LE_UINT16(sampleData + 0x22) == 16) + flags = Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN; + else + flags = Audio::Mixer::FLAG_UNSIGNED; + if (READ_LE_UINT16(sampleData + 0x16) == 2) + flags |= Audio::Mixer::FLAG_STEREO; + if (_fxList[elem->id].type == FX_LOOP) + flags |= Audio::Mixer::FLAG_LOOP; + _mixer->playRaw(Audio::Mixer::kSFXSoundType, &elem->handle, sampleData + 0x2C, size, 11025, flags, elem->id, volume, pan); + } } } else break; @@ -187,11 +195,69 @@ bool Sound::startSpeech(uint16 roomNo, uint16 localNo) { warning("Sound::startSpeech: COW file isn't open"); return false; } + + uint32 locIndex = 0xFFFFFFFF; + uint32 sampleSize = 0; + uint32 index = 0; - uint32 locIndex = _cowHeader[roomNo] >> 2; - uint32 sampleSize = _cowHeader[locIndex + (localNo * 2)]; - uint32 index = _cowHeader[locIndex + (localNo * 2) - 1]; + if (_cowMode == CowPSX) { + Common::File file; + uint16 i; + + if (!file.open("speech.lis")) { + warning ("Could not open speech.lis"); + return false; + } + + for (i = 0; !file.eos() && !file.err(); i++) + if (file.readUint16LE() == roomNo) { + locIndex = i; + break; + } + file.close(); + + if (locIndex == 0xFFFFFFFF) { + warning ("Could not find room %d in speech.lis", roomNo); + return false; + } + + if (!file.open("speech.inf")) { + warning ("Could not open speech.inf"); + return false; + } + + file.seek(locIndex * 4 + 2); // 4 bytes per room, skip first 2 bytes + + uint16 numLines = file.readUint16LE(); + uint16 roomOffset = file.readUint16LE(); + + file.seek(0x112 + roomOffset * 2); // The offset is in terms of uint16's, so multiply by 2. Skip the 0x112 byte header too. + + locIndex = 0xFFFFFFFF; + + for (i = 0; i < numLines; i++) + if (file.readUint16LE() == localNo) { + locIndex = i; + break; + } + + if (locIndex == 0xFFFFFFFF) { + warning ("Could not find local number %d in room %d in speech.inf", roomNo, localNo); + return false; + } + + file.close(); + + index = _cowHeader[(roomOffset + locIndex) * 2]; + sampleSize = _cowHeader[(roomOffset + locIndex) * 2 + 1]; + } else { + locIndex = _cowHeader[roomNo] >> 2; + sampleSize = _cowHeader[locIndex + (localNo * 2)]; + index = _cowHeader[locIndex + (localNo * 2) - 1]; + } + debug(6, "startSpeech(%d, %d): locIndex %d, sampleSize %d, index %d", roomNo, localNo, locIndex, sampleSize, index); + if (sampleSize) { uint8 speechVol = (_speechVolR + _speechVolL) / 2; int8 speechPan = (_speechVolR - _speechVolL) / 2; @@ -200,6 +266,14 @@ bool Sound::startSpeech(uint16 roomNo, uint16 localNo) { int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); if (data) _mixer->playRaw(Audio::Mixer::kSpeechSoundType, &_speechHandle, data, size, 11025, SPEECH_FLAGS, SOUND_SPEECH_ID, speechVol, speechPan); + } else if (_cowMode == CowPSX && sampleSize != 0xffffffff) { + _cowFile.seek(index * 2048); + _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, new VagStream(_cowFile.readStream(sampleSize)), SOUND_SPEECH_ID, speechVol, speechPan); + // with compressed audio, we can't calculate the wave volume. + // so default to talking. + for (int cnt = 0; cnt < 480; cnt++) + _waveVolume[cnt] = true; + _waveVolPos = 0; } #ifdef USE_FLAC else if (_cowMode == CowFlac) { @@ -419,21 +493,47 @@ void Sound::initCowSystem(void) { debug(1, "Using uncompressed Speech Cluster"); _cowMode = CowWave; } + + if (SwordEngine::isPsx()) { + // There's only one file on the PSX, so set it to the current disc. + _currentCowFile = SwordEngine::_systemVars.currentCD; + if (!_cowFile.isOpen()) { + if (!_cowFile.open("speech.dat")) + error ("Could not open speech.dat"); + _cowMode = CowPSX; + } + } + if (!_cowFile.isOpen()) _cowFile.open("speech.clu"); + if (!_cowFile.isOpen()) { _cowFile.open("cows.mad"); if (_cowFile.isOpen()) _cowMode = CowDemo; } + if (_cowFile.isOpen()) { - _cowHeaderSize = _cowFile.readUint32LE(); - _cowHeader = (uint32*)malloc(_cowHeaderSize); - if (_cowHeaderSize & 3) - error("Unexpected cow header size %d", _cowHeaderSize); - for (uint32 cnt = 0; cnt < (_cowHeaderSize / 4) - 1; cnt++) - _cowHeader[cnt] = _cowFile.readUint32LE(); - _currentCowFile = SwordEngine::_systemVars.currentCD; + if (SwordEngine::isPsx()) { + // Get data from the external table file + Common::File tableFile; + if (!tableFile.open("speech.tab")) + error ("Could not open speech.tab"); + _cowHeaderSize = tableFile.size(); + _cowHeader = (uint32 *)malloc(_cowHeaderSize); + if (_cowHeaderSize & 3) + error("Unexpected cow header size %d", _cowHeaderSize); + for (uint32 cnt = 0; cnt < _cowHeaderSize / 4; cnt++) + _cowHeader[cnt] = tableFile.readUint32LE(); + } else { + _cowHeaderSize = _cowFile.readUint32LE(); + _cowHeader = (uint32*)malloc(_cowHeaderSize); + if (_cowHeaderSize & 3) + error("Unexpected cow header size %d", _cowHeaderSize); + for (uint32 cnt = 0; cnt < (_cowHeaderSize / 4) - 1; cnt++) + _cowHeader[cnt] = _cowFile.readUint32LE(); + _currentCowFile = SwordEngine::_systemVars.currentCD; + } } else warning("Sound::initCowSystem: Can't open SPEECH%d.CLU", SwordEngine::_systemVars.currentCD); } |