diff options
Diffstat (limited to 'engines/saga')
-rw-r--r-- | engines/saga/actor_path.cpp | 3 | ||||
-rw-r--r-- | engines/saga/animation.cpp | 2 | ||||
-rw-r--r-- | engines/saga/gfx.cpp | 2 | ||||
-rw-r--r-- | engines/saga/interface.cpp | 4 | ||||
-rw-r--r-- | engines/saga/isomap.cpp | 2 | ||||
-rw-r--r-- | engines/saga/resource.h | 2 | ||||
-rw-r--r-- | engines/saga/saga.h | 12 | ||||
-rw-r--r-- | engines/saga/script.h | 4 | ||||
-rw-r--r-- | engines/saga/sndres.cpp | 228 | ||||
-rw-r--r-- | engines/saga/sndres.h | 3 | ||||
-rw-r--r-- | engines/saga/sound.cpp | 35 | ||||
-rw-r--r-- | engines/saga/sound.h | 19 |
12 files changed, 132 insertions, 184 deletions
diff --git a/engines/saga/actor_path.cpp b/engines/saga/actor_path.cpp index 3e10aba6b6..0fb072b201 100644 --- a/engines/saga/actor_path.cpp +++ b/engines/saga/actor_path.cpp @@ -223,7 +223,6 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be int currentRating; Point bestPath; int pointCounter; - int startDirection; const PathDirectionData *samplePathDirection; Point nextPoint; int directionCount; @@ -235,7 +234,7 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be bestRating = quickDistance(fromPoint, toPoint, compressX); bestPath = fromPoint; - for (startDirection = 0; startDirection < 4; startDirection++) { + for (int8 startDirection = 0; startDirection < 4; startDirection++) { PathDirectionData tmp = { startDirection, fromPoint.x, fromPoint.y }; pathDirectionQueue.push_back(tmp); } diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index 8b2d1e9dad..fd602ff4fb 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -501,7 +501,7 @@ void Anim::play(uint16 animId, int vectorTime, bool playing) { } anim = getAnimation(animId); - displayBuffer = (byte*)_vm->_render->getBackGroundSurface()->pixels; + displayBuffer = (byte *)_vm->_render->getBackGroundSurface()->pixels; if (playing) { anim->state = ANIM_PLAYING; diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp index 8e98f0fbe7..62250a0820 100644 --- a/engines/saga/gfx.cpp +++ b/engines/saga/gfx.cpp @@ -156,7 +156,7 @@ void Surface::transitionDissolve(const byte *sourceBuffer, const Common::Rect &s if (sourceRect.contains(x1, y1)) { color = sourceBuffer[(x1-sourceRect.left) + sourceRect.width()*(y1-sourceRect.top)]; if (flags == 0 || color) - ((byte*)pixels)[seq] = color; + ((byte *)pixels)[seq] = color; } } } diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp index 994b35cbf8..a7bd7edbe5 100644 --- a/engines/saga/interface.cpp +++ b/engines/saga/interface.cpp @@ -1151,7 +1151,7 @@ void Interface::processStatusTextInput(Common::KeyState keystate) { if (_statusTextInputPos >= STATUS_TEXT_INPUT_MAX) { break; } - if (isalnum(keystate.ascii) || (keystate.ascii == ' ')) { + if (Common::isAlnum(keystate.ascii) || (keystate.ascii == ' ')) { _statusTextInputString[_statusTextInputPos++] = keystate.ascii; _statusTextInputString[_statusTextInputPos] = 0; } @@ -1209,7 +1209,7 @@ bool Interface::processTextInput(Common::KeyState keystate) { _textInputPos = _textInputStringLength + 1; break; default: - if (((keystate.ascii <= 255) && (isalnum(keystate.ascii))) || (keystate.ascii == ' ') || + if (((keystate.ascii <= 255) && (Common::isAlnum(keystate.ascii))) || (keystate.ascii == ' ') || (keystate.ascii == '-') || (keystate.ascii == '_')) { if (_textInputStringLength < save_title_size - 1) { ch[0] = keystate.ascii; diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp index ec6b13f313..945b4ad5a7 100644 --- a/engines/saga/isomap.cpp +++ b/engines/saga/isomap.cpp @@ -346,7 +346,7 @@ int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) { if (offset + sizeof(int16) > _multiTableData.size() * sizeof(int16)) { error("wrong multiTileEntryData->offset"); } - tiles = (int16*)((byte*)&_multiTableData.front() + offset); + tiles = (int16 *)((byte *)&_multiTableData.front() + offset); tileIndex = *tiles; if (tileIndex >= 256) { warning("something terrible happened"); diff --git a/engines/saga/resource.h b/engines/saga/resource.h index 2124f3e29f..a8e2e92361 100644 --- a/engines/saga/resource.h +++ b/engines/saga/resource.h @@ -157,7 +157,7 @@ protected: virtual void processPatches(Resource *resource, const GamePatchDescription *patchFiles) { } }; -typedef Common::List<ResourceContext*> ResourceContextList; +typedef Common::List<ResourceContext *> ResourceContextList; struct MetaResource { int16 sceneIndex; diff --git a/engines/saga/saga.h b/engines/saga/saga.h index fb01b1ac5d..829425aeaf 100644 --- a/engines/saga/saga.h +++ b/engines/saga/saga.h @@ -208,18 +208,6 @@ enum PanelButtonType { kPanelAllButtons = 0xFFFFF }; -enum GameSoundTypes { - kSoundPCM = 0, - kSoundVOX = 1, - kSoundVOC = 2, - kSoundWAV = 3, - kSoundMP3 = 4, - kSoundOGG = 5, - kSoundFLAC = 6, - kSoundAIFF = 7, - kSoundShorten = 8 -}; - enum TextStringIds { kTextPickUp, kTextLookAt, diff --git a/engines/saga/script.h b/engines/saga/script.h index 227b58a298..c4ea2d62b3 100644 --- a/engines/saga/script.h +++ b/engines/saga/script.h @@ -196,9 +196,9 @@ public: case kAddressModule: return _moduleBase; case kAddressStack: - return (byte*)&_stackBuf[_frameIndex]; + return (byte *)&_stackBuf[_frameIndex]; case kAddressThread: - return (byte*)_threadVars; + return (byte *)_threadVars; default: return _commonBase; } diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp index add34e22a2..71044034d7 100644 --- a/engines/saga/sndres.cpp +++ b/engines/saga/sndres.cpp @@ -30,12 +30,17 @@ #include "saga/sound.h" #include "common/file.h" +#include "common/substream.h" #include "audio/audiostream.h" #include "audio/decoders/adpcm.h" #include "audio/decoders/aiff.h" +#include "audio/decoders/flac.h" +#include "audio/decoders/mac_snd.h" +#include "audio/decoders/mp3.h" #include "audio/decoders/raw.h" #include "audio/decoders/voc.h" +#include "audio/decoders/vorbis.h" #include "audio/decoders/wave.h" #ifdef ENABLE_SAGA2 #include "saga/shorten.h" @@ -99,9 +104,6 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm), _sfxContext(NULL), _voiceContext(NULL) } } -SndRes::~SndRes() { -} - void SndRes::setVoiceBank(int serial) { Common::File *file; if (_voiceSerial == serial) @@ -167,14 +169,31 @@ void SndRes::playVoice(uint32 resourceId) { _vm->_sound->playVoice(buffer); } +enum GameSoundType { + kSoundPCM = 0, + kSoundVOX = 1, + kSoundVOC = 2, + kSoundWAV = 3, + kSoundMP3 = 4, + kSoundOGG = 5, + kSoundFLAC = 6, + kSoundAIFF = 7, + kSoundShorten = 8, + kSoundMacSND = 9 +}; + +// Use a macro to read in the sound data based on if we actually want to buffer it or not +#define READ_STREAM(streamSize) \ + (onlyHeader \ + ? new Common::SeekableSubReadStream(&readS, readS.pos(), readS.pos() + (streamSize)) \ + : readS.readStream(streamSize)) + bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader) { - Audio::AudioStream *voxStream; size_t soundResourceLength; bool result = false; - GameSoundTypes resourceType = kSoundPCM; - byte *data = 0; + GameSoundType resourceType = kSoundPCM; int rate = 0, size = 0; - Common::File* file; + Common::File *file; if (resourceId == (uint32)-1) { return false; @@ -210,7 +229,7 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff soundResourceLength = resourceData->size; } - Common::SeekableReadStream& readS = *file; + Common::SeekableReadStream &readS = *file; bool uncompressedSound = false; if (soundResourceLength >= 8) { @@ -250,160 +269,141 @@ bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buff } - // Default sound type is 16-bit signed PCM, used in ITE by PCM and VOX files - buffer.isCompressed = context->isCompressed(); - buffer.soundType = resourceType; - buffer.originalSize = 0; - // Set default flags and frequency for PCM, VOC and VOX files, which got no header - buffer.flags = Audio::FLAG_16BITS; - buffer.frequency = 22050; + // Default sound type is 16-bit signed PCM, used in ITE + byte rawFlags = Audio::FLAG_16BITS; + if (_vm->getGameId() == GID_ITE) { - if (_vm->getFeatures() & GF_8BIT_UNSIGNED_PCM) { // older ITE demos - buffer.flags |= Audio::FLAG_UNSIGNED; - buffer.flags &= ~Audio::FLAG_16BITS; - } else { + if (context->fileType() & GAME_MACBINARY) { + // ITE Mac has sound in the Mac snd format + resourceType = kSoundMacSND; + } else if (_vm->getFeatures() & GF_8BIT_UNSIGNED_PCM) { // older ITE demos + rawFlags |= Audio::FLAG_UNSIGNED; + rawFlags &= ~Audio::FLAG_16BITS; + } else if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) { // Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded. - // These are LE in all the Windows and Mac demos - if (!uncompressedSound && !scumm_stricmp(context->fileName(), "voicesd.rsc")) { - resourceType = kSoundVOX; - buffer.flags |= Audio::FLAG_LITTLE_ENDIAN; - } + resourceType = kSoundVOX; } } - buffer.buffer = NULL; + + buffer.stream = 0; // Check for LE sounds if (!context->isBigEndian()) - buffer.flags |= Audio::FLAG_LITTLE_ENDIAN; - - // Older Mac versions of ITE were Macbinary packed - int soundOffset = (context->fileType() & GAME_MACBINARY) ? 36 : 0; + rawFlags |= Audio::FLAG_LITTLE_ENDIAN; switch (resourceType) { - case kSoundPCM: - buffer.size = soundResourceLength - soundOffset; - if (!onlyHeader) { - buffer.buffer = (byte *) malloc(buffer.size); - if (soundOffset > 0) - readS.skip(soundOffset); - readS.read(buffer.buffer, buffer.size); - } + case kSoundPCM: { + // In ITE CD German, some voices are absent and contain just 5 zero bytes. + // Round down to an even number when the audio is 16-bit so makeRawStream + // will accept the data (needs to be an even size for 16-bit data). + // See bug #1256701 + + if ((soundResourceLength & 1) && (rawFlags & Audio::FLAG_16BITS)) + soundResourceLength &= ~1; + + Audio::SeekableAudioStream *audStream = Audio::makeRawStream(READ_STREAM(soundResourceLength), 22050, rawFlags); + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); result = true; - break; + } break; case kSoundVOX: - buffer.size = soundResourceLength * 4; - if (!onlyHeader) { - voxStream = Audio::makeADPCMStream(&readS, DisposeAfterUse::NO, soundResourceLength, Audio::kADPCMOki); - buffer.buffer = (byte *)malloc(buffer.size); - voxStream->readBuffer((int16*)buffer.buffer, soundResourceLength * 2); - delete voxStream; - } + buffer.stream = Audio::makeADPCMStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES, soundResourceLength, Audio::kADPCMOki, 22050, 1); + buffer.streamLength = Audio::Timestamp(0, soundResourceLength * 2, buffer.stream->getRate()); result = true; break; + case kSoundMacSND: { + Audio::SeekableAudioStream *audStream = Audio::makeMacSndStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES); + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); + result = true; + } break; + case kSoundAIFF: { + Audio::SeekableAudioStream *audStream = Audio::makeAIFFStream(READ_STREAM(soundResourceLength), DisposeAfterUse::YES); + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); + result = true; + } break; + case kSoundVOC: { + Audio::SeekableAudioStream *audStream = Audio::makeVOCStream(READ_STREAM(soundResourceLength), Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); + result = true; + } break; case kSoundWAV: - case kSoundAIFF: case kSoundShorten: - case kSoundVOC: if (resourceType == kSoundWAV) { - result = Audio::loadWAVFromStream(readS, size, rate, buffer.flags); - } else if (resourceType == kSoundAIFF) { - result = Audio::loadAIFFFromStream(readS, size, rate, buffer.flags); + result = Audio::loadWAVFromStream(readS, size, rate, rawFlags); #ifdef ENABLE_SAGA2 } else if (resourceType == kSoundShorten) { - result = loadShortenFromStream(readS, size, rate, buffer.flags); + result = loadShortenFromStream(readS, size, rate, rawFlags); #endif - } else if (resourceType == kSoundVOC) { - data = Audio::loadVOCFromStream(readS, size, rate); - result = (data != NULL); - if (onlyHeader) - free(data); - buffer.flags |= Audio::FLAG_UNSIGNED; - buffer.flags &= ~Audio::FLAG_16BITS; - buffer.flags &= ~Audio::FLAG_STEREO; } if (result) { - buffer.frequency = rate; - buffer.size = size; - - if (!onlyHeader) { - if (resourceType == kSoundVOC) { - buffer.buffer = data; - } else { - buffer.buffer = (byte *)malloc(size); - readS.read(buffer.buffer, size); - } - } + Audio::SeekableAudioStream *audStream = Audio::makeRawStream(READ_STREAM(size), rate, rawFlags); + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); } break; case kSoundMP3: case kSoundOGG: - case kSoundFLAC: - ResourceData *resourceData; - resourceData = context->getResourceData(resourceId); - - // Read compressed sfx header - readS.readByte(); // Skip compression identifier byte - buffer.frequency = readS.readUint16LE(); - buffer.originalSize = readS.readUint32LE(); - if (readS.readByte() == 8) // read sample bits - buffer.flags &= ~Audio::FLAG_16BITS; - if (readS.readByte() != 0) // read stereo flag - buffer.flags |= Audio::FLAG_STEREO; - - buffer.size = soundResourceLength; - buffer.soundType = resourceType; - buffer.fileOffset = resourceData->offset + 9; // skip compressed sfx header: byte + uint16 + uint32 + byte + byte - - if (!onlyHeader) { - buffer.buffer = (byte *)malloc(buffer.size); - readS.read(buffer.buffer, buffer.size); + case kSoundFLAC: { + readS.skip(9); // skip sfx header + + Audio::SeekableAudioStream *audStream = 0; + Common::SeekableReadStream *memStream = READ_STREAM(soundResourceLength - 9); + + if (resourceType == kSoundMP3) { +#ifdef USE_MAD + audStream = Audio::makeMP3Stream(memStream, DisposeAfterUse::YES); +#endif + } else if (resourceType == kSoundOGG) { +#ifdef USE_VORBIS + audStream = Audio::makeVorbisStream(memStream, DisposeAfterUse::YES); +#endif + } else /* if (resourceType == kSoundFLAC) */ { +#ifdef USE_FLAC + audStream = Audio::makeFLACStream(memStream, DisposeAfterUse::YES); +#endif } - result = true; - break; + if (audStream) { + buffer.stream = audStream; + buffer.streamLength = audStream->getLength(); + result = true; + } else { + delete memStream; + } + + } break; default: error("SndRes::load Unknown sound type"); } - if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) { delete file; } - - // In ITE CD De some voices are absent and contain just 5 bytes header - // Round it to even number so soundmanager will not crash. - // See bug #1256701 - buffer.size &= ~(0x1); + if (onlyHeader) { + delete buffer.stream; + buffer.stream = 0; + } return result; } +#undef READ_STREAM + int SndRes::getVoiceLength(uint32 resourceId) { - double msDouble; SoundBuffer buffer; if (!(_vm->_voiceFilesExist)) return -1; - if (!load(_voiceContext, resourceId, buffer, true)) { + if (!load(_voiceContext, resourceId, buffer, true)) return -1; - } - - if (!_voiceContext->isCompressed() || buffer.originalSize == 0) - msDouble = (double)buffer.size; - else - msDouble = (double)buffer.originalSize; - - if (buffer.flags & Audio::FLAG_16BITS) - msDouble /= 2.0; - - if (buffer.flags & Audio::FLAG_STEREO) - msDouble /= 2.0; - msDouble = msDouble / buffer.frequency * 1000.0; - return (int)msDouble; + return buffer.streamLength.msecs(); } } // End of namespace Saga diff --git a/engines/saga/sndres.h b/engines/saga/sndres.h index 9b0eebc834..bc38bed431 100644 --- a/engines/saga/sndres.h +++ b/engines/saga/sndres.h @@ -39,7 +39,6 @@ class SndRes { public: SndRes(SagaEngine *vm); - ~SndRes(); void playSound(uint32 resourceId, int volume, bool loop); void playVoice(uint32 resourceId); @@ -52,8 +51,6 @@ public: private: bool load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader); - bool loadVocSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer); - bool loadWavSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer); ResourceContext *_sfxContext; ResourceContext *_voiceContext; diff --git a/engines/saga/sound.cpp b/engines/saga/sound.cpp index 3408125f73..67be499bc7 100644 --- a/engines/saga/sound.cpp +++ b/engines/saga/sound.cpp @@ -63,42 +63,11 @@ SndHandle *Sound::getHandle() { void Sound::playSoundBuffer(Audio::SoundHandle *handle, const SoundBuffer &buffer, int volume, sndHandleType handleType, bool loop) { - Audio::RewindableAudioStream *stream = 0; - Audio::Mixer::SoundType soundType = (handleType == kVoiceHandle) ? Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType; - if (!buffer.isCompressed) { - stream = Audio::makeRawStream(buffer.buffer, buffer.size, buffer.frequency, buffer.flags); - } else { - Common::SeekableReadStream *memStream = new Common::MemoryReadStream(buffer.buffer, buffer.size, DisposeAfterUse::YES); - - switch (buffer.soundType) { -#ifdef USE_MAD - case kSoundMP3: - stream = Audio::makeMP3Stream(memStream, DisposeAfterUse::YES); - break; -#endif -#ifdef USE_VORBIS - case kSoundOGG: - stream = Audio::makeVorbisStream(memStream, DisposeAfterUse::YES); - break; -#endif -#ifdef USE_FLAC - case kSoundFLAC: - stream = Audio::makeFLACStream(memStream, DisposeAfterUse::YES); - break; -#endif - default: - // Unknown compression, ignore sample - delete memStream; - warning("Unknown compression, ignoring sound"); - break; - } - } - - if (stream != NULL) - _mixer->playStream(soundType, handle, Audio::makeLoopingAudioStream(stream, loop ? 0 : 1), -1, volume); + if (buffer.stream) + _mixer->playStream(soundType, handle, Audio::makeLoopingAudioStream(buffer.stream, loop ? 0 : 1), -1, volume); } void Sound::playSound(SoundBuffer &buffer, int volume, bool loop, int resId) { diff --git a/engines/saga/sound.h b/engines/saga/sound.h index 15624a9da5..e2163dfb0e 100644 --- a/engines/saga/sound.h +++ b/engines/saga/sound.h @@ -27,9 +27,11 @@ #include "common/file.h" #include "audio/mixer.h" -#include "audio/decoders/mp3.h" -#include "audio/decoders/vorbis.h" -#include "audio/decoders/flac.h" +#include "audio/timestamp.h" + +namespace Audio { +class RewindableAudioStream; +} namespace Saga { @@ -40,15 +42,8 @@ enum SOUND_FLAGS { }; struct SoundBuffer { - uint16 frequency; - bool isCompressed; - byte flags; - - byte *buffer; - size_t size; - size_t originalSize; - GameSoundTypes soundType; - size_t fileOffset; + Audio::RewindableAudioStream *stream; + Audio::Timestamp streamLength; }; enum sndHandleType { |