aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/dm/dm.cpp2
-rw-r--r--engines/dm/dm.h29
-rw-r--r--engines/dm/sounds.cpp123
3 files changed, 134 insertions, 20 deletions
diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp
index e825ead2c2..0381f34067 100644
--- a/engines/dm/dm.cpp
+++ b/engines/dm/dm.cpp
@@ -396,7 +396,7 @@ void DMEngine::f2_gameloop() {
}
}
// F0363_COMMAND_HighlightBoxDisable();
- // F0065_SOUND_PlayPendingSound_CPSD();
+ f65_playPendingSound();
_championMan->f320_applyAndDrawPendingDamageAndWounds();
if (_championMan->_g303_partyDead)
break;
diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 02def018d1..1c187020f1 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -205,7 +205,25 @@ public:
SoundData(): _byteCount(0), _firstSample(nullptr), _sampleCount(0) {}
}; // @ SOUND_DATA
-
+class Sound {
+public:
+ int16 _graphicIndex;
+ byte _period;
+ byte _priority;
+ byte _loudDistance;
+ byte _softDistance;
+ Sound(int16 index, byte period, byte priority, byte loudDist, byte softDist) :
+ _graphicIndex(index), _period(period), _priority(priority), _loudDistance(loudDist), _softDistance(softDist) {}
+}; // @ Sound
+
+class PendingSound {
+public:
+ uint8 _leftVolume;
+ uint8 _rightVolume;
+ int16 _soundIndex;
+ PendingSound(uint8 leftVolume, uint8 rightVolume, int16 soundIndex):
+ _leftVolume(leftVolume), _rightVolume(rightVolume), _soundIndex(soundIndex) {}
+};
class DMEngine : public Engine {
void f462_startGame(); // @ F0462_START_StartGame_CPSF
@@ -236,9 +254,11 @@ public:
void f441_processEntrance(); // @ F0441_STARTEND_ProcessEntrance
void f444_endGame(bool doNotDrawCreditsOnly); // @ F0444_STARTEND_Endgame
- void f064_SOUND_RequestPlay_CPSD(uint16 P0088_ui_SoundIndex, int16 P0089_i_MapX, int16 P0090_i_MapY, uint16 P0091_ui_Mode) { warning(true, "STUB: f064_SOUND_RequestPlay_CPSD"); }
- void f060_SOUND_Play(uint16 P0921_ui_SoundIndex, uint16 P0085_i_Period, uint8 leftVol, uint8 rightVol);
- void f438_STARTEND_OpenEntranceDoors() { warning(true, "STUB: f438_STARTEND_OpenEntranceDoors"); }
+ void f064_SOUND_RequestPlay_CPSD(uint16 P0088_ui_SoundIndex, int16 P0089_i_MapX, int16 P0090_i_MapY, uint16 P0091_ui_Mode); // @ F0064_SOUND_RequestPlay_CPSD
+ void f060_SOUND_Play(uint16 P0921_ui_SoundIndex, uint16 P0085_i_Period, uint8 leftVol, uint8 rightVol); // @ F0060_SOUND_Play
+ void f65_playPendingSound(); // @ F0065_SOUND_PlayPendingSound_CPSD
+ bool f505_soundGetVolume(int16 mapX, int16 mapY, uint8 *leftVolume, uint8 *rightVolume); // @ F0505_SOUND_GetVolume
+ void f438_STARTEND_OpenEntranceDoors() { warning(true, "STUB: f438_STARTEND_OpenEntranceDoors"); } // @ F0438_STARTEND_OpenEntranceDoors
private:
int16 _g528_saveFormat; // @ G0528_i_Format
@@ -249,6 +269,7 @@ private:
byte *_g564_interfaceCredits; // @ G0564_puc_Graphic5_InterfaceCredits
Common::RandomSource *_rnd;
SoundData _gK24_soundData[k34_D13_soundCount]; // @ K0024_as_SoundData
+ Common::Queue<PendingSound> _pendingSounds;
public:
DisplayMan *_displayMan;
DungeonMan *_dungeonMan;
diff --git a/engines/dm/sounds.cpp b/engines/dm/sounds.cpp
index cdbed462a3..b44e97b2bf 100644
--- a/engines/dm/sounds.cpp
+++ b/engines/dm/sounds.cpp
@@ -31,23 +31,15 @@
#include "dm.h"
#include "gfx.h"
#include <audio/mixer.h>
+#include "timeline.h"
+#include "dungeonman.h"
namespace DM {
-class Sound {
-public:
- int16 _graphicIndex;
- byte _period;
- byte _priority;
- byte _loudDistance;
- byte _softDistance;
- Sound(int16 index, byte period, byte priority, byte loudDist, byte softDist) :
- _graphicIndex(index), _period(period), _priority(priority), _loudDistance(loudDist), _softDistance(softDist) {}
-}; // @ Sound
-Sound G0060_as_Graphic562_Sounds[k34_D13_soundCount] = {
+Sound g60_sounds[k34_D13_soundCount] = {
Sound(533, 112, 11, 3, 6), /* k00_soundMETALLIC_THUD 0 */
Sound(534, 112, 15, 0, 3), /* k01_soundSWITCH 1 */
Sound(535, 112, 72, 3, 6), /* k02_soundDOOR_RATTLE 2 */
@@ -87,7 +79,7 @@ void DMEngine::f503_loadSounds() {
for (uint16 soundIndex = 0; soundIndex < k34_D13_soundCount; ++soundIndex) {
SoundData *soundData = _gK24_soundData + soundIndex;
- uint16 graphicIndex = G0060_as_Graphic562_Sounds[soundIndex]._graphicIndex;
+ uint16 graphicIndex = g60_sounds[soundIndex]._graphicIndex;
soundData->_byteCount = _displayMan->getCompressedDataSize(graphicIndex) - 2; // the header is 2 bytes long
soundData->_firstSample = new byte[soundData->_byteCount];
@@ -98,14 +90,115 @@ void DMEngine::f503_loadSounds() {
}
void DMEngine::f060_SOUND_Play(uint16 soundIndex, uint16 period, uint8 leftVolume, uint8 rightVolume) {
- byte soundFlags = Audio::FLAG_STEREO;
SoundData *sound = &_gK24_soundData[soundIndex];
- Audio::AudioStream *stream = Audio::makeRawStream(sound->_firstSample, sound->_byteCount, 72800 / period, soundFlags, DisposeAfterUse::NO);
+ Audio::AudioStream *stream = Audio::makeRawStream(sound->_firstSample, sound->_byteCount, (72800 / period) * 8, 0, DisposeAfterUse::NO);
signed char balance = ((int16)rightVolume - (int16)leftVolume) / 2;
Audio::SoundHandle handle;
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, stream, - 1, 127, balance);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, stream, -1, 127, balance);
+}
+
+void DMEngine::f65_playPendingSound() {
+ while (!_pendingSounds.empty()) {
+ PendingSound pendingSound = _pendingSounds.pop();
+ f060_SOUND_Play(pendingSound._soundIndex, g60_sounds[pendingSound._soundIndex]._period, pendingSound._leftVolume, pendingSound._rightVolume);
+ }
+}
+
+bool DMEngine::f505_soundGetVolume(int16 mapX, int16 mapY, uint8* leftVolume, uint8* rightVolume) {
+ static byte K0030_aauc_DistanceToSoundVolume[25][25] = {
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 6, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 6, 10, 10, 10, 9, 8, 8, 7, 7, 6, 6, 5, 5, 5},
+ {1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 7, 12, 12, 11, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5},
+ {1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 7, 15, 14, 13, 12, 11, 9, 8, 8, 7, 6, 6, 5, 5},
+ {1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 8, 20, 19, 16, 14, 12, 10, 9, 8, 7, 7, 6, 6, 5},
+ {1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 8, 29, 26, 21, 16, 13, 11, 10, 8, 7, 7, 6, 6, 5},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 8, 58, 41, 26, 19, 14, 12, 10, 9, 8, 7, 6, 6, 5},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 6, 64, 58, 29, 20, 15, 12, 10, 9, 8, 7, 6, 6, 5},
+ {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 6, 41, 29, 19, 13, 10, 8, 7, 6, 6, 5, 5, 4, 4},
+ {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 6, 21, 19, 15, 12, 10, 8, 7, 6, 5, 5, 4, 4, 4},
+ {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 6, 14, 13, 12, 10, 9, 7, 7, 6, 5, 5, 4, 4, 4},
+ {0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 5, 11, 10, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4},
+ {0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4},
+ {0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 5, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4},
+ {0, 1, 1, 1, 1, 1, 1, 2, 2, 1, 3, 4, 6, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3}};
+
+ int16 L1678_i_RightVolumeColumnIndex = 0;
+ int16 L1679_i_LineIndex = 0;
+ int16 L1680_i_LeftVolumeColumnIndex = 0;
+
+
+ switch (_dungeonMan->_g308_partyDir) {
+ case kDirNorth:
+ L1678_i_RightVolumeColumnIndex = mapX - _dungeonMan->_g306_partyMapX;
+ L1679_i_LineIndex = mapY - _dungeonMan->_g307_partyMapY;
+ break;
+ case kDirEast:
+ L1678_i_RightVolumeColumnIndex = mapY - _dungeonMan->_g307_partyMapY;
+ L1679_i_LineIndex = -(mapX - _dungeonMan->_g306_partyMapX);
+ break;
+ case kDirSouth:
+ L1678_i_RightVolumeColumnIndex = -(mapX - _dungeonMan->_g306_partyMapX);
+ L1679_i_LineIndex = -(mapY - _dungeonMan->_g307_partyMapY);
+ break;
+ case kDirWest:
+ L1678_i_RightVolumeColumnIndex = -(mapY - _dungeonMan->_g307_partyMapY);
+ L1679_i_LineIndex = mapX - _dungeonMan->_g306_partyMapX;
+ break;
+ }
+ if ((L1678_i_RightVolumeColumnIndex < -12) || (L1678_i_RightVolumeColumnIndex > 12)) { /* Sound is not audible if source is more than 12 squares away from the party */
+ return false;
+ }
+ if ((L1679_i_LineIndex < -12) || (L1679_i_LineIndex > 12)) { /* Sound is not audible if source is more than 12 squares away from the party */
+ return false;
+ }
+ L1680_i_LeftVolumeColumnIndex = -L1678_i_RightVolumeColumnIndex + 12;
+ L1678_i_RightVolumeColumnIndex += 12;
+ L1679_i_LineIndex += 12;
+ *rightVolume = K0030_aauc_DistanceToSoundVolume[L1679_i_LineIndex][L1678_i_RightVolumeColumnIndex];
+ *leftVolume = K0030_aauc_DistanceToSoundVolume[L1679_i_LineIndex][L1680_i_LeftVolumeColumnIndex];
+ return true;
+}
+
+void DMEngine::f064_SOUND_RequestPlay_CPSD(uint16 soundIndex, int16 mapX, int16 mapY, uint16 mode) {
+ Sound* sound;
+ uint8 leftVolume, rightVolume;
+
+ if (mode && (_dungeonMan->_g272_currMapIndex != _dungeonMan->_g309_partyMapIndex))
+ return;
+
+ sound = &g60_sounds[soundIndex];
+ if (mode > k1_soundModePlayIfPrioritized) { /* Add an event in the timeline to play the sound (mode - 1) ticks later */
+ TimelineEvent event;
+ M33_setMapAndTime(event._mapTime, _dungeonMan->_g272_currMapIndex, _g313_gameTime + mode - 1);
+ event._type = k20_TMEventTypePlaySound;
+ event._priority = sound->_priority;
+ event._C._soundIndex = soundIndex;
+ event._B._location._mapX = mapX;
+ event._B._location._mapY = mapY;
+ _timeline->f238_addEventGetEventIndex(&event);
+ return;
+ }
+
+ if (!f505_soundGetVolume(mapX, mapY, &leftVolume, &rightVolume)) {
+ return;
+ }
+ if (!mode) { /* Play the sound immediately */
+ f060_SOUND_Play(soundIndex, sound->_period, leftVolume, rightVolume);
+ return;
+ }
+ _pendingSounds.push(PendingSound(leftVolume, rightVolume, soundIndex));
}
}