[Scummvm-cvs-logs] SF.net SVN: scummvm:[49576] scummvm/trunk/engines/sci

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Thu Jun 10 17:06:25 CEST 2010


Revision: 49576
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49576&view=rev
Author:   mthreepwood
Date:     2010-06-10 15:06:25 +0000 (Thu, 10 Jun 2010)

Log Message:
-----------
Add support for AIFF sound in SCI32 Mac games and add support for AIFF/WAVE audio36 patches; minor cleanup.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/resource.cpp
    scummvm/trunk/engines/sci/resource.h
    scummvm/trunk/engines/sci/resource_audio.cpp
    scummvm/trunk/engines/sci/sound/audio.cpp

Modified: scummvm/trunk/engines/sci/resource.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource.cpp	2010-06-10 14:02:20 UTC (rev 49575)
+++ scummvm/trunk/engines/sci/resource.cpp	2010-06-10 15:06:25 UTC (rev 49576)
@@ -481,6 +481,7 @@
 		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 @@
 			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 @@
 // 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,19 +1091,16 @@
 		}
 		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();
+	byte patchType = fileStream->readByte() & 0x7F;
+	byte patchDataOffset = fileStream->readByte();
 
-	if (resourceType == kResourceTypeAudio36) {
-		audio36Header = fileStream->readUint32BE();
-	}
-
 	delete fileStream;
 
 	if (patchType != checkForType) {
@@ -1114,13 +1108,6 @@
 		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 @@
 		      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 @@
 	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 @@
 
 		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 @@
 					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 @@
 	}
 }
 
-#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,

Modified: scummvm/trunk/engines/sci/resource.h
===================================================================
--- scummvm/trunk/engines/sci/resource.h	2010-06-10 14:02:20 UTC (rev 49575)
+++ scummvm/trunk/engines/sci/resource.h	2010-06-10 15:06:25 UTC (rev 49576)
@@ -452,15 +452,14 @@
 	 * 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).

Modified: scummvm/trunk/engines/sci/resource_audio.cpp
===================================================================
--- scummvm/trunk/engines/sci/resource_audio.cpp	2010-06-10 14:02:20 UTC (rev 49575)
+++ scummvm/trunk/engines/sci/resource_audio.cpp	2010-06-10 15:06:25 UTC (rev 49576)
@@ -162,6 +162,34 @@
 	}
 }
 
+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 @@
 	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);
 	}
 }
 

Modified: scummvm/trunk/engines/sci/sound/audio.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/audio.cpp	2010-06-10 14:02:20 UTC (rev 49575)
+++ scummvm/trunk/engines/sci/sound/audio.cpp	2010-06-10 15:06:25 UTC (rev 49576)
@@ -24,21 +24,22 @@
  */
 
 #include "sci/resource.h"
+#include "sci/engine/kernel.h"
 #include "sci/engine/selector.h"
-#include "sci/engine/kernel.h"
 #include "sci/engine/seg_manager.h"
 #include "sci/sound/audio.h"
 
+#include "common/file.h"
 #include "common/system.h"
-#include "common/file.h"
 
+#include "sound/audiocd.h"
 #include "sound/audiostream.h"
-#include "sound/audiocd.h"
-#include "sound/decoders/raw.h"
-#include "sound/decoders/wave.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 @@
 
 			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


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