mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
234 lines
6.1 KiB
C++
234 lines
6.1 KiB
C++
/* 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/>.
|
|
*
|
|
*/
|
|
|
|
#ifdef ENABLE_EOB
|
|
|
|
#include "kyra/sound/sound_intern.h"
|
|
#include "kyra/resource/resource.h"
|
|
#include "kyra/sound/drivers/capcom98.h"
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
namespace Kyra {
|
|
|
|
SoundPC98_Darkmoon::SoundPC98_Darkmoon(KyraEngine_v1 *vm, MidiDriver::DeviceHandle dev, Audio::Mixer *mixer) : Sound(vm, mixer),
|
|
_vm(vm), _driver(nullptr), _soundData(nullptr), _currentResourceSet(-1), _ready(false), _dev(dev), _drvType(kPC98), _lastTrack(-1) {
|
|
|
|
memset(&_resInfo, 0, sizeof(_resInfo));
|
|
_soundData = new uint8[20600];
|
|
memset(_soundData, 0, 20600);
|
|
_fileBuffer = new uint8[10500];
|
|
memset(_fileBuffer, 0, 10500);
|
|
|
|
MusicType type = MidiDriver::getMusicType(dev);
|
|
if (type == MT_MT32)
|
|
_drvType = kMidiMT32;
|
|
else if (type == MT_GM)
|
|
_drvType = kMidiGM;
|
|
}
|
|
|
|
SoundPC98_Darkmoon::~SoundPC98_Darkmoon() {
|
|
delete _driver;
|
|
delete[] _soundData;
|
|
delete[] _fileBuffer;
|
|
for (int i = 0; i < 3; i++)
|
|
initAudioResourceInfo(i, nullptr);
|
|
}
|
|
|
|
Sound::kType SoundPC98_Darkmoon::getMusicType() const {
|
|
return _drvType;
|
|
}
|
|
|
|
Sound::kType SoundPC98_Darkmoon::getSfxType() const {
|
|
return kPC98;
|
|
}
|
|
|
|
bool SoundPC98_Darkmoon::init() {
|
|
_driver = new CapcomPC98AudioDriver(_mixer, _dev);
|
|
_ready = (_soundData && _driver && _driver->isUsable());
|
|
return _ready;
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::initAudioResourceInfo(int set, void *info) {
|
|
if (set < kMusicIntro || set > kMusicFinale)
|
|
return;
|
|
delete _resInfo[set];
|
|
_resInfo[set] = info ? new SoundResourceInfo_PC(*(SoundResourceInfo_PC*)info) : nullptr;
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::selectAudioResourceSet(int set) {
|
|
if (set < kMusicIntro || set > kMusicFinale || set == _currentResourceSet || !_ready)
|
|
return;
|
|
if (_resInfo[set])
|
|
_currentResourceSet = set;
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::loadSoundFile(uint file) {
|
|
if (!_ready)
|
|
return;
|
|
|
|
if (file < res()->fileListSize)
|
|
loadSoundFile(res()->fileList[file]);
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::loadSoundFile(const Common::Path &name) {
|
|
if (!_ready)
|
|
return;
|
|
|
|
haltTrack();
|
|
stopAllSoundEffects();
|
|
|
|
Common::Path path(name);
|
|
path.appendInPlace(_drvType == kPC98 ? ".SDO" : ".SDM");
|
|
if (!_ready || _soundFileLoaded == path)
|
|
return;
|
|
|
|
Common::SeekableReadStream *in = _vm->resource()->createReadStream(path);
|
|
if (!in)
|
|
error("SoundPC98_Darkmoon::loadSoundFile(): Failed to load sound file '%s'", path.toString().c_str());
|
|
|
|
uint16 sz = in->readUint16LE();
|
|
uint8 cmp = in->readByte();
|
|
in->seek(1, SEEK_CUR);
|
|
uint32 outSize = in->readUint32LE();
|
|
if ((cmp == 0 && outSize > 10500) || (cmp != 0 && outSize > 20600))
|
|
error("SoundPC98_Darkmoon::loadSoundFile(): Failed to load sound file '%s'", path.toString().c_str());
|
|
sz -= in->pos();
|
|
in->seek(2, SEEK_CUR);
|
|
|
|
memset(_fileBuffer, 0, 10500);
|
|
uint16 readSize = in->read(_fileBuffer, 10500);
|
|
assert(sz == readSize);
|
|
delete in;
|
|
|
|
memset(_soundData, 0, 20600);
|
|
if (cmp == 0) {
|
|
memcpy(_soundData, _fileBuffer, outSize);
|
|
} else if (cmp == 3) {
|
|
Screen::decodeFrame3(_fileBuffer, _soundData, outSize, true);
|
|
} else if (cmp == 4) {
|
|
Screen::decodeFrame4(_fileBuffer, _soundData, outSize);
|
|
} else {
|
|
error("SoundPC98_Darkmoon::loadSoundFile(): Failed to load sound file '%s'", path.toString().c_str());
|
|
}
|
|
|
|
uint16 instrOffs = READ_LE_UINT16(_soundData);
|
|
if (instrOffs >= 20600)
|
|
error("SoundPC98_Darkmoon::loadSoundFile(): Failed to load sound file '%s'", path.toString().c_str());
|
|
|
|
_driver->loadFMInstruments(_soundData + instrOffs);
|
|
_driver->reset();
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::playTrack(uint8 track) {
|
|
if (track == 0 || track == 2)
|
|
_lastTrack = track;
|
|
playSoundEffect(track, 127);
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::haltTrack() {
|
|
if (!_ready)
|
|
return;
|
|
_driver->stopSong();
|
|
_lastTrack = -1;
|
|
}
|
|
|
|
bool SoundPC98_Darkmoon::isPlaying() const {
|
|
return _ready && _driver && _driver->songIsPlaying();
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::playSoundEffect(uint16 track, uint8 vol) {
|
|
if (!_ready)
|
|
return;
|
|
|
|
if (track == 0 || track == 2) {
|
|
restartBackgroundMusic();
|
|
return;
|
|
}
|
|
|
|
const uint8 *data = getData(track);
|
|
if (!data)
|
|
return;
|
|
|
|
if (track < 52 || track > 67) {
|
|
if (_sfxEnabled)
|
|
_driver->startSoundEffect(data, vol);
|
|
} else if (_musicEnabled) {
|
|
_lastTrack = track;
|
|
_driver->startSong(data, vol, false);
|
|
}
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::stopAllSoundEffects() {
|
|
if (_ready)
|
|
_driver->stopSoundEffect();
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::beginFadeOut() {
|
|
_driver->fadeOut();
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::pause(bool paused) {
|
|
if (_ready && paused)
|
|
_driver->allNotesOff();
|
|
}
|
|
|
|
int SoundPC98_Darkmoon::checkTrigger() {
|
|
return _driver ? _driver->checkSoundMarker() : 99;
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::restartBackgroundMusic() {
|
|
if (_lastTrack == -1) {
|
|
haltTrack();
|
|
stopAllSoundEffects();
|
|
} else {
|
|
_lastTrack = -1;
|
|
const uint8 *data = getData(0);
|
|
if (!data)
|
|
return;
|
|
if (_musicEnabled)
|
|
_driver->startSong(data, 127, true);
|
|
}
|
|
}
|
|
|
|
const uint8 *SoundPC98_Darkmoon::getData(uint16 track) const {
|
|
if (!_ready || track >= 120)
|
|
return nullptr;
|
|
|
|
uint16 offset = READ_LE_UINT16(&_soundData[(track + 1) << 1]);
|
|
return (offset < 20600) ? &_soundData[offset] : nullptr;
|
|
}
|
|
|
|
void SoundPC98_Darkmoon::updateVolumeSettings() {
|
|
if (!_driver || !_ready)
|
|
return;
|
|
|
|
bool mute = false;
|
|
if (ConfMan.hasKey("mute"))
|
|
mute = ConfMan.getBool("mute");
|
|
|
|
_driver->setMusicVolume((mute ? 0 : ConfMan.getInt("music_volume")));
|
|
_driver->setSoundEffectVolume((mute ? 0 : ConfMan.getInt("sfx_volume")));
|
|
}
|
|
|
|
} // End of namespace Kyra
|
|
|
|
#endif
|