[Scummvm-cvs-logs] SF.net SVN: scummvm:[55674] scummvm/trunk/engines/saga

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Jan 31 11:46:54 CET 2011


Revision: 55674
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55674&view=rev
Author:   thebluegr
Date:     2011-01-31 10:46:52 +0000 (Mon, 31 Jan 2011)

Log Message:
-----------
SAGA: Rewrote the MacBinary resource loading code

This simplifies the overall code and makes it easier to understand. Also, a bug with the
speech in the MacBinary packed version has been corrected, so there are no more clicking
sounds before each sample.
The Common::MacResMan code isn't really useful here, since it doesn't expose the offsets
and sizes of the actual files, which is what is needed in SAGA.

Modified Paths:
--------------
    scummvm/trunk/engines/saga/resource.cpp
    scummvm/trunk/engines/saga/resource.h
    scummvm/trunk/engines/saga/resource_rsc.cpp

Modified: scummvm/trunk/engines/saga/resource.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource.cpp	2011-01-31 08:51:37 UTC (rev 55673)
+++ scummvm/trunk/engines/saga/resource.cpp	2011-01-31 10:46:52 UTC (rev 55674)
@@ -83,7 +83,7 @@
 			resourceData = &_table[i];
 			resourceData->offset = contextOffset + readS1.readUint32();
 			resourceData->size = readS1.readUint32();
