aboutsummaryrefslogtreecommitdiff
path: root/engines/saga
diff options
context:
space:
mode:
authorMatthew Hoops2012-03-20 14:18:57 -0400
committerMatthew Hoops2012-03-20 14:49:16 -0400
commit71756bdf4eae5ba9cc3f329b85e894f04640aaef (patch)
tree40d464262da107ab5eed82f198685209161ebac1 /engines/saga
parent03eba05b09e5c9e5a351f8111185934b92a3fed3 (diff)
parent3c3576a224b92c703b4e8ea20008ac8a069980dd (diff)
downloadscummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.tar.gz
scummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.tar.bz2
scummvm-rg350-71756bdf4eae5ba9cc3f329b85e894f04640aaef.zip
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'engines/saga')
-rw-r--r--engines/saga/actor_path.cpp3
-rw-r--r--engines/saga/animation.cpp2
-rw-r--r--engines/saga/gfx.cpp2
-rw-r--r--engines/saga/interface.cpp4
-rw-r--r--engines/saga/isomap.cpp2
-rw-r--r--engines/saga/resource.h2
-rw-r--r--engines/saga/saga.h12
-rw-r--r--engines/saga/script.h4
-rw-r--r--engines/saga/sndres.cpp228
-rw-r--r--engines/saga/sndres.h3
-rw-r--r--engines/saga/sound.cpp35
-rw-r--r--engines/saga/sound.h19
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 {