diff options
Diffstat (limited to 'engines/kyra/sound_towns.cpp')
-rw-r--r-- | engines/kyra/sound_towns.cpp | 148 |
1 files changed, 112 insertions, 36 deletions
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index 4b25db33f2..af741a1ebe 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -35,8 +35,8 @@ namespace Kyra { SoundTowns::SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer), _lastTrack(-1), _musicTrackData(0), _sfxFileData(0), _cdaPlaying(0), - _sfxFileIndex((uint)-1), _musicFadeTable(0), _sfxWDTable(0), _sfxBTTable(0), _sfxChannel(0x46) { - + _sfxFileIndex((uint)-1), _musicFadeTable(0), _sfxWDTable(0), _sfxBTTable(0), _sfxChannel(0x46), _currentResourceSet(0) { + memset(&_resInfo, 0, sizeof(_resInfo)); _driver = new TownsEuphonyDriver(_mixer); } @@ -46,6 +46,8 @@ SoundTowns::~SoundTowns() { delete _driver; delete[] _musicTrackData; delete[] _sfxFileData; + for (int i = 0; i < 3; i++) + initAudioResourceInfo(i, 0); } bool SoundTowns::init() { @@ -78,11 +80,12 @@ void SoundTowns::playTrack(uint8 track) { return; track -= 2; - const int32 *const tTable = (const int32 *)cdaData(); - int tTableIndex = 3 * track; + uint tTableIndex = 3 * track; + + assert(tTableIndex + 2 < res()->cdaTableSize); - int trackNum = (int)READ_LE_UINT32(&tTable[tTableIndex + 2]); - int32 loop = (int32)READ_LE_UINT32(&tTable[tTableIndex + 1]); + int trackNum = (int)READ_LE_UINT32(&res()->cdaTable[tTableIndex + 2]); + int32 loop = (int32)READ_LE_UINT32(&res()->cdaTable[tTableIndex + 1]); if (track == _lastTrack && _musicEnabled) return; @@ -95,7 +98,7 @@ void SoundTowns::playTrack(uint8 track) { g_system->getAudioCDManager()->updateCD(); _cdaPlaying = true; } else if (_musicEnabled) { - playEuphonyTrack(READ_LE_UINT32(&tTable[tTableIndex]), loop); + playEuphonyTrack(READ_LE_UINT32(&res()->cdaTable[tTableIndex]), loop); _cdaPlaying = false; } @@ -117,12 +120,32 @@ void SoundTowns::haltTrack() { _driver->stopParser(); } +void SoundTowns::initAudioResourceInfo(int set, void *info) { + if (set >= kMusicIntro && set <= kMusicFinale) { + delete _resInfo[set]; + _resInfo[set] = info ? new SoundResourceInfo_Towns(*(SoundResourceInfo_Towns*)info) : 0; + } +} + +void SoundTowns::selectAudioResourceSet(int set) { + if (set >= kMusicIntro && set <= kMusicFinale) { + if (_resInfo[set]) + _currentResourceSet = set; + } +} + +bool SoundTowns::hasSoundFile(uint file) const { + if (file < res()->fileListSize) + return (res()->fileList[file] != 0); + return false; +} + void SoundTowns::loadSoundFile(uint file) { - if (_sfxFileIndex == file) + if (_sfxFileIndex == file || file >= res()->fileListSize) return; _sfxFileIndex = file; delete[] _sfxFileData; - _sfxFileData = _vm->resource()->fileData(fileListEntry(file), 0); + _sfxFileData = _vm->resource()->fileData(res()->fileList[file], 0); } void SoundTowns::playSoundEffect(uint8 track, uint8) { @@ -151,8 +174,8 @@ void SoundTowns::playSoundEffect(uint8 track, uint8) { } } - uint8 *fileBody = _sfxFileData + 0x01b8; - int32 offset = (int32)READ_LE_UINT32(_sfxFileData + (track - 0x0b) * 4); + uint8 *fileBody = _sfxFileData + 0x01B8; + int32 offset = (int32)READ_LE_UINT32(_sfxFileData + (track - 0x0B) * 4); if (offset == -1) return; @@ -191,10 +214,10 @@ void SoundTowns::playSoundEffect(uint8 track, uint8) { sfx_WdTable_Number = READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset); sfx_BtTable_Offset += (int16)READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset + 2); - *tgt++ = _sfxBTTable[((sfx_BtTable_Offset >> 2) & 0xff)]; + *tgt++ = _sfxBTTable[((sfx_BtTable_Offset >> 2) & 0xFF)]; sfx_BtTable_Offset += (int16)READ_LE_UINT16(_sfxWDTable + sfx_WdTable_Offset + 4); - *tgt++ = _sfxBTTable[((sfx_BtTable_Offset >> 2) & 0xff)]; + *tgt++ = _sfxBTTable[((sfx_BtTable_Offset >> 2) & 0xFF)]; } } @@ -270,7 +293,7 @@ void SoundTowns::beginFadeOut() { for (int ii = 0; ii < 6; ii++) _driver->chanVolume(ii, fadeVolCur[ii]); for (int ii = 0x40; ii < 0x46; ii++) - _driver->chanVolume(ii, fadeVolCur[ii - 0x3a]); + _driver->chanVolume(ii, fadeVolCur[ii - 0x3A]); for (int ii = 0; ii < 6; ii++) { fadeVolCur[ii] -= fadeVolStep[ii]; @@ -367,13 +390,16 @@ void SoundTowns::fadeOutSoundEffects() { } SoundPC98::SoundPC98(KyraEngine_v1 *vm, Audio::Mixer *mixer) : - Sound(vm, mixer), _musicTrackData(0), _sfxTrackData(0), _lastTrack(-1), _driver(0) { + Sound(vm, mixer), _musicTrackData(0), _sfxTrackData(0), _lastTrack(-1), _driver(0), _currentResourceSet(0) { + memset(&_resInfo, 0, sizeof(_resInfo)); } SoundPC98::~SoundPC98() { delete[] _musicTrackData; delete[] _sfxTrackData; delete _driver; + for (int i = 0; i < 3; i++) + initAudioResourceInfo(i, 0); } bool SoundPC98::init() { @@ -383,8 +409,26 @@ bool SoundPC98::init() { return reslt; } -void SoundPC98::loadSoundFile(uint file) { - if (!scumm_strnicmp(fileListEntry(0), "INTRO", 5)) { +void SoundPC98::initAudioResourceInfo(int set, void *info) { + if (set >= kMusicIntro && set <= kMusicFinale) { + delete _resInfo[set]; + _resInfo[set] = info ? new Common::String(((SoundResourceInfo_PC98*)info)->pattern) : 0; + } +} + +void SoundPC98::selectAudioResourceSet(int set) { + if (set >= kMusicIntro && set <= kMusicFinale) { + if (_resInfo[set]) + _currentResourceSet = set; + } +} + +bool SoundPC98::hasSoundFile(uint file) const { + return true; +} + +void SoundPC98::loadSoundFile(uint) { + if (_currentResourceSet == kMusicIntro) { delete[] _sfxTrackData; _sfxTrackData = 0; @@ -407,14 +451,14 @@ void SoundPC98::loadSoundFile(Common::String file) { } void SoundPC98::playTrack(uint8 track) { - track += extraOffset(); + track -= 1; if (track == _lastTrack && _musicEnabled) return; beginFadeOut(); - Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track); + Common::String musicFile = Common::String::format(resPattern(), track); delete[] _musicTrackData; _musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0); if (_musicEnabled) @@ -464,13 +508,16 @@ void SoundPC98::updateVolumeSettings() { // KYRA 2 SoundTownsPC98_v2::SoundTownsPC98_v2(KyraEngine_v1 *vm, Audio::Mixer *mixer) : - Sound(vm, mixer), _currentSFX(0), _musicTrackData(0), _sfxTrackData(0), _lastTrack(-1), _driver(0), _useFmSfx(false) { + Sound(vm, mixer), _currentSFX(0), _musicTrackData(0), _sfxTrackData(0), _lastTrack(-1), _driver(0), _useFmSfx(false), _currentResourceSet(0) { + memset(&_resInfo, 0, sizeof(_resInfo)); } SoundTownsPC98_v2::~SoundTownsPC98_v2() { delete[] _musicTrackData; delete[] _sfxTrackData; delete _driver; + for (int i = 0; i < 3; i++) + initAudioResourceInfo(i, 0); } bool SoundTownsPC98_v2::init() { @@ -478,7 +525,9 @@ bool SoundTownsPC98_v2::init() { TownsPC98_AudioDriver::kType86 : TownsPC98_AudioDriver::kTypeTowns); if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { - _vm->checkCD(); + if (_resInfo[_currentResourceSet]) + if (_resInfo[_currentResourceSet]->cdaTableSize) + _vm->checkCD(); // FIXME: While checking for 'track1.XXX(X)' looks like // a good idea, we should definitely not be doing this // here. Basically our filenaming scheme could change @@ -486,9 +535,9 @@ bool SoundTownsPC98_v2::init() { // this misses the possibility that we play the tracks // right off CD. So we should find another way to // check if we have access to CD audio. - Resource *res = _vm->resource(); + Resource *r = _vm->resource(); if (_musicEnabled && - (res->exists("track1.mp3") || res->exists("track1.ogg") || res->exists("track1.flac") || res->exists("track1.fla"))) + (r->exists("track1.mp3") || r->exists("track1.ogg") || r->exists("track1.flac") || r->exists("track1.fla"))) _musicEnabled = 2; else _musicEnabled = 1; @@ -503,6 +552,26 @@ bool SoundTownsPC98_v2::init() { return reslt; } +void SoundTownsPC98_v2::initAudioResourceInfo(int set, void *info) { + if (set >= kMusicIntro && set <= kMusicFinale) { + delete _resInfo[set]; + _resInfo[set] = info ? new SoundResourceInfo_TownsPC98V2(*(SoundResourceInfo_TownsPC98V2*)info) : 0; + } +} + +void SoundTownsPC98_v2::selectAudioResourceSet(int set) { + if (set >= kMusicIntro && set <= kMusicFinale) { + if (_resInfo[set]) + _currentResourceSet = set; + } +} + +bool SoundTownsPC98_v2::hasSoundFile(uint file) const { + if (file < res()->fileListSize) + return (res()->fileList[file] != 0); + return false; +} + void SoundTownsPC98_v2::loadSoundFile(Common::String file) { delete[] _sfxTrackData; _sfxTrackData = _vm->resource()->fileData(file.c_str(), 0); @@ -513,18 +582,14 @@ void SoundTownsPC98_v2::process() { } void SoundTownsPC98_v2::playTrack(uint8 track) { - track += extraOffset(); - if (track == _lastTrack && _musicEnabled) return; - const uint16 *const cdaTracks = (const uint16 *)cdaData(); - int trackNum = -1; if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { - for (int i = 0; i < cdaTrackNum(); i++) { - if (track == (uint8) READ_LE_UINT16(&cdaTracks[i * 2])) { - trackNum = (int) READ_LE_UINT16(&cdaTracks[i * 2 + 1]) - 1; + for (uint i = 0; i < res()->cdaTableSize; i++) { + if (track == (uint8) READ_LE_UINT16(&res()->cdaTable[i * 2])) { + trackNum = (int) READ_LE_UINT16(&res()->cdaTable[i * 2 + 1]) - 1; break; } } @@ -532,9 +597,10 @@ void SoundTownsPC98_v2::playTrack(uint8 track) { beginFadeOut(); - Common::String musicFile = fileListLen() == 1 ? Common::String::format(fileListEntry(0), track) : fileListEntry(track); + Common::String musicFile = res()->pattern ? Common::String::format(res()->pattern, track) : (res()->fileList ? res()->fileList[track] : 0); if (musicFile.empty()) return; + delete[] _musicTrackData; _musicTrackData = _vm->resource()->fileData(musicFile.c_str(), 0); @@ -569,15 +635,24 @@ void SoundTownsPC98_v2::beginFadeOut() { haltTrack(); } -int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, uint8, bool) { +int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, uint8 priority, bool) { static const uint16 rates[] = { 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 }; static const char patternHOF[] = "%s.PCM"; static const char patternLOL[] = "%s.VOC"; int h = 0; if (_currentSFX) { - while (h < kNumChannelHandles && _mixer->isSoundHandleActive(_soundChannels[h])) + while (h < kNumChannelHandles && _mixer->isSoundHandleActive(_soundChannels[h].handle)) h++; + + if (h >= kNumChannelHandles) { + h = 0; + while (h < kNumChannelHandles && _soundChannels[h].priority > priority) + ++h; + if (h < kNumChannelHandles) + voiceStop(&_soundChannels[h].handle); + } + if (h >= kNumChannelHandles) return 0; } @@ -621,7 +696,7 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, cmd = ~cmd; } else { cmd |= 0x80; - if (cmd == 0xff) + if (cmd == 0xFF) cmd--; } if (cmd < 0x80) @@ -630,9 +705,10 @@ int32 SoundTownsPC98_v2::voicePlay(const char *file, Audio::SoundHandle *handle, } _currentSFX = Audio::makeRawStream(sfx, outsize, sfxRate * 10, Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN); - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundChannels[h], _currentSFX); + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundChannels[h].handle, _currentSFX, -1, volume); + _soundChannels[h].priority = priority; if (handle) - *handle = _soundChannels[h]; + *handle = _soundChannels[h].handle; delete[] data; return 1; |