-			//sanity check
+			// Sanity check
 			if ((resourceData->offset > (uint)_fileSize) || (resourceData->size > contextSize)) {
 				result = false;
 				break;
@@ -103,15 +103,12 @@
 	uint32 subjectResourceId;
 	uint32 patchResourceId;
 	ResourceData *subjectResourceData;
-	bool isMacBinary;
 
-	if (_fileName == NULL) { // IHNM special case
+	if (_fileName == NULL) // IHNM special case
 		return true;
-	}
 
-	if (!_file.open(_fileName)) {
+	if (!_file.open(_fileName))
 		return false;
-	}
 
 	_fileSize = _file.size();
 	_isBigEndian = vm->isBigEndian();
@@ -119,20 +116,25 @@
 	if (_fileType & GAME_SWAPENDIAN)
 		_isBigEndian = !_isBigEndian;
 
-	isMacBinary = (_fileType & GAME_MACBINARY) > 0;
-	_fileType &= ~GAME_MACBINARY;
-
-	if (!isMacBinary) {
-		if (!loadRes(0, _fileSize)) {
-			return false;
+	if (_fileType & GAME_MACBINARY) {
+		// Special case for the MacBinary packed files in the old Mac ITE
+		// release. There are no patch files in this case.
+		if (!(_fileType & GAME_MUSICFILE_GM)) {
+			// Find the actual size, as there may be padded data in the end.
+			_file.seek(83);
+			uint32 macDataSize = _file.readSint32BE();
+			// Skip the MacBinary headers, and read the resource data.
+			return loadRes(MAC_BINARY_HEADER_SIZE, macDataSize);
+		} else {
+			// Unpack MacBinady packed MIDI files
+			return loadMacMIDI();
 		}
-	} else {
-		if (!loadMac()) {
-			return false;
-		}
 	}
 
-	//process internal patch files
+	if (!loadRes(0, _fileSize))
+		return false;
+
+	// Process internal patch files
 	if (_fileType & GAME_PATCHFILE) {
 		subjectResourceType = ~GAME_PATCHFILE & _fileType;
 		subjectContext = resource->getContext((GameFileTypes)subjectResourceType);
@@ -155,7 +157,7 @@
 		}
 	}
 
-	//process external patch files
+	// Process external patch files
 	for (patchDescription = vm->getPatchDescriptions(); patchDescription && patchDescription->fileName; ++patchDescription) {
 		if ((patchDescription->fileType & _fileType) != 0) {
 			if (patchDescription->resourceId < _table.size()) {

Modified: scummvm/trunk/engines/saga/resource.h
===================================================================
--- scummvm/trunk/engines/saga/resource.h	2011-01-31 08:51:37 UTC (rev 55673)
+++ scummvm/trunk/engines/saga/resource.h	2011-01-31 10:46:52 UTC (rev 55674)
@@ -84,22 +84,6 @@
 
 class ResourceContext {
 friend class Resource;
-protected:
-	const char *_fileName;
-	uint16 _fileType;
-	bool _isCompressed;
-	int _serial;					// IHNM speech files
-
-	bool _isBigEndian;
-	ResourceDataArray _table;
-	Common::File _file;
-	int32 _fileSize;
-
-	bool load(SagaEngine *_vm, Resource *resource);
-	bool loadResV1(uint32 contextOffset, uint32 contextSize);
-
-	virtual bool loadMac() = 0;
-	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) = 0;
 public:
 
 	ResourceContext():
@@ -172,6 +156,22 @@
 		}
 		return -1;
 	}
+protected:
+	const char *_fileName;
+	uint16 _fileType;
+	bool _isCompressed;
+	int _serial;					// IHNM speech files
+
+	bool _isBigEndian;
+	ResourceDataArray _table;
+	Common::File _file;
+	int32 _fileSize;
+
+	bool load(SagaEngine *_vm, Resource *resource);
+	bool loadResV1(uint32 contextOffset, uint32 contextSize);
+
+	virtual bool loadMacMIDI() = 0;
+	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) = 0;
 };
 
 class ResourceContextList : public Common::List<ResourceContext*> {
@@ -228,7 +228,7 @@
 // ITE
 class ResourceContext_RSC: public ResourceContext {
 protected:
-	virtual bool loadMac();
+	virtual bool loadMacMIDI();
 	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
 		return loadResV1(contextOffset, contextSize);
 	}
@@ -237,7 +237,9 @@
 class Resource_RSC : public Resource {
 public:
 	Resource_RSC(SagaEngine *vm) : Resource(vm) {}
-	virtual uint32 convertResourceId(uint32 resourceId);
+	virtual uint32 convertResourceId(uint32 resourceId) {
+		return _vm->isMacResources() ? resourceId - 2 : resourceId;
+	}
 	virtual void loadGlobalResources(int chapter, int actorsEntrance) {}
 	virtual MetaResource* getMetaResource() {
 		MetaResource *dummy = 0;
@@ -253,20 +255,16 @@
 // IHNM
 class ResourceContext_RES: public ResourceContext {
 protected:
-	virtual bool loadMac() {
-		return false;
-	}
+	virtual bool loadMacMIDI() { return false; }
 	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
 		return loadResV1(0, contextSize);
 	}
 };
 
-//TODO: move load routines from sndres
+// TODO: move load routines from sndres
 class VoiceResourceContext_RES: public ResourceContext {
 protected:
-	virtual bool loadMac() {
-		return false;
-	}
+	virtual bool loadMacMIDI() { return false; }
 	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
 		return false;
 	}
@@ -298,9 +296,7 @@
 protected:
 	ResourceDataArray _categories;
 
-	virtual bool loadMac() {
-		return false;
-	}
+	virtual bool loadMacMIDI() { return false; }
 	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
 		return loadResV2(contextSize);
 	}

Modified: scummvm/trunk/engines/saga/resource_rsc.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_rsc.cpp	2011-01-31 08:51:37 UTC (rev 55673)
+++ scummvm/trunk/engines/saga/resource_rsc.cpp	2011-01-31 10:46:52 UTC (rev 55674)
@@ -26,142 +26,62 @@
 // RSC Resource file management module (SAGA 1, used in ITE)
 
 #include "saga/saga.h"
-
-#include "saga/actor.h"
-#include "saga/animation.h"
-#include "saga/interface.h"
-#include "saga/music.h"
 #include "saga/resource.h"
-#include "saga/scene.h"
-#include "saga/sndres.h"
 
-#include "engines/advancedDetector.h"
-
 namespace Saga {
 
-struct MacResource {
-	int16 id;
-	int32 dataOffset;
-	MacResource() : id(0), dataOffset(0) {}
-};
-
-class MacResourceArray : public Common::Array<MacResource> {
-};
-
-struct MacResType {
-	uint32 id;
-	int16 maxItemId;
-	int16 offset;
-	MacResourceArray resources;
-	MacResType() : id(0), maxItemId(0), offset(0) {
-	}
-};
-
-class MacResTypeArray : public Common::Array<MacResType> {
-};
-
 #define ID_MIDI     MKID_BE('Midi')
 
-bool ResourceContext_RSC::loadMac() {
-	int32 macDataSize, macResSizePad, macResOffset;
-	uint32 macMapOffset, macDataOffset;
-
-	MacResTypeArray macResTypes;
-
-	bool notSagaContext = false;
-
+bool ResourceContext_RSC::loadMacMIDI() {
 	// Sanity check
 	if (_fileSize < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE)
 		return false;
 
-	_file.seek(82);
-	if (_file.readByte() != 0)
-		return false;
+	_file.seek(83);
+	int macDataSize = _file.readSint32BE();
+	int macResOffset = MAC_BINARY_HEADER_SIZE + (((macDataSize + 127) >> 7) << 7);
 
-	macDataSize = _file.readSint32BE();
-	macResOffset = MAC_BINARY_HEADER_SIZE + (((macDataSize + 127) >> 7) << 7);
-
-	macResSizePad = (((_file.readSint32BE() + 127) >> 7) << 7);
 	_file.seek(macResOffset);
+	uint32 macDataOffset = _file.readUint32BE() + macResOffset;
+	uint32 macMapOffset = _file.readUint32BE() + macResOffset;
 
-	macDataOffset = _file.readUint32BE() + macResOffset;
-	macMapOffset = _file.readUint32BE() + macResOffset;
-	// Used for sanity checks
-	uint32 macDataLength = _file.readUint32BE();
-	uint32 macMapLength = _file.readUint32BE();
-
-	if (macDataOffset >= (uint)_fileSize || macMapOffset >= (uint)_fileSize ||
-		macDataLength + macMapLength > (uint)_fileSize)
-			return false;
-
 	_file.seek(macMapOffset + 22);
-
 	_file.readUint16BE();	// resAttr
 	int16 typeOffset = _file.readUint16BE();
 	_file.readUint16BE();	// nameOffset
-	int16 numTypes = _file.readUint16BE() + 1;
-	macResTypes.resize(numTypes);
+	uint16 numTypes = _file.readUint16BE() + 1;
 
 	_file.seek(macMapOffset + typeOffset + 2);
 
-	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
-		k->id = _file.readUint32BE();
-		int16 items = _file.readUint16BE() + 1;
-		k->resources.resize(items);
-		k->offset = _file.readUint16BE();
-	}
+	// Find the MIDI files
+	for (uint16 i = 0; i < numTypes; i++) {
+		uint32 id = _file.readUint32BE();
+		uint16 items = _file.readUint16BE() + 1;
+		uint16 offset = _file.readUint16BE();
 
-	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
-		_file.seek(k->offset + macMapOffset + typeOffset);
+		if (id == ID_MIDI) {
+			for (uint16 curMidi = 0; curMidi < items; curMidi++) {
+				// Jump to the header of the entry and read its fields
+				_file.seek(offset + macMapOffset + typeOffset + curMidi * 12);
+				uint16 midiID = _file.readUint16BE();
+				_file.readUint16BE();	// nameOffset
+				uint32 midiOffset = _file.readUint32BE() & 0xFFFFFF;
+				_file.readUint32BE();	// macResSize
 
-		for (MacResourceArray::iterator j = k->resources.begin(); j != k->resources.end(); ++j) {
-			j->id = _file.readUint16BE();
-			_file.readUint16BE();	// nameOffset
-			j->dataOffset = _file.readUint32BE();
-			_file.readUint32BE();	// macResSize
+				// Jump to the actual data and read the file size
+				_file.seek(macDataOffset + midiOffset);
+				uint32 midiSize = _file.readUint32BE();
 
-			j->dataOffset &= 0xFFFFFF;
-			if (j->id > k->maxItemId)
-				k->maxItemId = j->id;
-		}
-	}
-
-	//
-	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
-		//getting offsets & sizes of midi
-		if (((_fileType & GAME_MUSICFILE_GM) > 0) && (k->id == ID_MIDI)) {
-
-			_table.resize(k->maxItemId + 1);
-			for (MacResourceArray::iterator j = k->resources.begin(); j != k->resources.end(); ++j) {
-				_file.seek(macDataOffset + j->dataOffset);
-				_table[j->id].size = _file.readUint32BE();
-				_table[j->id].offset = _file.pos();
+				// Add the entry
+				if (_table.size() <= midiID)
+					_table.resize(midiID + 1);
+				_table[midiID].offset = macDataOffset + midiOffset + 4;
+				_table[midiID].size = midiSize;
 			}
-			notSagaContext = true;
-			break;
 		}
 	}
 
-	if ((!notSagaContext) && (!loadRes(MAC_BINARY_HEADER_SIZE, macDataSize))) {
-		return false;
-	}
-
 	return true;
 }
 
-uint32 Resource_RSC::convertResourceId(uint32 resourceId) {
-
-	if (_vm->isMacResources()) {
-		if (resourceId > 1537) {
-			return resourceId - 2;
-		} else {
-			if (resourceId == 1535 || resourceId == 1536) {
-				error("Wrong resource number %d for Mac ITE", resourceId);
-			}
-		}
-	}
-
-	return resourceId;
-}
-
 } // End of namespace Saga


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