Initial commit
This commit is contained in:
285
engines/scumm/imuse_digi/dimuse_sndmgr.cpp
Normal file
285
engines/scumm/imuse_digi/dimuse_sndmgr.cpp
Normal file
@@ -0,0 +1,285 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/decoders/flac.h"
|
||||
#include "audio/decoders/voc.h"
|
||||
#include "audio/decoders/vorbis.h"
|
||||
#include "audio/decoders/mp3.h"
|
||||
|
||||
#include "scumm/resource.h"
|
||||
#include "scumm/scumm.h"
|
||||
#include "scumm/imuse_digi/dimuse_bndmgr.h"
|
||||
#include "scumm/imuse_digi/dimuse_codecs.h"
|
||||
#include "scumm/imuse_digi/dimuse_sndmgr.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
ImuseDigiSndMgr::ImuseDigiSndMgr(ScummEngine *scumm) {
|
||||
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
|
||||
memset(&_sounds[l], 0, sizeof(SoundDesc));
|
||||
}
|
||||
_vm = scumm;
|
||||
_disk = 0;
|
||||
_cacheBundleDir = new BundleDirCache(scumm);
|
||||
assert(_cacheBundleDir);
|
||||
BundleCodecs::initializeImcTables();
|
||||
}
|
||||
|
||||
ImuseDigiSndMgr::~ImuseDigiSndMgr() {
|
||||
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
|
||||
closeSound(&_sounds[l]);
|
||||
}
|
||||
|
||||
delete _cacheBundleDir;
|
||||
BundleCodecs::releaseImcTables();
|
||||
}
|
||||
|
||||
ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::allocSlot() {
|
||||
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
|
||||
if (!_sounds[l].inUse) {
|
||||
_sounds[l].inUse = true;
|
||||
_sounds[l].scheduledForDealloc = false;
|
||||
return &_sounds[l];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ImuseDigiSndMgr::openMusicBundle(SoundDesc *sound, int &disk) {
|
||||
bool result = false;
|
||||
bool compressed = false;
|
||||
|
||||
sound->bundle = new BundleMgr(_vm, _cacheBundleDir);
|
||||
assert(sound->bundle);
|
||||
if (_vm->_game.id == GID_CMI) {
|
||||
if (_vm->_game.features & GF_DEMO) {
|
||||
result = sound->bundle->open("music.bun", compressed);
|
||||
} else {
|
||||
char musicfile[20];
|
||||
if (disk == -1)
|
||||
disk = _vm->VAR(_vm->VAR_CURRENTDISK);
|
||||
Common::sprintf_s(musicfile, "musdisk%d.bun", disk);
|
||||
// if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
|
||||
// _vm->_DiMUSE_v1->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
|
||||
// _vm->_DiMUSE_v1->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
|
||||
// _vm->_DiMUSE_v1->stopAllSounds();
|
||||
// sound->bundle->closeFile();
|
||||
// }
|
||||
|
||||
result = sound->bundle->open(musicfile, compressed);
|
||||
|
||||
// FIXME: Shouldn't we only set _disk if result == true?
|
||||
_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
|
||||
}
|
||||
} else if (_vm->_game.id == GID_DIG)
|
||||
result = sound->bundle->open("digmusic.bun", compressed);
|
||||
else
|
||||
error("ImuseDigiSndMgr::openMusicBundle() Don't know which bundle file to load");
|
||||
|
||||
_vm->VAR(_vm->VAR_MUSIC_BUNDLE_LOADED) = result ? 1 : 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ImuseDigiSndMgr::openVoiceBundle(SoundDesc *sound, int &disk) {
|
||||
bool result = false;
|
||||
bool compressed = false;
|
||||
|
||||
sound->bundle = new BundleMgr(_vm, _cacheBundleDir);
|
||||
assert(sound->bundle);
|
||||
if (_vm->_game.id == GID_CMI) {
|
||||
if (_vm->_game.features & GF_DEMO) {
|
||||
result = sound->bundle->open("voice.bun", compressed);
|
||||
} else {
|
||||
char voxfile[20];
|
||||
if (disk == -1)
|
||||
disk = _vm->VAR(_vm->VAR_CURRENTDISK);
|
||||
Common::sprintf_s(voxfile, "voxdisk%d.bun", disk);
|
||||
// if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
|
||||
// _vm->_DiMUSE_v1->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
|
||||
// _vm->_DiMUSE_v1->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
|
||||
// _vm->_DiMUSE_v1->stopAllSounds();
|
||||
// sound->bundle->closeFile();
|
||||
// }
|
||||
|
||||
result = sound->bundle->open(voxfile, compressed);
|
||||
|
||||
// FIXME: Shouldn't we only set _disk if result == true?
|
||||
_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
|
||||
}
|
||||
} else if (_vm->_game.id == GID_DIG)
|
||||
result = sound->bundle->open("digvoice.bun", compressed);
|
||||
else
|
||||
error("ImuseDigiSndMgr::openVoiceBundle() Don't know which bundle file to load");
|
||||
|
||||
_vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = result ? 1 : 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk) {
|
||||
assert(soundId >= 0);
|
||||
assert(soundType);
|
||||
|
||||
SoundDesc *sound = allocSlot();
|
||||
if (!sound) {
|
||||
error("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
|
||||
}
|
||||
|
||||
const bool header_outside = ((_vm->_game.id == GID_CMI) && !(_vm->_game.features & GF_DEMO));
|
||||
bool result = false;
|
||||
byte *ptr = nullptr;
|
||||
|
||||
switch (soundType) {
|
||||
case IMUSE_RESOURCE:
|
||||
assert(soundName[0] == 0); // Paranoia check
|
||||
|
||||
_vm->_res->lock(rtSound, soundId);
|
||||
ptr = _vm->getResourceAddress(rtSound, soundId);
|
||||
if (ptr == nullptr) {
|
||||
closeSound(sound);
|
||||
return nullptr;
|
||||
}
|
||||
sound->resPtr = ptr;
|
||||
sound->resSize = _vm->getResourceSize(rtSound, soundId) - 8;
|
||||
break;
|
||||
case IMUSE_BUNDLE:
|
||||
if (volGroupId == IMUSE_VOLGRP_VOICE)
|
||||
result = openVoiceBundle(sound, disk);
|
||||
else if (volGroupId == IMUSE_VOLGRP_MUSIC)
|
||||
result = openMusicBundle(sound, disk);
|
||||
else
|
||||
error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
|
||||
if (!result) {
|
||||
closeSound(sound);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (soundName[0] != 0) {
|
||||
if (sound->bundle->readFile(soundName, 0x2000, &ptr, header_outside) == 0 || ptr == nullptr) {
|
||||
closeSound(sound);
|
||||
free(ptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
sound->resPtr = nullptr;
|
||||
break;
|
||||
default:
|
||||
error("ImuseDigiSndMgr::openSound() Unknown soundType %d (trying to load sound %d)", soundType, soundId);
|
||||
}
|
||||
|
||||
Common::strlcpy(sound->name, soundName, sizeof(sound->name));
|
||||
sound->soundId = soundId;
|
||||
|
||||
if (soundType == IMUSE_BUNDLE) {
|
||||
free(ptr);
|
||||
}
|
||||
return sound;
|
||||
}
|
||||
|
||||
void ImuseDigiSndMgr::closeSound(SoundDesc *soundDesc) {
|
||||
// Check if there's an actual sound to close...
|
||||
if (!checkForProperHandle(soundDesc))
|
||||
return;
|
||||
|
||||
if (soundDesc->resPtr) {
|
||||
bool found = false;
|
||||
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
|
||||
if ((_sounds[l].soundId == soundDesc->soundId) && (&_sounds[l] != soundDesc))
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
_vm->_res->unlock(rtSound, soundDesc->soundId);
|
||||
}
|
||||
|
||||
delete soundDesc->bundle;
|
||||
|
||||
memset(soundDesc, 0, sizeof(SoundDesc));
|
||||
}
|
||||
|
||||
ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::findSoundById(int soundId) {
|
||||
SoundDesc *soundDesc = nullptr;
|
||||
for (int i = 0; i < MAX_IMUSE_SOUNDS; i++) {
|
||||
if (_sounds[i].soundId == soundId) {
|
||||
soundDesc = &_sounds[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return soundDesc;
|
||||
}
|
||||
|
||||
ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::getSounds() {
|
||||
return _sounds;
|
||||
}
|
||||
|
||||
void ImuseDigiSndMgr::scheduleSoundForDeallocation(int soundId) {
|
||||
SoundDesc *soundDesc = nullptr;
|
||||
for (int i = 0; i < MAX_IMUSE_SOUNDS; i++) {
|
||||
if (_sounds[i].soundId == soundId) {
|
||||
soundDesc = &_sounds[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there's an actual sound to deallocate...
|
||||
if (!checkForProperHandle(soundDesc))
|
||||
return;
|
||||
|
||||
soundDesc->scheduledForDealloc = true;
|
||||
}
|
||||
|
||||
void ImuseDigiSndMgr::closeSoundById(int soundId) {
|
||||
SoundDesc *soundDesc = nullptr;
|
||||
for (int i = 0; i < MAX_IMUSE_SOUNDS; i++) {
|
||||
if (_sounds[i].soundId == soundId) {
|
||||
soundDesc = &_sounds[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (soundDesc) {
|
||||
assert(checkForProperHandle(soundDesc));
|
||||
|
||||
if (soundDesc->resPtr) {
|
||||
_vm->_res->unlock(rtSound, soundDesc->soundId);
|
||||
}
|
||||
|
||||
delete soundDesc->bundle;
|
||||
|
||||
memset(soundDesc, 0, sizeof(SoundDesc));
|
||||
}
|
||||
}
|
||||
|
||||
bool ImuseDigiSndMgr::checkForProperHandle(SoundDesc *soundDesc) {
|
||||
if (!soundDesc)
|
||||
return false;
|
||||
for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
|
||||
if (soundDesc == &_sounds[l])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
Reference in New Issue
Block a user