diff options
| -rw-r--r-- | engines/saga/resource.cpp | 38 | ||||
| -rw-r--r-- | engines/saga/resource.h | 52 | ||||
| -rw-r--r-- | engines/saga/resource_rsc.cpp | 142 | 
3 files changed, 75 insertions, 157 deletions
| diff --git a/engines/saga/resource.cpp b/engines/saga/resource.cpp index 169c901950..0ef0d438d9 100644 --- a/engines/saga/resource.cpp +++ b/engines/saga/resource.cpp @@ -83,7 +83,7 @@ bool ResourceContext::loadResV1(uint32 contextOffset, uint32 contextSize) {  			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 @@ bool ResourceContext::load(SagaEngine *vm, Resource *resource) {  	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 @@ bool ResourceContext::load(SagaEngine *vm, Resource *resource) {  	if (_fileType & GAME_SWAPENDIAN)  		_isBigEndian = !_isBigEndian; -	isMacBinary = (_fileType & GAME_MACBINARY) > 0; -	_fileType &= ~GAME_MACBINARY; - -	if (!isMacBinary) { -		if (!loadRes(0, _fileSize)) { -			return false; -		} -	} else { -		if (!loadMac()) { -			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();  		}  	} -	//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 @@ bool ResourceContext::load(SagaEngine *vm, Resource *resource) {  		}  	} -	//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()) { diff --git a/engines/saga/resource.h b/engines/saga/resource.h index 5009c862f4..048ed3933d 100644 --- a/engines/saga/resource.h +++ b/engines/saga/resource.h @@ -84,22 +84,6 @@ class ResourceDataArray : public Common::Array<ResourceData> {  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 @@ public:  		}  		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 @@ public:  // 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 @@ protected:  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 @@ protected:  // 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 @@ class ResourceContext_HRS: public ResourceContext {  protected:  	ResourceDataArray _categories; -	virtual bool loadMac() { -		return false; -	} +	virtual bool loadMacMIDI() { return false; }  	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {  		return loadResV2(contextSize);  	} diff --git a/engines/saga/resource_rsc.cpp b/engines/saga/resource_rsc.cpp index b07741436b..6d9ef70bfe 100644 --- a/engines/saga/resource_rsc.cpp +++ b/engines/saga/resource_rsc.cpp @@ -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; - -	macDataSize = _file.readSint32BE(); -	macResOffset = MAC_BINARY_HEADER_SIZE + (((macDataSize + 127) >> 7) << 7); +	_file.seek(83); +	int macDataSize = _file.readSint32BE(); +	int macResOffset = MAC_BINARY_HEADER_SIZE + (((macDataSize + 127) >> 7) << 7); -	macResSizePad = (((_file.readSint32BE() + 127) >> 7) << 7);  	_file.seek(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; +	uint32 macDataOffset = _file.readUint32BE() + macResOffset; +	uint32 macMapOffset = _file.readUint32BE() + macResOffset;  	_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(); -	} - -	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) { -		_file.seek(k->offset + macMapOffset + typeOffset); - -		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 - -			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(); +	// Find the MIDI files +	for (uint16 i = 0; i < numTypes; i++) { +		uint32 id = _file.readUint32BE(); +		uint16 items = _file.readUint16BE() + 1; +		uint16 offset = _file.readUint16BE(); + +		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 + +				// Jump to the actual data and read the file size +				_file.seek(macDataOffset + midiOffset); +				uint32 midiSize = _file.readUint32BE(); + +				// 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 | 
