aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/tsage/sound.cpp288
-rw-r--r--engines/tsage/sound.h46
2 files changed, 123 insertions, 211 deletions
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index 01e770a77a..7f454bf801 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -126,7 +126,10 @@ Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
assert(__sndmgrReady);
_availableDrivers.clear();
- // Build up a list of available drivers. Currently we only implement an Adlib driver
+ // Build up a list of available drivers. Currently we only implement an Adlib music
+ // and SoundBlaster FX driver
+
+ // Adlib driver
SoundDriverEntry sd;
sd.driverNum = ADLIB_DRIVER_NUM;
sd.status = detectFlag ? SNDSTATUS_DETECTED : SNDSTATUS_SKIPPED;
@@ -136,12 +139,23 @@ Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
sd.longDescription = "3812fm";
_availableDrivers.push_back(sd);
+ // SoundBlaster entry
+ SoundDriverEntry sdFx;
+ sdFx.driverNum = SBLASTER_DRIVER_NUM;
+ sdFx.status = detectFlag ? SNDSTATUS_DETECTED : SNDSTATUS_SKIPPED;
+ sdFx.field2 = 0;
+ sdFx.field6 = 15000;
+ sdFx.shortDescription = "SndBlast";
+ sdFx.longDescription = "SoundBlaster";
+ _availableDrivers.push_back(sdFx);
+
_driversDetected = true;
return _availableDrivers;
}
void SoundManager::installConfigDrivers() {
installDriver(ADLIB_DRIVER_NUM);
+ installDriver(SBLASTER_DRIVER_NUM);
}
Common::List<SoundDriverEntry> &SoundManager::getDriverList(bool detectFlag) {
@@ -2125,7 +2139,7 @@ void Sound::_soProc32(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voice
vtStruct->_entries[entryIndex]._type1._field4 = v0;
vtStruct->_entries[entryIndex]._type1._field5 = 0;
- driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, _chProgram[channelNum], v0, v1);
+ driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, _chProgram[channelNum], v0, v1);
}
}
@@ -2143,8 +2157,9 @@ void Sound::_soProc42(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voice
vtStruct->_entries[entryIndex]._type1._field4 = v0;
vtStruct->_entries[entryIndex]._type1._field5 = 0;
- driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, -1, v0, 0x7F);
- driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, voiceType, 0);
+ int v1, v2;
+ driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, -1, v0, 0x7F);
+ driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, voiceType, 0, &v1, &v2);
}
break;
}
@@ -2271,11 +2286,33 @@ void Sound::_soServiceTrackType1(int trackIndex, const byte *channelData) {
vtStruct->_entries[entryIndex]._type1._field4 = *(channelData + 1);
vtStruct->_entries[entryIndex]._type1._field5 = 0;
- driver->proc32(vtStruct->_entries[entryIndex]._voiceNum, -1, *(channelData + 1), 0x7f);
+ int v1, v2;
+ driver->proc32(this, vtStruct->_entries[entryIndex]._voiceNum, -1, *(channelData + 1), 0x7f);
+ driver->proc42(vtStruct->_entries[entryIndex]._voiceNum, *(channelData + 1), _loop ? 1 : 0,
+ &v1, &v2);
}
} else {
+ int channel = 0; // Is this correct?!
+ for (uint entryIndex = 0; entryIndex < vtStruct->_entries.size(); ++entryIndex) {
+ VoiceStructEntry &vte = vtStruct->_entries[entryIndex];
+ VoiceStructEntryType1 &vse = vte._type1;
+ if ((vse._sound == this) && (vse._channelNum == channel) && (vse._field4 == vtStruct->_total)) {
+ SoundDriver *driver = vte._driver;
+
+ int v1, v2;
+ driver->proc42(vte._voiceNum, vtStruct->_total, _loop ? 1 : 0, &v1, &v2);
+ if (v2) {
+ _trkState[trackIndex] = 0;
+ } else if (vtStruct->_total) {
+ _timer = 0;
+ }
+ }
+ }
+ _trkState[trackIndex] = 0;
}
+ } else {
+ _trkState[trackIndex] = 0;
}
}
}
@@ -2511,7 +2548,7 @@ int AdlibSoundDriver::setMasterVolume(int volume) {
return oldVolume;
}
-void AdlibSoundDriver::proc32(int channel, int program, int v0, int v1) {
+void AdlibSoundDriver::proc32(Sound *sound, int channel, int program, int v0, int v1) {
if (program == -1)
return;
@@ -2735,7 +2772,7 @@ AdlibFxSoundDriver::AdlibFxSoundDriver(): SoundDriver() {
_maxVersion = 0x10A;
_masterVolume = 0;
- _groupData.groupMask = 9;
+ _groupData.groupMask = 1;
_groupData.v1 = 0x3E;
_groupData.v2 = 0;
_groupData.pData = &adlib_group_data[0];
@@ -2765,31 +2802,25 @@ AdlibFxSoundDriver::~AdlibFxSoundDriver() {
}
bool AdlibFxSoundDriver::open() {
+ write209();
+ write(64);
+ write(165);
+ // for (int idx = 0; idx < 5000 * 16; ++idx) al = port[21h]
- write(1, 0x20);
- if (!reset())
- return false;
+// _v45071 = 1;
+// _v4506F = 0;
- write(8, 0);
- for (int idx = 0x20; idx < 0xF6; ++idx)
- write(idx, 0);
-
- write(0xBD, 0);
return true;
}
void AdlibFxSoundDriver::close() {
- for (int idx = 0xB0; idx < 0xB8; ++idx)
- write(idx, _portContents[idx] & 0xDF);
- for (int idx = 0x40; idx < 0x55; ++idx)
- write(idx, 0x3F);
- reset();
+ write(208);
+ write211();
+
}
bool AdlibFxSoundDriver::reset() {
- write(1, 0x20);
- write(1, 0x20);
return true;
}
@@ -2798,77 +2829,72 @@ const GroupData *AdlibFxSoundDriver::getGroupData() {
return &_groupData;
}
+void AdlibFxSoundDriver::poll() {
+ if (!_masterVolume || !_channelVolume) {
+ if (_v45046)
+ write211();
+ } else {
+ if (!_v45046)
+ write209();
+ }
+}
+
int AdlibFxSoundDriver::setMasterVolume(int volume) {
int oldVolume = _masterVolume;
_masterVolume = volume;
- for (int channelNum = 0; channelNum < ADLIB_CHANNEL_COUNT; ++channelNum)
- updateChannelVolume(channelNum);
-
return oldVolume;
}
-void AdlibFxSoundDriver::proc32(int channel, int program, int v0, int v1) {
+void AdlibFxSoundDriver::proc32(Sound *sound, int channel, int program, int v0, int v1) {
if (program == -1)
return;
-/*
- int offset = READ_LE_UINT16(_patchData + program * 2);
- if (offset) {
- const byte *dataP = _patchData + offset;
- int id;
-
- for (offset = 2, id = 0; id != READ_LE_UINT16(dataP); offset += 30, ++id) {
- if ((dataP[offset] <= v0) && (dataP[offset + 1] >= v0)) {
- if (dataP[offset + 2] != 0xff)
- v0 = dataP[offset + 2];
- _v4409E[channel] = dataP + offset - _patchData;
+ if (_sound)
+ updateVoice(channel);
- // Set sustain/release
- int portNum = v440C2[v440B0[channel]] + 0x80;
- write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
+ // TODO: Stuff
- portNum = v440C2[v440B9[channel]] + 0x80;
- write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
- if (_channelVoiced[channel])
- clearVoice(channel);
- _v44067[channel] = v0;
- _v4405E[channel] = v1;
-
- updateChannel(channel);
- setFrequency(channel);
- updateChannelVolume(channel);
- setVoice(channel);
- break;
- }
- }
- }
- */
}
void AdlibFxSoundDriver::updateVoice(int channel) {
- if (_channelVoiced[channel])
- clearVoice(channel);
+ if (_sound) {
+ write(208);
+
+ _sound = NULL;
+ _v45062 = 0;
+ _v45066 = 0;
+ _v45068 = 0;
+ }
}
void AdlibFxSoundDriver::proc38(int channel, int cmd, int value) {
if (cmd == 7) {
// Set channel volume
- _channelVolume[channel] = value;
- updateChannelVolume(channel);
+ _channelVolume = value;
}
}
-void AdlibFxSoundDriver::setPitch(int channel, int pitchBlend) {
- _pitchBlend[channel] = pitchBlend;
- setFrequency(channel);
+void AdlibFxSoundDriver::proc42(int channel, int cmd, int value, int *v1, int *v2) {
+ _v4506A = value;
+ *v1 = _v4506B;
+ *v2 = 0;
+ _v4506B = 0;
+
+ if (!_sound)
+ *v2 = 1;
}
-void AdlibFxSoundDriver::write(byte reg, byte value) {
- _portContents[reg] = value;
- _queue.push(RegisterValue(reg, value));
+void AdlibFxSoundDriver::write(int v) {
+ /*
+ port[adlib_port + 12] = v;
+ for (int i = 0; i < 100; ++i) {
+ if (!port[adlib_port + 12] & 0x80)
+ break;
+ }
+ */
}
void AdlibFxSoundDriver::flush() {
@@ -2880,127 +2906,7 @@ void AdlibFxSoundDriver::flush() {
}
}
-void AdlibFxSoundDriver::updateChannelVolume(int channelNum) {
- int volume = (_masterVolume * _channelVolume[channelNum] / 127 * _v4405E[channelNum] / 127) / 2;
- int level2 = 63 - v44134[volume * _v44079[channelNum] / 63];
- int level1 = !_v44082[channelNum] ? 63 - _v44070[channelNum] :
- 63 - v44134[volume * _v44070[channelNum] / 63];
-
- int portNum = v440C2[v440B0[channelNum]] + 0x40;
- write(portNum, (_portContents[portNum] & 0x80) | level1);
-
- portNum = v440C2[v440B9[channelNum]] + 0x40;
- write(portNum, (_portContents[portNum] & 0x80) | level2);
-}
-
-void AdlibFxSoundDriver::setVoice(int channel) {
- int portNum = 0xB0 + channel;
- write(portNum, _portContents[portNum] | 0x20);
- _channelVoiced[channel] = true;
-}
-
-void AdlibFxSoundDriver::clearVoice(int channel) {
- write(0xB0 + channel, _portContents[0xB0 + channel] & ~0x20);
- _channelVoiced[channel] = false;
-}
-
-void AdlibFxSoundDriver::updateChannel(int channel) {
-/*
- const byte *dataP = _patchData + _v4409E[channel];
- int portOffset = v440C2[v440B0[channel]];
-
- int portNum = portOffset + 0x20;
- int portValue = 0;
- if (*(dataP + 4))
- portValue |= 0x80;
- if (*(dataP + 5))
- portValue |= 0x40;
- if (*(dataP + 8))
- portValue |= 0x20;
- if (*(dataP + 6))
- portValue |= 0x10;
- portValue |= *(dataP + 7);
- write(portNum, portValue);
-
- portValue = (_portContents[0x40 + portOffset] & 0x3F) | (*(dataP + 9) << 6);
- write(0x40 + portOffset, portValue);
-
- _v44070[channel] = 63 - *(dataP + 10);
- write(0x60 + portOffset, *(dataP + 12) | (*(dataP + 11) << 4));
- write(0x80 + portOffset, *(dataP + 14) | (*(dataP + 13) << 4));
- write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 15));
-
- portOffset = v440C2[v440B9[channel]];
- portNum = portOffset + 0x20;
- portValue = 0;
- if (*(dataP + 17))
- portValue |= 0x80;
- if (*(dataP + 18))
- portValue |= 0x40;
- if (*(dataP + 21))
- portValue |= 0x20;
- if (*(dataP + 19))
- portValue |= 0x10;
- portValue |= *(dataP + 20);
- write(portNum, portValue);
-
- write(0x40 + portOffset, (_portContents[0x40 + portOffset] & 0x3f) | (*(dataP + 22) << 6));
- _v44079[channel] = 0x3F - *(dataP + 23);
- write(0x60 + portOffset, *(dataP + 25) | (*(dataP + 24) << 4));
- write(0x80 + portOffset, *(dataP + 27) | (*(dataP + 26) << 4));
- write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 28));
-
- write(0xC0 + channel, (_portContents[0xC0 + channel] & 0xF0)
- | (*(dataP + 16) << 1) | *(dataP + 3));
-
- _v44082[channel] = *(dataP + 3);
- */
-}
-
-void AdlibFxSoundDriver::setFrequency(int channel) {
- int offset, ch;
-
- int v = _pitchBlend[channel];
- if (v == 0x2000) {
- offset = 0;
- ch = _v44067[channel];
- } else if (v > 0x2000) {
- ch = _v44067[channel];
- v -= 0x2000;
- if (v == 0x1fff)
- v = 0x2000;
-
- offset = (v / 170) & 3;
- ch += (v / 170) >> 2;
-
- if (ch >= 128)
- ch = 127;
- } else {
- ch = _v44067[channel];
- int tempVal = (0x2000 - v) / 170;
- int tempVal2 = 4 - (tempVal & 3);
-
- if (tempVal2 == 4)
- offset = 0;
- else {
- offset = tempVal2;
- --ch;
- }
-
- ch -= tempVal >> 2;
- if (ch < 0)
- ch = 0;
- }
-
- int var2 = ch / 12;
- if (var2)
- --var2;
- int dataWord = v440D4[((ch % 12) << 2) + offset];
- write(0xA0 + channel, dataWord & 0xff);
- write(0xB0 + channel, (_portContents[0xB0 + channel] & 0xE0) |
- ((dataWord >> 8) & 3) | (var2 << 2));
-}
int AdlibFxSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
update(buffer, numSamples);
@@ -3025,4 +2931,14 @@ void AdlibFxSoundDriver::update(int16 *buf, int len) {
}
}
+void AdlibFxSoundDriver::write209() {
+ write(209);
+ _v45046 = true;
+}
+
+void AdlibFxSoundDriver::write211() {
+ write(211);
+ _v45046 = false;
+}
+
} // End of namespace tSage
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 27f30b9b08..26bf3e6d33 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -40,6 +40,7 @@ class Sound;
#define SOUND_ARR_SIZE 16
#define ROLAND_DRIVER_NUM 2
#define ADLIB_DRIVER_NUM 3
+#define SBLASTER_DRIVER_NUM 4
struct trackInfoStruct {
int _numTracks;
@@ -106,12 +107,12 @@ public:
virtual void setProgram(int channel, int program) {} // Method #13
virtual void setVolume1(int channel, int v2, int v3, int volume) {}
virtual void setPitchBlend(int channel, int pitchBlend) {} // Method #15
- virtual void proc32(int channel, int program, int v0, int v1) {}// Method #16
+ virtual void proc32(Sound *sound, int channel, int program, int v0, int v1) {}// Method #16
virtual void updateVoice(int channel) {} // Method #17
virtual void proc36() {} // Method #18
virtual void proc38(int channel, int cmd, int value) {} // Method #19
virtual void setPitch(int channel, int pitchBlend) {} // Method #20
- virtual void proc42(int channel, int v0, int v1) {} // Method #21
+ virtual void proc42(int channel, int cmd, int value, int *v1, int *v2) {} // Method #21
};
struct VoiceStructEntryType0 {
@@ -439,7 +440,7 @@ public:
virtual const GroupData *getGroupData();
virtual void installPatch(const byte *data, int size);
virtual int setMasterVolume(int volume);
- virtual void proc32(int channel, int program, int v0, int v1);
+ virtual void proc32(Sound *sound, int channel, int program, int v0, int v1);
virtual void updateVoice(int channel);
virtual void proc38(int channel, int cmd, int value);
virtual void setPitch(int channel, int pitchBlend);
@@ -455,33 +456,28 @@ public:
class AdlibFxSoundDriver: public SoundDriver, Audio::AudioStream {
private:
+ Common::Queue<RegisterValue> _queue;
GroupData _groupData;
Audio::Mixer *_mixer;
FM_OPL *_opl;
Audio::SoundHandle _soundHandle;
int _sampleRate;
- byte _portContents[256];
- int _masterVolume;
- Common::Queue<RegisterValue> _queue;
-
- bool _channelVoiced[ADLIB_CHANNEL_COUNT];
- int _channelVolume[ADLIB_CHANNEL_COUNT];
- int _v4405E[ADLIB_CHANNEL_COUNT];
- int _v44067[ADLIB_CHANNEL_COUNT];
- int _v44070[ADLIB_CHANNEL_COUNT];
- int _v44079[ADLIB_CHANNEL_COUNT];
- int _v44082[ADLIB_CHANNEL_COUNT + 1];
- int _pitchBlend[ADLIB_CHANNEL_COUNT];
- int _v4409E[ADLIB_CHANNEL_COUNT];
+ int _v45062;
+ int _v45066;
+ int _v45068;
+ int _v4506A;
+ int _v4506B;
+ bool _v45046;
+ byte _masterVolume;
+ byte _channelVolume;
+ Sound *_sound;
- void write(byte reg, byte value);
+ void write(int v);
void flush();
- void updateChannelVolume(int channel);
- void setVoice(int channel);
- void clearVoice(int channel);
- void updateChannel(int channel);
- void setFrequency(int channel);
+ void sub_4556E();
+ void write209();
+ void write211();
public:
AdlibFxSoundDriver();
virtual ~AdlibFxSoundDriver();
@@ -490,12 +486,12 @@ public:
virtual void close();
virtual bool reset();
virtual const GroupData *getGroupData();
- virtual void installPatch(const byte *data, int size) {}
+ virtual void poll();
virtual int setMasterVolume(int volume);
- virtual void proc32(int channel, int program, int v0, int v1);
+ virtual void proc32(Sound *sound, int channel, int program, int v0, int v1);
virtual void updateVoice(int channel);
virtual void proc38(int channel, int cmd, int value);
- virtual void setPitch(int channel, int pitchBlend);
+ virtual void proc42(int channel, int cmd, int value, int *v1, int *v2);
// AudioStream interface
virtual int readBuffer(int16 *buffer, const int numSamples);