aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/resource.cpp72
-rw-r--r--engines/sci/resource.h3
-rw-r--r--engines/sci/resource_audio.cpp63
-rw-r--r--engines/sci/sound/audio.cpp24
4 files changed, 90 insertions, 72 deletions
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 307b4e888e..0b7badb8f7 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -481,6 +481,7 @@ int ResourceManager::addAppropriateSources() {
addPatchDir("Robot Folder");
addPatchDir("Sound Folder");
addPatchDir("Voices Folder");
+ addPatchDir("Voices");
//addPatchDir("VMD Folder");
// There can also be a "Patches" resource fork with patches
@@ -620,11 +621,11 @@ void ResourceManager::scanNewSources() {
switch (source->source_type) {
case kSourceDirectory:
readResourcePatches(source);
-#ifdef ENABLE_SCI32
+
// We can't use getSciVersion() at this point, thus using _volVersion
if (_volVersion >= kResVersionSci11) // SCI1.1+
readResourcePatchesBase36(source);
-#endif
+
readWaveAudioPatches();
break;
case kSourceExtMap:
@@ -1070,18 +1071,14 @@ ResourceManager::ResVersion ResourceManager::detectVolVersion() {
// version-agnostic patch application
void ResourceManager::processPatch(ResourceSource *source, ResourceType resourceType, uint16 resourceNr, uint32 tuple) {
Common::SeekableReadStream *fileStream = 0;
- Resource *newrsc;
+ Resource *newrsc = 0;
ResourceId resId = ResourceId(resourceType, resourceNr, tuple);
ResourceType checkForType = resourceType;
- byte patchType, patchDataOffset;
- int fsize;
- uint32 audio36Header = 0;
// base36 encoded patches (i.e. audio36 and sync36) have the same type as their non-base36 encoded counterparts
if (checkForType == kResourceTypeAudio36)
checkForType = kResourceTypeAudio;
-
- if (checkForType == kResourceTypeSync36)
+ else if (checkForType == kResourceTypeSync36)
checkForType = kResourceTypeSync;
if (source->resourceFile) {
@@ -1094,18 +1091,15 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource
}
fileStream = file;
}
- fsize = fileStream->size();
+
+ int fsize = fileStream->size();
if (fsize < 3) {
debug("Patching %s failed - file too small", source->location_name.c_str());
return;
}
- patchType = fileStream->readByte() & 0x7F;
- patchDataOffset = fileStream->readByte();
-
- if (resourceType == kResourceTypeAudio36) {
- audio36Header = fileStream->readUint32BE();
- }
+ byte patchType = fileStream->readByte() & 0x7F;
+ byte patchDataOffset = fileStream->readByte();
delete fileStream;
@@ -1114,13 +1108,6 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource
return;
}
- if (resourceType == kResourceTypeAudio36) {
- if (audio36Header != MKID_BE('SOL\x00')) {
- debug("Patching %s failed - audio36 patch doesn't have SOL header", source->location_name.c_str());
- return;
- }
- }
-
// Fixes SQ5/German, patch file special case logic taken from SCI View disassembly
if (patchDataOffset & 0x80) {
switch (patchDataOffset & 0x7F) {
@@ -1144,12 +1131,14 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource
source->location_name.c_str(), patchDataOffset + 2, fsize);
return;
}
+
// Prepare destination, if neccessary
if (_resMap.contains(resId) == false) {
newrsc = new Resource;
_resMap.setVal(resId, newrsc);
} else
newrsc = _resMap.getVal(resId);
+
// Overwrite everything, because we're patching
newrsc->_id = resId;
newrsc->_status = kResStatusNoMalloc;
@@ -1160,8 +1149,6 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType resource
debugC(1, kDebugLevelResMan, "Patching %s - OK", source->location_name.c_str());
}
-#ifdef ENABLE_SCI32
-
void ResourceManager::readResourcePatchesBase36(ResourceSource *source) {
// The base36 encoded audio36 and sync36 resources use a different naming scheme, because they
// cannot be described with a single resource number, but are a result of a
@@ -1192,19 +1179,20 @@ void ResourceManager::readResourcePatchesBase36(ResourceSource *source) {
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
name = (*x)->getName();
+
inputName = (*x)->getName();
inputName.toUppercase();
-
inputName.deleteChar(0); // delete the first character (type)
inputName.deleteChar(7); // delete the dot
// The base36 encoded resource contains the following:
// uint16 resourceId, byte noun, byte verb, byte cond, byte seq
- uint16 resourceNr = strtol(Common::String(inputName.c_str(), 3).c_str(), 0, 36); // 3 characters
- uint16 noun = strtol(Common::String(inputName.c_str() + 3, 2).c_str(), 0, 36); // 2 characters
- uint16 verb = strtol(Common::String(inputName.c_str() + 5, 2).c_str(), 0, 36); // 2 characters
- uint16 cond = strtol(Common::String(inputName.c_str() + 7, 2).c_str(), 0, 36); // 2 characters
- uint16 seq = strtol(Common::String(inputName.c_str() + 9, 1).c_str(), 0, 36); // 1 character
+ uint16 resourceNr = strtol(Common::String(inputName.c_str(), 3).c_str(), 0, 36); // 3 characters
+ uint16 noun = strtol(Common::String(inputName.c_str() + 3, 2).c_str(), 0, 36); // 2 characters
+ uint16 verb = strtol(Common::String(inputName.c_str() + 5, 2).c_str(), 0, 36); // 2 characters
+ uint16 cond = strtol(Common::String(inputName.c_str() + 7, 2).c_str(), 0, 36); // 2 characters
+ uint16 seq = strtol(Common::String(inputName.c_str() + 9, 1).c_str(), 0, 36); // 1 character
+
// Check, if we got valid results
if ((noun <= 255) && (verb <= 255) && (cond <= 255) && (seq <= 255)) {
ResourceId resource36((ResourceType)i, resourceNr, noun, verb, cond, seq);
@@ -1216,6 +1204,28 @@ void ResourceManager::readResourcePatchesBase36(ResourceSource *source) {
debug("sync36 patch: %s => %s. tuple:%d, %s\n", name.c_str(), inputName.c_str(), resource36.tuple, resource36.toString().c_str());
*/
+ // Make sure that the audio patch is a valid resource
+ if (i == kResourceTypeAudio36) {
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name);
+ uint32 tag = stream->readUint32BE();
+
+ if (tag == MKID_BE('RIFF') || tag == MKID_BE('FORM')) {
+ delete stream;
+ processWavePatch(resource36, name);
+ continue;
+ }
+
+ // Check for SOL as well
+ tag = (tag << 16) | stream->readUint16BE();
+
+ if (tag != MKID_BE('SOL\0')) {
+ delete stream;
+ continue;
+ }
+
+ delete stream;
+ }
+
psrcPatch = new ResourceSource;
psrcPatch->source_type = kSourcePatch;
psrcPatch->location_name = name;
@@ -1226,8 +1236,6 @@ void ResourceManager::readResourcePatchesBase36(ResourceSource *source) {
}
}
-#endif
-
void ResourceManager::readResourcePatches(ResourceSource *source) {
// Note: since some SCI1 games(KQ5 floppy, SQ4) might use SCI0 naming scheme for patch files
// this function tries to read patch file with any supported naming scheme,
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 533c81bdf5..66742f11f5 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -452,15 +452,14 @@ protected:
* Reads patch files from a local directory.
*/
void readResourcePatches(ResourceSource *source);
-#ifdef ENABLE_SCI32
void readResourcePatchesBase36(ResourceSource *source);
-#endif
void processPatch(ResourceSource *source, ResourceType resourceType, uint16 resourceNr, uint32 tuple = 0);
/**
* Process wave files as patches for Audio resources
*/
void readWaveAudioPatches();
+ void processWavePatch(ResourceId resourceId, Common::String name);
/**
* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2).
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 2a5b56d4bc..861866edc0 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -162,6 +162,34 @@ void ResourceManager::addNewGMPatch(const Common::String &gameId) {
}
}
+void ResourceManager::processWavePatch(ResourceId resourceId, Common::String name) {
+ ResourceSource *resSrc = new ResourceSource;
+ resSrc->source_type = kSourceWave;
+ resSrc->resourceFile = 0;
+ resSrc->location_name = name;
+ resSrc->volume_number = 0;
+ resSrc->audioCompressionType = 0;
+
+ Resource *newRes = 0;
+
+ if (_resMap.contains(resourceId)) {
+ newRes = _resMap.getVal(resourceId);
+ } else {
+ newRes = new Resource;
+ _resMap.setVal(resourceId, newRes);
+ }
+
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name);
+ newRes->size = stream->size();
+ delete stream;
+
+ newRes->_id = resourceId;
+ newRes->_status = kResStatusNoMalloc;
+ newRes->_source = resSrc;
+ newRes->_headerSize = 0;
+ debugC(1, kDebugLevelResMan, "Patching %s - OK", name.c_str());
+}
+
void ResourceManager::readWaveAudioPatches() {
// Here we do check for SCI1.1+ so we can patch wav files in as audio resources
Common::ArchiveMemberList files;
@@ -170,39 +198,8 @@ void ResourceManager::readWaveAudioPatches() {
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
Common::String name = (*x)->getName();
- if (isdigit(name[0])) {
- int number = atoi(name.c_str());
- ResourceSource *psrcPatch = new ResourceSource;
- psrcPatch->source_type = kSourceWave;
- psrcPatch->resourceFile = 0;
- psrcPatch->location_name = name;
- psrcPatch->volume_number = 0;
- psrcPatch->audioCompressionType = 0;
-
- ResourceId resId = ResourceId(kResourceTypeAudio, number);
-
- Resource *newrsc = NULL;
-
- // Prepare destination, if neccessary
- if (_resMap.contains(resId) == false) {
- newrsc = new Resource;
- _resMap.setVal(resId, newrsc);
- } else
- newrsc = _resMap.getVal(resId);
-
- // Get the size of the file
- Common::SeekableReadStream *stream = (*x)->createReadStream();
- uint32 fileSize = stream->size();
- delete stream;
-
- // Overwrite everything, because we're patching
- newrsc->_id = resId;
- newrsc->_status = kResStatusNoMalloc;
- newrsc->_source = psrcPatch;
- newrsc->size = fileSize;
- newrsc->_headerSize = 0;
- debugC(1, kDebugLevelResMan, "Patching %s - OK", psrcPatch->location_name.c_str());
- }
+ if (isdigit(name[0]))
+ processWavePatch(ResourceId(kResourceTypeAudio, atoi(name.c_str())), name);
}
}
diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 7748c0505b..f10cc5ed68 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -24,21 +24,22 @@
*/
#include "sci/resource.h"
-#include "sci/engine/selector.h"
#include "sci/engine/kernel.h"
+#include "sci/engine/selector.h"
#include "sci/engine/seg_manager.h"
#include "sci/sound/audio.h"
-#include "common/system.h"
#include "common/file.h"
+#include "common/system.h"
-#include "sound/audiostream.h"
#include "sound/audiocd.h"
-#include "sound/decoders/raw.h"
-#include "sound/decoders/wave.h"
+#include "sound/audiostream.h"
+#include "sound/decoders/aiff.h"
#include "sound/decoders/flac.h"
#include "sound/decoders/mp3.h"
+#include "sound/decoders/raw.h"
#include "sound/decoders/vorbis.h"
+#include "sound/decoders/wave.h"
namespace Sci {
@@ -287,6 +288,19 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
waveStream->seek(0, SEEK_SET);
audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
+ } else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKID_BE('FORM')) {
+ // AIFF detected
+ Common::MemoryReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
+
+ // Calculate samplelen from AIFF header
+ int waveSize = 0, waveRate = 0;
+ byte waveFlags = 0;
+ Audio::loadAIFFFromStream(*waveStream, waveSize, waveRate, waveFlags);
+ *sampleLen = (waveFlags & Audio::FLAG_16BITS ? waveSize >> 1 : waveSize) * 60 / waveRate;
+
+ waveStream->seek(0, SEEK_SET);
+ audioStream = Audio::makeAIFFStream(*waveStream);
+ delete waveStream; // makeAIFFStream doesn't handle this for us
} else if (audioRes->size > 14 && READ_BE_UINT16(audioRes->data) == 1 && READ_BE_UINT16(audioRes->data + 2) == 1
&& READ_BE_UINT16(audioRes->data + 4) == 5 && READ_BE_UINT32(audioRes->data + 10) == 0x00018051) {
// Mac snd detected