[Scummvm-cvs-logs] SF.net SVN: scummvm:[45000] scummvm/trunk/engines/draci
spalek at users.sourceforge.net
spalek at users.sourceforge.net
Tue Oct 13 00:27:23 CEST 2009
Revision: 45000
http://scummvm.svn.sourceforge.net/scummvm/?rev=45000&view=rev
Author: spalek
Date: 2009-10-12 22:27:23 +0000 (Mon, 12 Oct 2009)
Log Message:
-----------
Sound effects are now correctly played.
Dubbing is not yet played.
Modified Paths:
--------------
scummvm/trunk/engines/draci/animation.cpp
scummvm/trunk/engines/draci/animation.h
scummvm/trunk/engines/draci/draci.cpp
scummvm/trunk/engines/draci/draci.h
scummvm/trunk/engines/draci/game.cpp
scummvm/trunk/engines/draci/sound.cpp
scummvm/trunk/engines/draci/sound.h
Modified: scummvm/trunk/engines/draci/animation.cpp
===================================================================
--- scummvm/trunk/engines/draci/animation.cpp 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/animation.cpp 2009-10-12 22:27:23 UTC (rev 45000)
@@ -39,6 +39,7 @@
_paused = false;
_tick = _vm->_system->getMillis();
_currentFrame = 0;
+ _hasChangedFrame = true;
_callback = &Animation::doNothing;
}
@@ -97,6 +98,8 @@
// Fetch new frame and mark it dirty
markDirtyRect(surface);
+
+ _hasChangedFrame = true;
}
}
@@ -129,6 +132,15 @@
// Draw frame
frame->drawReScaled(surface, false, _displacement);
}
+
+ const SoundSample *sample = _samples[_currentFrame];
+ if (_hasChangedFrame && sample) {
+ debugC(3, kDraciSoundDebugLevel,
+ "Playing sample on animation %d, frame %d: %d+%d at %dHz",
+ _id, _currentFrame, sample->_offset, sample->_length, sample->_frequency);
+ _vm->_sound->playSound(sample, Audio::Mixer::kMaxChannelVolume, false);
+ }
+ _hasChangedFrame = false;
}
void Animation::setID(int id) {
@@ -162,6 +174,9 @@
void Animation::setPlaying(bool playing) {
_tick = _vm->_system->getMillis();
_playing = playing;
+
+ // When restarting an animation, allow playing sounds.
+ _hasChangedFrame |= playing;
}
bool Animation::isPaused() const {
Modified: scummvm/trunk/engines/draci/animation.h
===================================================================
--- scummvm/trunk/engines/draci/animation.h 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/animation.h 2009-10-12 22:27:23 UTC (rev 45000)
@@ -130,6 +130,7 @@
uint _currentFrame;
uint _z;
+ bool _hasChangedFrame;
Displacement _displacement;
@@ -145,7 +146,7 @@
* object doesn't own these pointers, but they are stored in the
* cache.
*/
- Common::List<const SoundSample *> _samples;
+ Common::Array<const SoundSample *> _samples;
AnimationCallback _callback;
Modified: scummvm/trunk/engines/draci/draci.cpp
===================================================================
--- scummvm/trunk/engines/draci/draci.cpp 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/draci.cpp 2009-10-12 22:27:23 UTC (rev 45000)
@@ -62,6 +62,9 @@
const char *soundsPath = "CD2.SAM";
const char *dubbingPath = "CD.SAM";
+const uint kSoundsFrequency = 13000;
+const uint kDubbingFrequency = 22000;
+
DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc)
: Engine(syst) {
// Put your engine in a sane state, but do nothing big yet;
@@ -79,6 +82,7 @@
Common::addDebugChannel(kDraciArchiverDebugLevel, "archiver", "BAR archiver debug info");
Common::addDebugChannel(kDraciLogicDebugLevel, "logic", "Game logic debug info");
Common::addDebugChannel(kDraciAnimationDebugLevel, "animation", "Animation debug info");
+ Common::addDebugChannel(kDraciSoundDebugLevel, "sound", "Sound debug info");
// Don't forget to register your random source
g_eventRec.registerRandomSource(_rnd, "draci");
@@ -109,8 +113,9 @@
_itemImagesArchive = new BArchive(itemImagesPath);
_stringsArchive = new BArchive(stringsPath);
- _soundsArchive = new SoundArchive(soundsPath);
- _dubbingArchive = new SoundArchive(dubbingPath);
+ _soundsArchive = new SoundArchive(soundsPath, kSoundsFrequency);
+ _dubbingArchive = new SoundArchive(dubbingPath, kDubbingFrequency);
+ _sound = new Sound(_mixer);
// Load the game's fonts
_smallFont = new Font(kFontSmall);
@@ -298,6 +303,7 @@
delete _soundsArchive;
delete _dubbingArchive;
+ delete _sound;
// Remove all of our debug levels here
Common::clearAllDebugChannels();
@@ -337,7 +343,7 @@
void DraciEngine::syncSoundSettings() {
Engine::syncSoundSettings();
- // TODO: update our volumes
+ _sound->setVolume();
}
const char *DraciEngine::getSavegameFile(int saveGameIdx) {
Modified: scummvm/trunk/engines/draci/draci.h
===================================================================
--- scummvm/trunk/engines/draci/draci.h 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/draci.h 2009-10-12 22:27:23 UTC (rev 45000)
@@ -66,6 +66,7 @@
Game *_game;
Script *_script;
AnimationManager *_anims;
+ Sound *_sound;
Font *_smallFont;
Font *_bigFont;
@@ -99,7 +100,8 @@
kDraciBytecodeDebugLevel = 1 << 1,
kDraciArchiverDebugLevel = 1 << 2,
kDraciLogicDebugLevel = 1 << 3,
- kDraciAnimationDebugLevel = 1 << 4
+ kDraciAnimationDebugLevel = 1 << 4,
+ kDraciSoundDebugLevel = 1 << 5
};
// Macro to simulate lround() for non-C99 compilers
Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/game.cpp 2009-10-12 22:27:23 UTC (rev 45000)
@@ -1157,7 +1157,7 @@
uint scaledWidth = animationReader.readUint16LE();
uint scaledHeight = animationReader.readUint16LE();
byte mirror = animationReader.readByte();
- uint sample = animationReader.readUint16LE();
+ int sample = animationReader.readUint16LE() - 1;
uint freq = animationReader.readUint16LE();
uint delay = animationReader.readUint16LE();
@@ -1301,6 +1301,11 @@
}
debugC(1, kDraciLogicDebugLevel, "Entering room %d using gate %d", _newRoom, _newGate);
+ // TODO: maybe wait till all sounds end instead of stopping them.
+ // In any case, make sure all sounds are stopped before we deallocate
+ // their memory by clearing the cache.
+ _vm->_sound->stopAll();
+
// Clear archives
_vm->_roomsArchive->clearCache();
_vm->_spritesArchive->clearCache();
Modified: scummvm/trunk/engines/draci/sound.cpp
===================================================================
--- scummvm/trunk/engines/draci/sound.cpp 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/sound.cpp 2009-10-12 22:27:23 UTC (rev 45000)
@@ -23,6 +23,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/str.h"
@@ -31,6 +32,9 @@
#include "draci/sound.h"
#include "draci/draci.h"
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+
namespace Draci {
void SoundArchive::openArchive(const Common::String &path) {
@@ -129,9 +133,9 @@
*
* Loads individual samples from an archive to memory on demand.
*/
-const SoundSample *SoundArchive::getSample(uint i, uint freq) {
+const SoundSample *SoundArchive::getSample(int i, uint freq) {
// Check whether requested file exists
- if (i >= _sampleCount) {
+ if (i < 0 || i >= (int) _sampleCount) {
return NULL;
}
@@ -150,12 +154,122 @@
debugC(3, kDraciArchiverDebugLevel, "Cached sample %d from archive %s",
i, _path.c_str());
}
- _samples[i]._frequency = freq;
+ _samples[i]._frequency = freq ? freq : _defaultFreq;
return _samples + i;
}
-} // End of namespace Draci
+Sound::Sound(Audio::Mixer *mixer) : _mixer(mixer) {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ _handles[i].type = kFreeHandle;
+ setVolume();
+}
+SndHandle *Sound::getHandle() {
+ for (int i = 0; i < SOUND_HANDLES; i++) {
+ if (_handles[i].type != kFreeHandle && !_mixer->isSoundHandleActive(_handles[i].handle)) {
+ debugC(5, kDraciSoundDebugLevel, "Handle %d has finished playing", i);
+ _handles[i].type = kFreeHandle;
+ }
+ }
+
+ for (int i = 0; i < SOUND_HANDLES; i++) {
+ if (_handles[i].type == kFreeHandle)
+ return &_handles[i];
+ }
+
+ error("Sound::getHandle(): Too many sound handles");
+
+ return NULL; // for compilers that don't support NORETURN
+}
+
+void Sound::playSoundBuffer(Audio::SoundHandle *handle, const SoundSample &buffer, int volume,
+ sndHandleType handleType, bool loop) {
+
+ // Don't use FLAG_AUTOFREE, because our caching system deletes samples by itself.
+ byte flags = Audio::Mixer::FLAG_UNSIGNED;
+
+ if (loop)
+ flags |= Audio::Mixer::FLAG_LOOP;
+
+ const Audio::Mixer::SoundType soundType = (handleType == kVoiceHandle) ?
+ Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType;
+
+ _mixer->playRaw(soundType, handle, buffer._data,
+ buffer._length, buffer._frequency, flags, -1, volume);
+}
+
+void Sound::playSound(const SoundSample *buffer, int volume, bool loop) {
+ if (!buffer)
+ return;
+ SndHandle *handle = getHandle();
+
+ handle->type = kEffectHandle;
+ playSoundBuffer(&handle->handle, *buffer, 2 * volume, handle->type, loop);
+}
+
+void Sound::pauseSound() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kEffectHandle)
+ _mixer->pauseHandle(_handles[i].handle, true);
+}
+
+void Sound::resumeSound() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kEffectHandle)
+ _mixer->pauseHandle(_handles[i].handle, false);
+}
+
+void Sound::stopSound() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kEffectHandle) {
+ _mixer->stopHandle(_handles[i].handle);
+ _handles[i].type = kFreeHandle;
+ }
+}
+
+void Sound::playVoice(const SoundSample *buffer) {
+ if (!buffer)
+ return;
+ SndHandle *handle = getHandle();
+
+ handle->type = kVoiceHandle;
+ playSoundBuffer(&handle->handle, *buffer, Audio::Mixer::kMaxChannelVolume, handle->type, false);
+}
+
+void Sound::pauseVoice() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kVoiceHandle)
+ _mixer->pauseHandle(_handles[i].handle, true);
+}
+
+void Sound::resumeVoice() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kVoiceHandle)
+ _mixer->pauseHandle(_handles[i].handle, false);
+}
+
+void Sound::stopVoice() {
+ for (int i = 0; i < SOUND_HANDLES; i++)
+ if (_handles[i].type == kVoiceHandle) {
+ _mixer->stopHandle(_handles[i].handle);
+ _handles[i].type = kFreeHandle;
+ }
+}
+
+void Sound::stopAll() {
+ stopVoice();
+ stopSound();
+}
+
+void Sound::setVolume() {
+ const int soundVolume = ConfMan.getInt("sfx_volume");
+ const int speechVolume = ConfMan.getInt("speech_volume");
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, speechVolume);
+ // TODO: make sure this sound settings works
+}
+
+} // End of namespace Draci
Modified: scummvm/trunk/engines/draci/sound.h
===================================================================
--- scummvm/trunk/engines/draci/sound.h 2009-10-12 22:23:27 UTC (rev 44999)
+++ scummvm/trunk/engines/draci/sound.h 2009-10-12 22:27:23 UTC (rev 45000)
@@ -28,6 +28,7 @@
#include "common/str.h"
#include "common/file.h"
+#include "sound/mixer.h"
namespace Draci {
@@ -48,10 +49,8 @@
class SoundArchive {
public:
- SoundArchive() : _path(), _samples(NULL), _sampleCount(0), _opened(false), _f(NULL) {}
-
- SoundArchive(const Common::String &path) :
- _path(), _samples(NULL), _sampleCount(0), _opened(false), _f(NULL) {
+ SoundArchive(const Common::String &path, uint defaultFreq) :
+ _path(), _samples(NULL), _sampleCount(0), _defaultFreq(defaultFreq), _opened(false), _f(NULL) {
openArchive(path);
}
@@ -69,16 +68,64 @@
void clearCache();
- const SoundSample *getSample(uint i, uint freq);
+ const SoundSample *getSample(int i, uint freq);
private:
Common::String _path; ///< Path to file
SoundSample *_samples; ///< Internal array of files
uint _sampleCount; ///< Number of files in archive
+ uint _defaultFreq; ///< The default sampling frequency of the archived samples
bool _opened; ///< True if the archive is opened, false otherwise
Common::File *_f; ///< Opened file
};
+#define SOUND_HANDLES 10
+
+enum sndHandleType {
+ kFreeHandle,
+ kEffectHandle,
+ kVoiceHandle
+};
+
+struct SndHandle {
+ Audio::SoundHandle handle;
+ sndHandleType type;
+};
+
+// Taken from engines/saga/sound.h and simplified (in particular, removed
+// decompression until we support compressed files too).
+class Sound {
+public:
+
+ Sound(Audio::Mixer *mixer);
+ ~Sound() {}
+
+ void playSound(const SoundSample *buffer, int volume, bool loop);
+ void pauseSound();
+ void resumeSound();
+ void stopSound();
+
+ void playVoice(const SoundSample *buffer);
+ void pauseVoice();
+ void resumeVoice();
+ void stopVoice();
+
+ void stopAll();
+
+ void setVolume();
+
+ private:
+
+ void playSoundBuffer(Audio::SoundHandle *handle, const SoundSample &buffer, int volume,
+ sndHandleType handleType, bool loop);
+
+ SndHandle *getHandle();
+
+ Audio::Mixer *_mixer;
+
+ SndHandle _handles[SOUND_HANDLES];
+};
+
} // End of namespace Draci
#endif // DRACI_SOUND_H
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list