aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound/drivers/adlib.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sound/drivers/adlib.cpp')
-rw-r--r--engines/sci/sound/drivers/adlib.cpp61
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);
+ }
}
}
}