aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorRetro-Junk2016-10-22 14:15:45 +0300
committerEugene Sandulenko2017-01-25 22:42:02 +0100
commit7e92fb079021081eb28c2d284f1b81b8f5b7dab2 (patch)
treeed8ba6e87598af3f03ee28bb3ae3ba88a125bab0 /engines
parent5616897f2a8480141b8ac2adb656a7e1ca45c95c (diff)
downloadscummvm-rg350-7e92fb079021081eb28c2d284f1b81b8f5b7dab2.tar.gz
scummvm-rg350-7e92fb079021081eb28c2d284f1b81b8f5b7dab2.tar.bz2
scummvm-rg350-7e92fb079021081eb28c2d284f1b81b8f5b7dab2.zip
CRYO: Add sound playback
Diffstat (limited to 'engines')
-rw-r--r--engines/cryo/bugs.txt4
-rw-r--r--engines/cryo/eden.cpp81
-rw-r--r--engines/cryo/eden.h6
-rw-r--r--engines/cryo/sound.cpp71
-rw-r--r--engines/cryo/sound.h41
5 files changed, 158 insertions, 45 deletions
diff --git a/engines/cryo/bugs.txt b/engines/cryo/bugs.txt
index ca410c2533..ec3c4b58e0 100644
--- a/engines/cryo/bugs.txt
+++ b/engines/cryo/bugs.txt
@@ -14,3 +14,7 @@ C. PC cursor clipped too agressively
D. PC logos and credits videos won't play because encoded in old HNM format
E. Eye blinking works incorrectly?
F. Bogus hitbox in upper right corner of mirror screen (under mini-map)
+G. Wrong frescoes cursor on PC
+H. No Eloi comment after getting flute on PC?
+I. Junk on a valley entrance screen on PC
+J. Move right cursor on PC rotates in wrong direction
diff --git a/engines/cryo/eden.cpp b/engines/cryo/eden.cpp
index ca2d162719..1d28279843 100644
--- a/engines/cryo/eden.cpp
+++ b/engines/cryo/eden.cpp
@@ -44,6 +44,7 @@
#include "cryo/platdefs.h"
#include "cryo/cryolib.h"
#include "cryo/eden.h"
+#include "cryo/sound.h"
namespace Cryo {
@@ -109,7 +110,8 @@ EdenGame::EdenGame() {
bufferAllocationErrorFl = quit_flag2 = quit_flag3 = false;
gameStarted = false;
_soundAllocated = false;
- _musicChannel = hnmsound_ch = nullptr;
+ _musicChannel = _voiceChannel = nullptr;
+ hnmsound_ch = nullptr;
voiceSound = nullptr;
p_view2 = p_underSubtitlesView = p_subtitlesview = p_underBarsView = p_mainview = p_hnmview = nullptr;
_hnmContext = nullptr;
@@ -131,7 +133,7 @@ EdenGame::EdenGame() {
_musicFadeFlag = 0;
musicPlaying = 0;
mus_samples_ptr = mus_patterns_ptr = mus_sequence_ptr = nullptr;
- mus_queue_grp = nullptr;
+ mus_enabled = false;
pCurrentObjectLocation = nullptr;
byte_31D64 = false;
no_palette = 0;
@@ -5629,9 +5631,11 @@ void EdenGame::run() {
CLHNM_SetupTimer(12.5);
voiceSound = CLSoundRaw_New(0, 11025 * 65536.0, 8, 0);
hnmsound_ch = CLHNM_GetSoundChannel();
- _musicChannel = CLSoundChannel_New(0);
CLSound_SetWantsDesigned(1);
+ _musicChannel = new CSoundChannel(g_ed->_mixer, 11025, false);
+ _voiceChannel = new CSoundChannel(g_ed->_mixer, 11025, false);
+
allocateBuffers();
openbigfile();
openwindow();
@@ -5665,14 +5669,16 @@ void EdenGame::run() {
gameLoaded = 0;
}
fademusica0(2);
- CLSoundChannel_Stop(_musicChannel);
- CLSoundGroup_Free(mus_queue_grp);
+ _musicChannel->stop();
musicPlaying = 0;
- mus_queue_grp = 0;
+ mus_enabled = false;
}
// LostEdenMac_SavePrefs();
}
+ delete _voiceChannel;
+ delete _musicChannel;
+
fadetoblack(4);
closebigfile();
freebuf();
@@ -5696,10 +5702,9 @@ void EdenGame::edmain() {
fadetoblack(3);
CLBlitter_FillScreenView(0);
CLBlitter_FillView(p_mainview, 0);
- CLSoundChannel_Stop(_musicChannel);
- CLSoundGroup_Free(mus_queue_grp);
+ _musicChannel->stop();
musicPlaying = 0;
- mus_queue_grp = 0;
+ mus_enabled = false;
intro();
entergame();
}
@@ -6346,7 +6351,7 @@ void EdenGame::playHNM(int16 num) {
oldDialogType = p_global->dialogType;
prechargephrases(num);
fademusica0(1);
- CLSoundChannel_Stop(_musicChannel);
+ _musicChannel->stop();
}
showVideoSubtitle = 0;
videoCanceled = 0;
@@ -6468,8 +6473,7 @@ void EdenGame::startmusique(byte num) {
return;
if (musicPlaying) {
fademusica0(1);
- CLSoundChannel_Stop(_musicChannel);
- CLSoundGroup_Free(mus_queue_grp);
+ _musicChannel->stop();
}
loadmusicfile(num);
p_global->currentMusicNum = num;
@@ -6479,29 +6483,29 @@ void EdenGame::startmusique(byte num) {
pat_size = PLE16(music_buf + 27);
mus_samples_ptr = music_buf + 32 + 4 + pat_size;
freq = PLE16(mus_samples_ptr - 2);
- if (freq == 166)
- mus_queue_grp = CLSoundGroup_New(3, 0, 8, 7.225344e8, 0);
- else
- mus_queue_grp = CLSoundGroup_New(3, 0, 8, 1.4450688e9, 0);
+
+ delete _musicChannel;
+ _musicChannel = new CSoundChannel(g_ed->_mixer, freq == 166 ? 11025 : 22050, false);
+ mus_enabled = true;
+
musicSequencePos = 0;
mus_vol_left = p_global->pref_10C[0];
mus_vol_right = p_global->pref_10C[1];
- CLSoundChannel_SetVolumeLeft(_musicChannel, mus_vol_left);
- CLSoundChannel_SetVolumeRight(_musicChannel, mus_vol_right);
+ _musicChannel->setVolume(mus_vol_left, mus_vol_right);
}
void EdenGame::musicspy() {
byte patnum, *patptr;
int ofs, len;
- if (!mus_queue_grp)
+ if (!mus_enabled)
return;
mus_vol_left = p_global->pref_10C[0];
mus_vol_right = p_global->pref_10C[1];
if (_musicFadeFlag & 3)
fademusicup();
- if (_personTalking && !hnmsound_ch->_numSounds)
+ if (_personTalking && !_voiceChannel->numQueued())
_musicFadeFlag = 3;
- if (_musicChannel->_numSounds < 3) {
+ if (_musicChannel->numQueued() < 3) {
patnum = mus_sequence_ptr[(int)musicSequencePos];
if (patnum == 0xFF) {
// rewind
@@ -6512,8 +6516,7 @@ void EdenGame::musicspy() {
patptr = mus_patterns_ptr + patnum * 6;
ofs = patptr[0] + (patptr[1] << 8) + (patptr[2] << 16);
len = patptr[3] + (patptr[4] << 8) + (patptr[5] << 16);
- CLSoundGroup_AssignDatas(mus_queue_grp, mus_samples_ptr + ofs, len, 0);
- CLSoundGroup_PlayNextSample(mus_queue_grp, _musicChannel);
+ _musicChannel->queueBuffer(mus_samples_ptr + ofs, len);
musicPlaying = 1;
}
}
@@ -6539,25 +6542,18 @@ void EdenGame::persovox() {
voiceSamplesSize = ssndfl(num);
int16 volumeLeft = p_global->pref_110[0];
int16 volumeRight = p_global->pref_110[1];
- int16 stepLeft = -1;
- if (_musicChannel->_volumeLeft < volumeLeft)
- stepLeft = 1;
- int16 stepRight = -1;
- if (_musicChannel->_volumeRight < volumeRight)
- stepRight = 1;
+ int16 stepLeft = _musicChannel->_volumeLeft < volumeLeft ? stepLeft = 1 : -1;
+ int16 stepRight = _musicChannel->_volumeRight < volumeRight ? stepRight = 1 : -1;
do {
if (volumeLeft != _musicChannel->_volumeLeft)
- CLSoundChannel_SetVolumeLeft(_musicChannel, _musicChannel->_volumeLeft + stepLeft);
+ _musicChannel->setVolumeLeft(_musicChannel->_volumeLeft + stepLeft);
if (volumeRight != _musicChannel->_volumeRight)
- CLSoundChannel_SetVolumeRight(_musicChannel, _musicChannel->_volumeRight + stepRight);
+ _musicChannel->setVolumeRight(_musicChannel->_volumeRight + stepRight);
} while (_musicChannel->_volumeLeft != volumeLeft || _musicChannel->_volumeRight != volumeRight);
volumeLeft = p_global->pref_10E[0];
volumeRight = p_global->pref_10E[1];
- CLSoundChannel_SetVolumeLeft(hnmsound_ch, volumeLeft);
- CLSoundChannel_SetVolumeRight(hnmsound_ch, volumeRight);
- CLSound_SetWantsDesigned(0);
- CLSoundRaw_AssignBuffer(voiceSound, voiceSamplesBuffer, 0, voiceSamplesSize);
- CLSoundChannel_Play(hnmsound_ch, voiceSound);
+ _voiceChannel->setVolume(volumeLeft, volumeRight);
+ _voiceChannel->queueBuffer((byte*)voiceSamplesBuffer, voiceSamplesSize, true);
_personTalking = true;
_musicFadeFlag = 0;
_lastAnimTicks = TimerTicks;
@@ -6566,7 +6562,7 @@ void EdenGame::persovox() {
void EdenGame::endpersovox() {
restaurefondbulle();
if (_personTalking) {
- CLSoundChannel_Stop(hnmsound_ch);
+ _voiceChannel->stop();
_personTalking = false;
_musicFadeFlag = 3;
}
@@ -6590,7 +6586,7 @@ void EdenGame::fademusicup() {
if (vol < mus_vol_left)
vol = mus_vol_left;
}
- CLSoundChannel_SetVolumeLeft(_musicChannel, vol);
+ _musicChannel->setVolumeLeft(vol);
if (vol == mus_vol_left)
_musicFadeFlag &= ~2;
}
@@ -6605,7 +6601,7 @@ void EdenGame::fademusicup() {
if (vol < mus_vol_right)
vol = mus_vol_right;
}
- CLSoundChannel_SetVolumeRight(_musicChannel, vol);
+ _musicChannel->setVolumeRight(vol);
if (vol == mus_vol_right)
_musicFadeFlag &= ~1;
}
@@ -6613,11 +6609,11 @@ void EdenGame::fademusicup() {
void EdenGame::fademusica0(int16 delay) {
int16 volume;
- while ((volume = CLSoundChannel_GetVolume(_musicChannel)) > 2) {
+ while ((volume = _musicChannel->getVolume()) > 2) {
volume -= 2;
if (volume < 2)
volume = 2;
- CLSoundChannel_SetVolume(_musicChannel, volume);
+ _musicChannel->setVolume(volume, volume);
wait(delay);
}
}
@@ -7222,8 +7218,7 @@ void EdenGame::newvol(byte *volptr, int16 delta) {
if (vol > 63)
vol = 63;
*volptr = vol * 4;
- CLSoundChannel_SetVolumeLeft(_musicChannel, p_global->pref_10C[0]); //TODO: this val only?
- CLSoundChannel_SetVolumeRight(_musicChannel, p_global->pref_10C[1]);
+ _musicChannel->setVolume(p_global->pref_10C[0], p_global->pref_10C[1]);
}
void EdenGame::playtape() {
diff --git a/engines/cryo/eden.h b/engines/cryo/eden.h
index 9efebb694d..5fce67dd75 100644
--- a/engines/cryo/eden.h
+++ b/engines/cryo/eden.h
@@ -23,6 +23,7 @@
#ifndef CRYO_EDEN_H
#define CRYO_EDEN_H
+#include "cryo/sound.h"
#include "cryo/defs.h"
enum Direction {
@@ -641,7 +642,8 @@ private:
bool gameStarted;
bool _soundAllocated;
- soundchannel_t *_musicChannel;
+ CSoundChannel *_musicChannel;
+ CSoundChannel *_voiceChannel;
soundchannel_t *hnmsound_ch;
sound_t *voiceSound;
@@ -693,7 +695,7 @@ private:
byte *mus_samples_ptr;
byte *mus_patterns_ptr; //TODO: sndblock_t ?
byte *mus_sequence_ptr;
- soundgroup_t *mus_queue_grp;
+ bool mus_enabled;
int16 *pCurrentObjectLocation;
byte own_objects[128];
bool byte_31D64;
diff --git a/engines/cryo/sound.cpp b/engines/cryo/sound.cpp
new file mode 100644
index 0000000000..c6ed250451
--- /dev/null
+++ b/engines/cryo/sound.cpp
@@ -0,0 +1,71 @@
+#include "cryo/sound.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+namespace Cryo {
+
+ CSoundChannel::CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo) : _mixer(mixer), _sampleRate(sampleRate), _stereo(stereo) {
+ _audioStream = nullptr;
+ _volumeLeft = _volumeRight = Audio::Mixer::kMaxChannelVolume;
+}
+
+CSoundChannel::~CSoundChannel() {
+ stop();
+ if (_audioStream)
+ delete _audioStream;
+}
+
+void CSoundChannel::queueBuffer(byte *buffer, unsigned int size, bool playNow) {
+ if (playNow)
+ stop();
+ if (!_audioStream)
+ _audioStream = Audio::makeQueuingAudioStream(_sampleRate, _stereo);
+ _audioStream->queueBuffer(buffer, size, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ if (!_mixer->isSoundHandleActive(_soundHandle)) {
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ applyVolumeChange();
+ }
+}
+
+void CSoundChannel::stop() {
+ if (_mixer->isSoundHandleActive(_soundHandle))
+ _mixer->stopHandle(_soundHandle);
+
+ if (_audioStream) {
+ _audioStream->finish();
+ delete _audioStream;
+ _audioStream = nullptr;
+ }
+}
+
+unsigned int CSoundChannel::numQueued() {
+ return _audioStream ? _audioStream->numQueuedStreams() : 0;
+}
+
+unsigned int CSoundChannel::getVolume() {
+ return (_volumeRight + _volumeLeft) / 2;
+}
+
+void CSoundChannel::setVolume(unsigned int volumeLeft, unsigned int volumeRight) {
+ _volumeLeft = volumeLeft;
+ _volumeRight = volumeRight;
+ applyVolumeChange();
+}
+
+void CSoundChannel::setVolumeLeft(unsigned int volume) {
+ setVolume(volume, _volumeRight);
+}
+
+void CSoundChannel::setVolumeRight(unsigned int volume) {
+ setVolume(_volumeLeft, volume);
+}
+
+void CSoundChannel::applyVolumeChange() {
+ unsigned int volume = (_volumeRight + _volumeLeft) / 2;
+ int balance = (signed int)(_volumeRight - _volumeLeft) / 2;
+ _mixer->setChannelVolume(_soundHandle, volume);
+ _mixer->setChannelBalance(_soundHandle, balance);
+}
+
+}
diff --git a/engines/cryo/sound.h b/engines/cryo/sound.h
new file mode 100644
index 0000000000..74300adcb8
--- /dev/null
+++ b/engines/cryo/sound.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+namespace Cryo {
+
+class CSoundChannel {
+private:
+ Audio::Mixer *_mixer;
+ Audio::QueuingAudioStream *_audioStream;
+ Audio::SoundHandle _soundHandle;
+ unsigned int _sampleRate;
+ bool _stereo;
+
+public:
+ CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo);
+ ~CSoundChannel();
+
+ // Queue a new buffer, cancel any previously queued buffers if playNow is set
+ void queueBuffer(byte *buffer, unsigned int size, bool playNow = false);
+
+ // Stop playing and purge play queue
+ void stop();
+
+ // How many buffers in queue (including currently playing one)
+ unsigned int numQueued();
+
+ // Volume control
+ int _volumeLeft, _volumeRight;
+ unsigned int getVolume();
+ void setVolume(unsigned int volumeLeft, unsigned int volumeRight);
+ void setVolumeLeft(unsigned int volume);
+ void setVolumeRight(unsigned int volume);
+
+private:
+ void applyVolumeChange();
+};
+
+}