diff options
Diffstat (limited to 'engines/sci/sound/drivers/adlib.cpp')
-rw-r--r-- | engines/sci/sound/drivers/adlib.cpp | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp index 4f557be95e..b8e90802b2 100644 --- a/engines/sci/sound/drivers/adlib.cpp +++ b/engines/sci/sound/drivers/adlib.cpp @@ -31,6 +31,7 @@ #include "sci/resource.h" #include "sci/sound/drivers/mididriver.h" +#include "sci/util.h" namespace Sci { @@ -50,7 +51,7 @@ public: kRhythmKeys = 62 }; - MidiDriver_AdLib(Audio::Mixer *mixer) :_playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0), _isOpen(false) { } + MidiDriver_AdLib(Audio::Mixer *mixer) :_playSwitch(true), _masterVolume(15), _rhythmKeyMap(), _opl(0), _isOpen(false) { } virtual ~MidiDriver_AdLib() { } // MidiDriver @@ -70,10 +71,10 @@ public: void setVolume(byte volume); void playSwitch(bool play); - bool loadResource(const byte *data, uint size); + bool loadResource(const SciSpan<const byte> &data); virtual uint32 property(int prop, uint32 param); - bool useRhythmChannel() const { return _rhythmKeyMap != NULL; } + bool useRhythmChannel() const { return _rhythmKeyMap; } private: enum ChannelID { @@ -139,13 +140,13 @@ private: int _masterVolume; Channel _channels[MIDI_CHANNELS]; AdLibVoice _voices[kVoices]; - byte *_rhythmKeyMap; + Common::SpanOwner<SciSpan<const byte> > _rhythmKeyMap; Common::Array<AdLibPatch> _patches; Common::TimerManager::TimerProc _adlibTimerProc; void *_adlibTimerParam; - void loadInstrument(const byte *ins); + void loadInstrument(const SciSpan<const byte> &ins); void voiceOn(int voice, int note, int velocity); void voiceOff(int voice); void setPatch(int voice, int patch); @@ -255,7 +256,7 @@ int MidiDriver_AdLib::openAdLib(bool isSCI0) { void MidiDriver_AdLib::close() { delete _opl; - delete[] _rhythmKeyMap; + _rhythmKeyMap.clear(); } void MidiDriver_AdLib::setVolume(byte volume) { @@ -346,12 +347,12 @@ void MidiDriver_AdLib::onTimer() { } } -void MidiDriver_AdLib::loadInstrument(const byte *ins) { +void MidiDriver_AdLib::loadInstrument(const SciSpan<const byte> &ins) { AdLibPatch patch; // Set data for the operators for (int i = 0; i < 2; i++) { - const byte *op = ins + i * 13; + const byte *op = ins.getUnsafeDataAt(i * 13, 13); patch.op[i].kbScaleLevel = op[0] & 0x3; patch.op[i].frequencyMult = op[1] & 0xf; patch.op[i].attackRate = op[3] & 0xf; @@ -589,7 +590,7 @@ void MidiDriver_AdLib::voiceOn(int voice, int note, int velocity) { _voices[voice].age = 0; - if ((channel == 9) && _rhythmKeyMap) { + if (channel == 9 && _rhythmKeyMap) { patch = CLIP(note, 27, 88) + 101; } else { patch = _channels[channel].patch; @@ -616,7 +617,7 @@ void MidiDriver_AdLib::setNote(int voice, int note, bool key) { float delta; int bend = _channels[channel].pitchWheel; - if ((channel == 9) && _rhythmKeyMap) { + if (channel == 9 && _rhythmKeyMap) { note = _rhythmKeyMap[CLIP(note, 27, 88) - 27]; } @@ -756,30 +757,32 @@ void MidiDriver_AdLib::playSwitch(bool play) { renewNotes(-1, play); } -bool MidiDriver_AdLib::loadResource(const byte *data, uint size) { - if ((size != 1344) && (size != 2690) && (size != 5382)) { - error("ADLIB: Unsupported patch format (%i bytes)", size); +bool MidiDriver_AdLib::loadResource(const SciSpan<const byte> &data) { + const uint32 size = data.size(); + if (size != 1344 && size != 2690 && size != 5382) { + error("ADLIB: Unsupported patch format (%u bytes)", size); return false; } for (int i = 0; i < 48; i++) - loadInstrument(data + (28 * i)); + loadInstrument(data.subspan(28 * i)); if (size == 1344) { byte dummy[28] = {0}; // Only 48 instruments, add dummies for (int i = 0; i < 48; i++) - loadInstrument(dummy); + loadInstrument(SciSpan<const byte>(dummy, sizeof(dummy))); } else if (size == 2690) { for (int i = 48; i < 96; i++) - loadInstrument(data + 2 + (28 * i)); + loadInstrument(data.subspan(2 + (28 * i))); } else { // SCI1.1 and later - for (int i = 48; i < 190; i++) - loadInstrument(data + (28 * i)); - _rhythmKeyMap = new byte[kRhythmKeys]; - memcpy(_rhythmKeyMap, data + 5320, kRhythmKeys); + for (int i = 48; i < 190; i++) { + loadInstrument(data.subspan(28 * i)); + } + + _rhythmKeyMap->allocateFromSpan(data.subspan(5320, kRhythmKeys)); } return true; @@ -802,11 +805,11 @@ int MidiPlayer_AdLib::open(ResourceManager *resMan) { assert(resMan != NULL); // Load up the patch.003 file, parse out the instruments - Resource *res = resMan->findResource(ResourceId(kResourceTypePatch, 3), 0); + Resource *res = resMan->findResource(ResourceId(kResourceTypePatch, 3), false); bool ok = false; if (res) { - ok = static_cast<MidiDriver_AdLib *>(_driver)->loadResource(res->data, res->size); + ok = static_cast<MidiDriver_AdLib *>(_driver)->loadResource(*res); } else { // Early SCI0 games have the sound bank embedded in the AdLib driver @@ -819,13 +822,13 @@ int MidiPlayer_AdLib::open(ResourceManager *resMan) { // Note: Funseeker's Guide also has another version of adl.drv, 8803 bytes. // This isn't supported, but it's not really used anywhere, as that demo // doesn't have sound anyway. - if ((size == 5684) || (size == 5720) || (size == 5727)) { - byte *buf = new byte[patchSize]; - - if (f.seek(0x45a) && (f.read(buf, patchSize) == patchSize)) - ok = static_cast<MidiDriver_AdLib *>(_driver)->loadResource(buf, patchSize); - - delete[] buf; + if (size == 5684 || size == 5720 || size == 5727) { + ok = f.seek(0x45a); + if (ok) { + Common::SpanOwner<SciSpan<const byte> > patchData; + patchData->allocateFromStream(f, patchSize); + ok = static_cast<MidiDriver_AdLib *>(_driver)->loadResource(*patchData); + } } } } |