From f71b32dd96cc524fbb433752ea2ead51e1cf02a4 Mon Sep 17 00:00:00 2001 From: Robert Špalek Date: Sun, 11 Oct 2009 23:01:59 +0000 Subject: Loading and caching sound samples in memory. The sounds are not played yet, but the infrastructure is getting ready. svn-id: r44957 --- engines/draci/animation.cpp | 6 ++++-- engines/draci/animation.h | 8 +++++++- engines/draci/barchive.cpp | 4 ++-- engines/draci/draci.cpp | 10 ++++++++++ engines/draci/game.cpp | 22 +++++++++++++--------- engines/draci/script.cpp | 2 +- engines/draci/sound.cpp | 21 +++++++++++---------- engines/draci/sound.h | 3 ++- 8 files changed, 50 insertions(+), 26 deletions(-) (limited to 'engines') diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp index 3429884397..c3ae4a8f12 100644 --- a/engines/draci/animation.cpp +++ b/engines/draci/animation.cpp @@ -191,8 +191,9 @@ double Animation::getScaleY() const { return _displacement.extraScaleY; } -void Animation::addFrame(Drawable *frame) { +void Animation::addFrame(Drawable *frame, const SoundSample *sample) { _frames.push_back(frame); + _samples.push_back(sample); } int Animation::getIndex() const { @@ -246,6 +247,7 @@ void Animation::deleteFrames() { delete _frames[i]; _frames.pop_back(); } + _samples.clear(); } void Animation::stopAnimation() { @@ -382,7 +384,7 @@ void AnimationManager::addOverlay(Drawable *overlay, uint z) { anim->setID(kOverlayImage); anim->setZ(z); anim->setPlaying(true); - anim->addFrame(overlay); + anim->addFrame(overlay, NULL); insertAnimation(anim); } diff --git a/engines/draci/animation.h b/engines/draci/animation.h index e8b09823e6..8dc596406d 100644 --- a/engines/draci/animation.h +++ b/engines/draci/animation.h @@ -27,6 +27,7 @@ #define DRACI_ANIMATION_H #include "draci/sprite.h" +#include "draci/sound.h" namespace Draci { @@ -76,7 +77,7 @@ public: void nextFrame(bool force = false); void drawFrame(Surface *surface); - void addFrame(Drawable *frame); + void addFrame(Drawable *frame, const SoundSample *sample); Drawable *getFrame(int frameNum = kCurrentFrame); void setCurrentFrame(uint frame); uint currentFrameNum() const; @@ -140,6 +141,11 @@ private: /** Array of frames of the animation. The animation object owns these pointers. */ Common::Array _frames; + /** Array of samples played during the animation. The animation + * object doesn't own these pointers, but they are stored in the + * cache. + */ + Common::List _samples; AnimationCallback _callback; diff --git a/engines/draci/barchive.cpp b/engines/draci/barchive.cpp index 408fe0c7de..8b75ac679c 100644 --- a/engines/draci/barchive.cpp +++ b/engines/draci/barchive.cpp @@ -268,6 +268,7 @@ void BArchive::closeArchive(void) { * @return Pointer to a BAFile coresponding to the opened file or NULL (on failure) * * Loads individual BAR files from an archive to memory on demand. + * Should not be called directly. */ BAFile *BArchive::loadFileBAR(uint i) { Common::File f; @@ -305,8 +306,7 @@ BAFile *BArchive::loadFileBAR(uint i) { * @return Pointer to a BAFile coresponding to the opened file or NULL (on failure) * * Loads individual DFW files from an archive to memory on demand. - * Should not be called directly. Instead, one should access files - * through the operator[] interface. + * Should not be called directly. */ BAFile *BArchive::loadFileDFW(uint i) { Common::File f; diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index ce0d59f8fe..1868460fcf 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -162,6 +162,16 @@ int DraciEngine::init() { return Common::kUnknownError; } + if (!_soundsArchive->isOpen()) { + debugC(2, kDraciGeneralDebugLevel, "ERROR - Opening sounds archive failed"); + return Common::kUnknownError; + } + + if (!_dubbingArchive->isOpen()) { + debugC(2, kDraciGeneralDebugLevel, "ERROR - Opening dubbing archive failed"); + return Common::kUnknownError; + } + _showWalkingMap = false; // Basic archive test diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index 1b51bd9142..34549df416 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -177,25 +177,25 @@ void Game::init() { // Initialize animation for object / room titles Animation *titleAnim = _vm->_anims->addText(kTitleText, true); Text *title = new Text("", _vm->_smallFont, kTitleColour, 0, 0); - titleAnim->addFrame(title); + titleAnim->addFrame(title, NULL); // Initialize animation for speech text Animation *speechAnim = _vm->_anims->addText(kSpeechText, true); Text *speech = new Text("", _vm->_bigFont, kFontColour1, 0, 0); - speechAnim->addFrame(speech); + speechAnim->addFrame(speech, NULL); // Initialize inventory animation const BAFile *f = _vm->_iconsArchive->getFile(13); Animation *inventoryAnim = _vm->_anims->addAnimation(kInventorySprite, 255, false); Sprite *inventorySprite = new Sprite(f->_data, f->_length, 0, 0, true); - inventoryAnim->addFrame(inventorySprite); + inventoryAnim->addFrame(inventorySprite, NULL); inventoryAnim->setRelative((kScreenWidth - inventorySprite->getWidth()) / 2, (kScreenHeight - inventorySprite->getHeight()) / 2); for (uint i = 0; i < kDialogueLines; ++i) { _dialogueAnims[i] = _vm->_anims->addText(kDialogueLinesID - i, true); Text *dialogueLine = new Text("", _vm->_smallFont, kLineInactiveColour, 0, 0); - _dialogueAnims[i]->addFrame(dialogueLine); + _dialogueAnims[i]->addFrame(dialogueLine, NULL); _dialogueAnims[i]->setZ(254); _dialogueAnims[i]->setRelative(1, @@ -644,7 +644,7 @@ void Game::putItem(int itemID, int position) { anim = _vm->_anims->addItem(anim_id); const BAFile *img = _vm->_itemImagesArchive->getFile(2 * itemID); Sprite *sp = new Sprite(img->_data, img->_length, 0, 0, true); - anim->addFrame(sp); + anim->addFrame(sp, NULL); } Drawable *frame = anim->getFrame(); @@ -1117,7 +1117,7 @@ void Game::loadRoom(int roomNum) { delete[] wlk; Animation *map = _vm->_anims->addAnimation(kWalkingMapOverlay, 255, false); - map->addFrame(ov); + map->addFrame(ov, NULL); } int Game::loadAnimation(uint animNum, uint z) { @@ -1145,8 +1145,8 @@ int Game::loadAnimation(uint animNum, uint z) { uint scaledWidth = animationReader.readUint16LE(); uint scaledHeight = animationReader.readUint16LE(); byte mirror = animationReader.readByte(); - /* uint sample = */ animationReader.readUint16LE(); - /* uint freq = */ animationReader.readUint16LE(); + uint sample = animationReader.readUint16LE(); + uint freq = animationReader.readUint16LE(); uint delay = animationReader.readUint16LE(); const BAFile *spriteFile = _vm->_spritesArchive->getFile(spriteNum); @@ -1171,7 +1171,9 @@ int Game::loadAnimation(uint animNum, uint z) { sp->setDelay(delay * 10); - anim->addFrame(sp); + const SoundSample *sam = _vm->_soundsArchive->getSample(sample, freq); + + anim->addFrame(sp, sam); } return animNum; @@ -1282,6 +1284,8 @@ void Game::enterNewRoom(bool force_reload) { _vm->_paletteArchive->clearCache(); _vm->_animationsArchive->clearCache(); _vm->_walkingMapsArchive->clearCache(); + _vm->_soundsArchive->clearCache(); + _vm->_dubbingArchive->clearCache(); _vm->_screen->clearScreen(); diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp index 722af9e21e..ecdca91435 100644 --- a/engines/draci/script.cpp +++ b/engines/draci/script.cpp @@ -569,7 +569,7 @@ void Script::icoStat(Common::Queue ¶ms) { Animation *itemAnim = _vm->_anims->addItem(kInventoryItemsID - itemID); const BAFile *f = _vm->_itemImagesArchive->getFile(2 * itemID); Sprite *sp = new Sprite(f->_data, f->_length, 0, 0, true); - itemAnim->addFrame(sp); + itemAnim->addFrame(sp, NULL); } _vm->_game->setCurrentItem(itemID); diff --git a/engines/draci/sound.cpp b/engines/draci/sound.cpp index bd2f68658b..8f734d1afb 100644 --- a/engines/draci/sound.cpp +++ b/engines/draci/sound.cpp @@ -74,6 +74,7 @@ void SoundArchive::openArchive(const Common::String &path) { for (uint i = 0; i < _sampleCount; ++i) { _samples[i]._offset = sampleStarts[i]; _samples[i]._length = sampleStarts[i+1] - sampleStarts[i]; + _samples[i]._frequency = 0; // set in getSample() _samples[i]._data = NULL; } if (_samples[_sampleCount-1]._offset + _samples[_sampleCount-1]._length != totalLength && @@ -128,7 +129,7 @@ void SoundArchive::clearCache() { * * Loads individual samples from an archive to memory on demand. */ -const SoundSample *SoundArchive::getSample(uint i) { +const SoundSample *SoundArchive::getSample(uint i, uint freq) { // Check whether requested file exists if (i >= _sampleCount) { return NULL; @@ -140,16 +141,16 @@ const SoundSample *SoundArchive::getSample(uint i) { // Check if file has already been opened and return that if (_samples[i]._data) { debugC(2, kDraciArchiverDebugLevel, "Success"); - return _samples + i; - } - - // Read in the file (without the file header) - _f->seek(_samples[i]._offset); - _samples[i]._data = new byte[_samples[i]._length]; - _f->read(_samples[i]._data, _samples[i]._length); + } else { + // Read in the file (without the file header) + _f->seek(_samples[i]._offset); + _samples[i]._data = new byte[_samples[i]._length]; + _f->read(_samples[i]._data, _samples[i]._length); - debugC(3, kDraciArchiverDebugLevel, "Cached sample %d from archive %s", - i, _path.c_str()); + debugC(3, kDraciArchiverDebugLevel, "Cached sample %d from archive %s", + i, _path.c_str()); + } + _samples[i]._frequency = freq; return _samples + i; } diff --git a/engines/draci/sound.h b/engines/draci/sound.h index 9c8c571af4..b9429a70a7 100644 --- a/engines/draci/sound.h +++ b/engines/draci/sound.h @@ -37,6 +37,7 @@ namespace Draci { struct SoundSample { uint _offset; uint _length; + uint _frequency; byte* _data; void close(void) { @@ -68,7 +69,7 @@ public: void clearCache(); - const SoundSample *getSample(uint i); + const SoundSample *getSample(uint i, uint freq); private: Common::String _path; ///< Path to file -- cgit v1.2.3