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

h00ligan at users.sourceforge.net h00ligan at users.sourceforge.net
Fri Dec 4 18:52:42 CET 2009


Revision: 46254
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46254&view=rev
Author:   h00ligan
Date:     2009-12-04 17:52:42 +0000 (Fri, 04 Dec 2009)

Log Message:
-----------
refactor resource module:
- struct ResourceContext => class ResourceContext
- replace "*alloc","free" with array templates
- simplify createContexts routines

Modified Paths:
--------------
    scummvm/trunk/engines/saga/actor.cpp
    scummvm/trunk/engines/saga/font.cpp
    scummvm/trunk/engines/saga/music.cpp
    scummvm/trunk/engines/saga/resource.cpp
    scummvm/trunk/engines/saga/resource.h
    scummvm/trunk/engines/saga/resource_hrs.cpp
    scummvm/trunk/engines/saga/resource_rsc.cpp
    scummvm/trunk/engines/saga/saga.h
    scummvm/trunk/engines/saga/scene.cpp
    scummvm/trunk/engines/saga/script.cpp
    scummvm/trunk/engines/saga/sndres.cpp
    scummvm/trunk/engines/saga/sprite.cpp

Modified: scummvm/trunk/engines/saga/actor.cpp
===================================================================
--- scummvm/trunk/engines/saga/actor.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/actor.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -352,7 +352,7 @@
 		memoryError("Actor::loadFrameList");
 	}
 
-	MemoryReadStreamEndian readS(resourcePointer, resourceLength, _actorContext->isBigEndian);
+	MemoryReadStreamEndian readS(resourcePointer, resourceLength, _actorContext->isBigEndian());
 
 	for (int i = 0; i < framesCount; i++) {
 		debug(9, "frameType %d", i);

Modified: scummvm/trunk/engines/saga/font.cpp
===================================================================
--- scummvm/trunk/engines/saga/font.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/font.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -90,7 +90,7 @@
 		error("Font::loadFont() Invalid font length (%i < %i)", (int)fontResourceLength, FONT_DESCSIZE);
 	}
 
-	MemoryReadStreamEndian readS(fontResourcePointer, fontResourceLength, fontContext->isBigEndian);
+	MemoryReadStreamEndian readS(fontResourcePointer, fontResourceLength, fontContext->isBigEndian());
 
 	// Create new font structure
 	font = (FontData *)malloc(sizeof(*font));

Modified: scummvm/trunk/engines/saga/music.cpp
===================================================================
--- scummvm/trunk/engines/saga/music.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/music.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -296,12 +296,12 @@
 				// Digital music
 				ResourceData *resData = _digitalMusicContext->getResourceData(resourceId - 9);
 				Common::File *musicFile = _digitalMusicContext->getFile(resData);
-				int offs = (_digitalMusicContext->isCompressed) ? 9 : 0;
+				int offs = (_digitalMusicContext->isCompressed()) ? 9 : 0;
 
 				Common::SeekableSubReadStream *musicStream = new Common::SeekableSubReadStream(musicFile, 
 							(uint32)resData->offset + offs, (uint32)resData->offset + resData->size - offs);
 
-				if (!_digitalMusicContext->isCompressed) {
+				if (!_digitalMusicContext->isCompressed()) {
 					byte musicFlags = Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_STEREO | 
 										Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN;
 					if (flags == MUSIC_LOOP)

Modified: scummvm/trunk/engines/saga/resource.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/resource.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -39,21 +39,13 @@
 
 namespace Saga {
 
-Resource::Resource(SagaEngine *vm): _vm(vm) {
-	_contexts = NULL;
-	_contextsCount = 0;
-}
-
-Resource::~Resource() {
-	clearContexts();
-}
-
-bool Resource::loadResContext_v1(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+bool ResourceContext::loadResV1(uint32 contextOffset, uint32 contextSize) {
 	size_t i;
 	bool result;
 	byte tableInfo[RSC_TABLEINFO_SIZE];
 	byte *tableBuffer;
 	size_t tableSize;
+	uint32 count;
 	uint32 resourceTableOffset;
 	ResourceData *resourceData;
 
@@ -61,41 +53,41 @@
 		return false;
 	}
 
-	context->file->seek(contextOffset + contextSize - RSC_TABLEINFO_SIZE);
+	_file.seek(contextOffset + contextSize - RSC_TABLEINFO_SIZE);
 
-	if (context->file->read(tableInfo, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) {
+	if (_file.read(tableInfo, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) {
 		return false;
 	}
 
-	MemoryReadStreamEndian readS(tableInfo, RSC_TABLEINFO_SIZE, context->isBigEndian);
+	MemoryReadStreamEndian readS(tableInfo, RSC_TABLEINFO_SIZE, _isBigEndian);
 
 	resourceTableOffset = readS.readUint32();
-	context->count = readS.readUint32();
+	count = readS.readUint32();
 
 	// Check for sane table offset
-	if (resourceTableOffset != contextSize - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * context->count) {
+	if (resourceTableOffset != contextSize - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * count) {
 		return false;
 	}
 
 	// Load resource table
-	tableSize = RSC_TABLEENTRY_SIZE * context->count;
+	tableSize = RSC_TABLEENTRY_SIZE * count;
 
 	tableBuffer = (byte *)malloc(tableSize);
 
-	context->file->seek(resourceTableOffset + contextOffset, SEEK_SET);
+	_file.seek(resourceTableOffset + contextOffset, SEEK_SET);
 
-	result = (context->file->read(tableBuffer, tableSize) == tableSize);
+	result = (_file.read(tableBuffer, tableSize) == tableSize);
 	if (result) {
-		context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
+		_table.resize(count);
 
-		MemoryReadStreamEndian readS1(tableBuffer, tableSize, context->isBigEndian);
+		MemoryReadStreamEndian readS1(tableBuffer, tableSize, _isBigEndian);
 
-		for (i = 0; i < context->count; i++) {
-			resourceData = &context->table[i];
+		for (i = 0; i < count; i++) {
+			resourceData = &_table[i];
 			resourceData->offset = contextOffset + readS1.readUint32();
 			resourceData->size = readS1.readUint32();
 			//sanity check
-			if ((resourceData->offset > (uint)context->fileSize) || (resourceData->size > contextSize)) {
+			if ((resourceData->offset > (uint)_fileSize) || (resourceData->size > contextSize)) {
 				result = false;
 				break;
 			}
@@ -106,7 +98,7 @@
 	return result;
 }
 
-bool Resource::loadContext(ResourceContext *context) {
+bool ResourceContext::load(SagaEngine *vm, Resource *resource) {
 	size_t i;
 	const GamePatchDescription *patchDescription;
 	ResourceData *resourceData;
@@ -119,45 +111,49 @@
 	size_t tableSize;
 	bool isMacBinary;
 
-	if (!context->file->open(context->fileName)) {
+	if (_fileName == NULL) { // IHNM special case
+		return true;
+	}
+
+	if (!_file.open(_fileName)) {
 		return false;
 	}
 
-	context->fileSize = context->file->size();
-	context->isBigEndian = _vm->isBigEndian();
+	_fileSize = _file.size();
+	_isBigEndian = vm->isBigEndian();
 
-	if (context->fileType & GAME_SWAPENDIAN)
-		context->isBigEndian = !context->isBigEndian;
+	if (_fileType & GAME_SWAPENDIAN)
+		_isBigEndian = !_isBigEndian;
 
-	isMacBinary = (context->fileType & GAME_MACBINARY) > 0;
-	context->fileType &= ~GAME_MACBINARY;
+	isMacBinary = (_fileType & GAME_MACBINARY) > 0;
+	_fileType &= ~GAME_MACBINARY;
 
 	if (!isMacBinary) {
-		if (!loadResContext(context, 0, context->fileSize)) {
+		if (!loadRes(0, _fileSize)) {
 			return false;
 		}
 	} else {
-		if (!loadMacContext(context)) {
+		if (!loadMac()) {
 			return false;
 		}
 	}
 
 	//process internal patch files
-	if (context->fileType & GAME_PATCHFILE) {
-		subjectResourceType = ~GAME_PATCHFILE & context->fileType;
-		subjectContext = getContext((GameFileTypes)subjectResourceType);
+	if (_fileType & GAME_PATCHFILE) {
+		subjectResourceType = ~GAME_PATCHFILE & _fileType;
+		subjectContext = resource->getContext((GameFileTypes)subjectResourceType);
 		if (subjectContext == NULL) {
-			error("Resource::loadContext() Subject context not found");
+			error("ResourceContext::load() Subject context not found");
 		}
-		loadResource(context, context->count - 1, tableBuffer, tableSize);
+		resource->loadResource(this, _table.size() - 1, tableBuffer, tableSize);
 
-		MemoryReadStreamEndian readS2(tableBuffer, tableSize, context->isBigEndian);
+		MemoryReadStreamEndian readS2(tableBuffer, tableSize, _isBigEndian);
 		for (i = 0; i < tableSize / 8; i++) {
 			subjectResourceId = readS2.readUint32();
 			patchResourceId = readS2.readUint32();
 			subjectResourceData = subjectContext->getResourceData(subjectResourceId);
-			resourceData = context->getResourceData(patchResourceId);
-			subjectResourceData->patchData = new PatchData(context->file);
+			resourceData = getResourceData(patchResourceId);
+			subjectResourceData->patchData = new PatchData(&_file);
 			subjectResourceData->offset = resourceData->offset;
 			subjectResourceData->size = resourceData->size;
 		}
@@ -165,10 +161,10 @@
 	}
 
 	//process external patch files
-	for (patchDescription = _vm->getPatchDescriptions(); patchDescription && patchDescription->fileName; ++patchDescription) {
-		if ((patchDescription->fileType & context->fileType) != 0) {
-			if (patchDescription->resourceId < context->count) {
-				resourceData = &context->table[patchDescription->resourceId];
+	for (patchDescription = vm->getPatchDescriptions(); patchDescription && patchDescription->fileName; ++patchDescription) {
+		if ((patchDescription->fileType & _fileType) != 0) {
+			if (patchDescription->resourceId < _table.size()) {
+				resourceData = &_table[patchDescription->resourceId];
 				resourceData->patchData = new PatchData(patchDescription);
 				if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {
 					resourceData->offset = 0;
@@ -176,7 +172,7 @@
 					// ITE uses several patch files which are loaded and then not needed
 					// anymore (as they're in memory), so close them here. IHNM uses only
 					// 1 patch file, which is reused, so don't close it
-					if (_vm->getGameId() == GID_ITE)
+					if (vm->getGameId() == GID_ITE)
 						resourceData->patchData->_patchFile->close();
 				} else {
 					delete resourceData->patchData;
@@ -189,221 +185,140 @@
 	// Close the file if it's part of a series of files
 	// This prevents having all voice files open in IHNM for no reason, as each chapter uses
 	// a different voice file
-	if (context->serial > 0)
-		context->file->close();
+	if (_serial > 0)
+		_file.close();
 
 	return true;
 }
 
-bool Resource::createContexts() {
-	int i;
+Resource::Resource(SagaEngine *vm): _vm(vm) {
+}
+
+Resource::~Resource() {
+	clearContexts();
+}
+
+void Resource::addContext(const char *fileName, uint16 fileType, bool isCompressed, int serial) {
 	ResourceContext *context;
-	int soundFileIndex = 0;
-	int voicesFileIndex = 0;
-	bool digitalMusic = false;
+	context = createContext();
+	context->_fileName = fileName;
+	context->_fileType = fileType;
+	context->_isCompressed = isCompressed;
+	context->_serial = serial;
+	_contexts.push_back(context);
+}
+
+bool Resource::createContexts() {
 	bool soundFileInArray = false;
-	bool multipleVoices = false;
-	bool censoredVersion = false;
-	bool compressedSounds = false;
-	bool compressedMusic = false;
-	uint16 voiceFileType = GAME_VOICEFILE;
-	bool fileFound = false;
-	int maxFile = 0;
 
 	_vm->_voiceFilesExist = true;
 
 	struct SoundFileInfo {
+		int gameId;
 		char fileName[40];
 		bool isCompressed;
+		uint16 voiceFileAddType;
 	};
 
-	SoundFileInfo *curSoundfiles = 0;
 
 	// If the Wyrmkeep credits file is found, set the Wyrmkeep version flag to true
 	if (Common::File::exists("graphics/credit3n.dlt")) {
 		_vm->_gf_wyrmkeep = true;
 	}
 
-	_contextsCount = 0;
-	for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {
-		_contextsCount++;
-		if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE)
+	for (const ADGameFileDescription *gameFileDescription = _vm->getFilesDescriptions();
+		gameFileDescription->fileName; gameFileDescription++) {
+		addContext(gameFileDescription->fileName, gameFileDescription->fileType);
+		if (gameFileDescription->fileType == GAME_SOUNDFILE) {
 			soundFileInArray = true;
+		}
 	}
 
 	//// Detect and add SFX files ////////////////////////////////////////////////
-	SoundFileInfo sfxFilesITE[] = {
-		{	"sounds.rsc",		false	},
-		{	"sounds.cmp",		true	},
-		{	"soundsd.rsc",		false	},
-		{	"soundsd.cmp",		true	}
-	};
-
+	SoundFileInfo sfxFiles[] = {
+		{	GID_ITE,	"sounds.rsc",		false	},
+		{	GID_ITE,	"sounds.cmp",		true	},
+		{	GID_ITE,	"soundsd.rsc",		false	},
+		{	GID_ITE,	"soundsd.cmp",		true	},
 #ifdef ENABLE_IHNM
-	SoundFileInfo sfxFilesIHNM[] = {
-		{	"sfx.res",			false	},
-		{	"sfx.cmp",			true	}
-	};
+		{	GID_IHNM,	"sfx.res",			false	},
+		{	GID_IHNM,	"sfx.cmp",			true	},
 #endif
-
 #ifdef ENABLE_SAGA2
-	SoundFileInfo sfxFilesFTA2[] = {
-		{	"ftasound.hrs",		false	}
+		{	GID_FTA2,	"ftasound.hrs",		false	},
+		{	GID_DINO,	"dinosnd.hrs",		false	},
+#endif
+		{	-1,			NULL,				false	}
 	};
 
-	SoundFileInfo sfxFilesDino[] = {
-		{	"dinosnd.hrs",		false	},
-	};
-#endif
-
+	_soundFileName[0] = 0;
 	if (!soundFileInArray) {
-		// If the sound file is not specified in the detector table, add it here
-		fileFound = false;
-
-		switch (_vm->getGameId()) {
-			case GID_ITE:
-				curSoundfiles = sfxFilesITE;
-				maxFile = 4;
-				break;
-#ifdef ENABLE_IHNM
-			case GID_IHNM:
-				curSoundfiles = sfxFilesIHNM;
-				maxFile = 2;
-				break;
-#endif
-#ifdef ENABLE_SAGA2
-			case GID_DINO:
-				curSoundfiles = sfxFilesDino;
-				maxFile = 1;
-				break;
-			case GID_FTA2:
-				curSoundfiles = sfxFilesFTA2;
-				maxFile = 1;
-				break;
-#endif
+		for (SoundFileInfo *curSoundFile = sfxFiles; (curSoundFile->gameId != -1); curSoundFile++) {
+			if (curSoundFile->gameId != _vm->getGameId()) continue;
+			if (!Common::File::exists(curSoundFile->fileName)) continue;
+			strcpy(_soundFileName, curSoundFile->fileName);
+			addContext(_soundFileName, GAME_SOUNDFILE, curSoundFile->isCompressed);
+			break;
 		}
-
-		for (i = 0; i < maxFile; i++) {
-			if (Common::File::exists(curSoundfiles[i].fileName)) {
-				_contextsCount++;
-				soundFileIndex = _contextsCount - 1;
-				strcpy(_soundFileName, curSoundfiles[i].fileName);
-				compressedSounds = curSoundfiles[i].isCompressed;
-				fileFound = true;
-				break;
-			}
-		}
-
-		if (!fileFound) {
-			// No sound file found, don't add any file to the array
-			soundFileInArray = true;
-			if (_vm->getGameId() == GID_ITE) {
-				// ITE floppy versions have both voices and sounds in voices.rsc
-				voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE;
-			}
-		}
 	}
 
 	//// Detect and add voice files /////////////////////////////////////////////
-	SoundFileInfo voiceFilesITE[] = {
-		{	"voices.rsc",					false	},
-		{	"voices.cmp",					true	},
-		{	"voicesd.rsc",					false	},
-		{	"voicesd.cmp",					true	},
-		{	"inherit the earth voices",		false	},
-		{	"inherit the earth voices.cmp",	true	},
-		{	"ite voices.bin",				false	}
-	};
-
+	SoundFileInfo voiceFiles[] = {
+		{	GID_ITE,	"voices.rsc",					false	,	(_soundFileName[0] == 0) ? GAME_SOUNDFILE : 0},
+		{	GID_ITE,	"voices.cmp",					true	,	(_soundFileName[0] == 0) ? GAME_SOUNDFILE : 0},
+		{	GID_ITE,	"voicesd.rsc",					false	,	(_soundFileName[0] == 0) ? GAME_SOUNDFILE : 0},
+		{	GID_ITE,	"voicesd.cmp",					true	,	(_soundFileName[0] == 0) ? GAME_SOUNDFILE : 0},
+		// The resources in the Wyrmkeep combined Windows/Mac/Linux CD version are little endian, but
+		// the voice file is big endian. If we got such a version with mixed files, mark this voice file
+		// as big endian
+		{	GID_ITE,	"inherit the earth voices",		false	,	_vm->isBigEndian() ? 0 : GAME_SWAPENDIAN},
+		{	GID_ITE,	"inherit the earth voices.cmp",	true	,	_vm->isBigEndian() ? 0 : GAME_SWAPENDIAN},
+		{	GID_ITE,	"ite voices.bin",				false	,	GAME_MACBINARY},
 #ifdef ENABLE_IHNM
-	SoundFileInfo voiceFilesIHNM[] = {
-		{	"voicess.res",					false	},
-		{	"voicess.cmp",					true	},
-		{	"voicesd.res",					false	},
-		{	"voicesd.cmp",					true	},
-	};
+		{	GID_IHNM,	"voicess.res",					false	,	0},
+		{	GID_IHNM,	"voicess.cmp",					true	,	0},
+		{	GID_IHNM,	"voicesd.res",					false	,	0},
+		{	GID_IHNM,	"voicesd.cmp",					true	,	0},
 #endif
-
 #ifdef ENABLE_SAGA2
-	SoundFileInfo voiceFilesFTA2[] = {
-		{	"ftavoice.hrs",					false	},
-	};
+		{	GID_FTA2,	"ftavoice.hrs",					false	,	0},
 #endif
+		{	-1,			NULL,							false	,	0}
+	};
 
 	// Detect and add voice files
-	fileFound = false;
+	_voicesFileName[0][0] = 0;
+	for (SoundFileInfo *curSoundFile = voiceFiles; (curSoundFile->gameId != -1); curSoundFile++) {
+		if (curSoundFile->gameId != _vm->getGameId()) continue;
+		if (!Common::File::exists(curSoundFile->fileName)) continue;
 
-	switch (_vm->getGameId()) {
-		case GID_ITE:
-			curSoundfiles = voiceFilesITE;
-			maxFile = 7;
-			break;
-#ifdef ENABLE_IHNM
-		case GID_IHNM:
-			curSoundfiles = voiceFilesIHNM;
-			maxFile = 4;
-			break;
-#endif
-#ifdef ENABLE_SAGA2
-		/*
-		case GID_DINO:
-			// TODO
-			curSoundfiles = NULL;
-			maxFile = 0;
-			break;
-		*/
-		case GID_FTA2:
-			curSoundfiles = voiceFilesFTA2;
-			maxFile = 1;
-			break;
-#endif
-	}
+		strcpy(_voicesFileName[0], curSoundFile->fileName);
+		addContext(_voicesFileName[0], GAME_VOICEFILE | curSoundFile->voiceFileAddType, curSoundFile->isCompressed);
 
-	for (i = 0; i < maxFile; i++) {
-		if (Common::File::exists(curSoundfiles[i].fileName)) {
-			_contextsCount++;
-			voicesFileIndex = _contextsCount - 1;
-			strcpy(_voicesFileName[0], curSoundfiles[i].fileName);
-			compressedSounds = curSoundfiles[i].isCompressed;
-			fileFound = true;
-
-			// Special cases
-			if (!scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices") ||
-				!scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices.cmp")) {
-				// The resources in the Wyrmkeep combined Windows/Mac/Linux CD version are little endian, but
-				// the voice file is big endian. If we got such a version with mixed files, mark this voice file
-				// as big endian
-				if (!_vm->isBigEndian())
-					voiceFileType = GAME_VOICEFILE | GAME_SWAPENDIAN;	// This file is big endian
-			}
-
-			if (!scumm_stricmp(curSoundfiles[i].fileName, "ite voices.bin")) {
-				voiceFileType = GAME_VOICEFILE | GAME_MACBINARY;
-			}
-
-			if (!scumm_stricmp(curSoundfiles[i].fileName, "voicess.res") ||
-				!scumm_stricmp(curSoundfiles[i].fileName, "voicess.cmp")) {
+		// Special cases
+		if (!scumm_stricmp(curSoundFile->fileName, "voicess.res") ||
+			!scumm_stricmp(curSoundFile->fileName, "voicess.cmp")) {
 				// IHNM has multiple voice files
-				multipleVoices = true;
-				// Note: it is assumed that the voice files are always last in the list
-				if (Common::File::exists("voices4.res") || Common::File::exists("voices4.cmp")) {
-					_contextsCount += 6;	// voices1-voices6
-				} else {
-					// The German and French versions of IHNM don't have Nimdok's chapter,
-					// therefore the voices file for that chapter is missing
-					_contextsCount += 5;	// voices1-voices3, voices4-voices5
-					censoredVersion = true;
+				for (size_t i = 1; i <= 6; i++) { // voices1-voices6
+					sprintf(_voicesFileName[i], "voices%i.%s", i, curSoundFile->isCompressed ? "cmp" : "res");
+					if (i == 4) {
+						// The German and French versions of IHNM don't have Nimdok's chapter,
+						// therefore the voices file for that chapter is missing
+						if (!Common::File::exists(_voicesFileName[i])) {
+							continue;
+						}
+					}
+					addContext(_voicesFileName[i], GAME_VOICEFILE, curSoundFile->isCompressed, i);
 				}
-			}
-
-			break;
 		}
+		break;
 	}
 
-	if (!fileFound) {
+	if (_voicesFileName[0][0] == 0) {
 		if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
 			// The Macintosh version of IHNM has no voices.res, and it has all
 			// its voice files in subdirectories, so don't do anything here
+			_contexts.push_back(new VoiceResourceContext_RES());
 		} else {
 			warning("No voice file found, voices will be disabled");
 			_vm->_voicesEnabled = false;
@@ -412,83 +327,27 @@
 		}
 	}
 
-	//// Detect and add ITE music files /////////////////////////////////////////
-	SoundFileInfo musicFilesITE[] = {
-		{	"music.rsc",	false	},
-		{	"music.cmp",	true	},
-		{	"musicd.rsc",	false	},
-		{	"musicd.cmp",	true	},
+	//// Detect and add music files /////////////////////////////////////////
+	SoundFileInfo musicFiles[] = {
+		{	GID_ITE,	"music.rsc",	false	},
+		{	GID_ITE,	"music.cmp",	true	},
+		{	GID_ITE,	"musicd.rsc",	false	},
+		{	GID_ITE,	"musicd.cmp",	true	},
+		{	-1,			NULL,			false	}
 	};
 
 	// Check for digital music in ITE
-	if (_vm->getGameId() == GID_ITE) {
-		fileFound = false;
 
-		for (i = 0; i < 4; i++) {
-			if (Common::File::exists(musicFilesITE[i].fileName)) {
-				_contextsCount++;
-				digitalMusic = true;
-				compressedMusic = musicFilesITE[i].isCompressed;
-				fileFound = true;
-				strcpy(_musicFileName, musicFilesITE[i].fileName);
-				break;
-			}
-		}
-
-		if (!fileFound) {
-			// No sound file found, don't add any file to the array
-			digitalMusic = false;
-		}
+	for (SoundFileInfo *curSoundFile = musicFiles; (curSoundFile->gameId != -1); curSoundFile++) {
+		if (curSoundFile->gameId != _vm->getGameId()) continue;
+		if (!Common::File::exists(curSoundFile->fileName)) continue;
+		strcpy(_musicFileName, curSoundFile->fileName);
+		addContext(_musicFileName, GAME_DIGITALMUSICFILE, curSoundFile->isCompressed);
+		break;
 	}
 
-	_contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));
-
-	for (i = 0; i < _contextsCount; i++) {
-		context = &_contexts[i];
-		context->file = new Common::File();
-		context->serial = 0;
-
-		// For ITE, add the digital music file and sfx file information here
-		if (_vm->getGameId() == GID_ITE && digitalMusic && i == _contextsCount - 1) {
-			context->fileName = _musicFileName;
-			context->fileType = GAME_DIGITALMUSICFILE;
-			context->isCompressed = compressedMusic;
-		} else if (!soundFileInArray && i == soundFileIndex) {
-			context->fileName = _soundFileName;
-			context->fileType = GAME_SOUNDFILE;
-			context->isCompressed = compressedSounds;
-		} else if (_vm->_voiceFilesExist && i == voicesFileIndex && !(_vm->getGameId() == GID_IHNM && _vm->isMacResources())) {
-			context->fileName = _voicesFileName[0];
-			// can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN
-			context->fileType = voiceFileType;
-			context->isCompressed = compressedSounds;
-		} else {
-			if (!(_vm->_voiceFilesExist && multipleVoices && (i > voicesFileIndex))) {
-				context->fileName = _vm->getFilesDescriptions()[i].fileName;
-				context->fileType = _vm->getFilesDescriptions()[i].fileType;
-				context->isCompressed = compressedSounds;
-			} else {
-				int token = (censoredVersion && (i - voicesFileIndex >= 4)) ? 1 : 0;	// censored versions don't have voice4
-
-				if (compressedSounds)
-					sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.cmp", i - voicesFileIndex + token);
-				else
-					sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.res", i - voicesFileIndex + token);
-
-				context->fileName = _voicesFileName[i - voicesFileIndex + token];
-				context->fileType = GAME_VOICEFILE;
-				context->isCompressed = compressedSounds;
-
-				// IHNM has several different voice files, so we need to allow
-				// multiple resource contexts of the same type. We tell them
-				// apart by assigning each of the duplicates a unique serial
-				// number. The default behaviour when requesting a context will
-				// be to look for serial number 0.
-				context->serial = i - voicesFileIndex + token;
-			}
-		}
-
-		if (!loadContext(context)) {
+	for (ResourceContextList::iterator i = _contexts.begin(); i != _contexts.end(); ++i) {
+		if (!(*i)->load(_vm, this)) {
 			return false;
 		}
 	}
@@ -496,27 +355,12 @@
 }
 
 void Resource::clearContexts() {
-	int i;
-	size_t j;
-	ResourceContext *context;
-	if (_contexts == NULL) {
-		return;
+	ResourceContextList::iterator i = _contexts.begin();
+	while (i != _contexts.end()) {
+		ResourceContext * context = *i;
+		i = _contexts.erase(i);
+		delete context;
 	}
-	for (i = 0; i < _contextsCount; i++) {
-		context = &_contexts[i];
-		delete context->file;
-		if (context->table != NULL) {
-			for (j = 0; j < context->count; j++) {
-				delete context->table[j].patchData;
-			}
-		}
-		if (_vm->isSaga2()) {
-			free(context->categories);
-		}
-		free(context->table);
-	}
-	free(_contexts);
-	_contexts = NULL;
 }
 
 void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize) {
@@ -548,4 +392,14 @@
 		file->close();
 }
 
+ResourceContext *Resource::getContext(uint16 fileType, int serial) {
+	for (ResourceContextList::const_iterator i = _contexts.begin(); i != _contexts.end(); ++i) {
+		ResourceContext * context = *i;
+		if ((context->fileType() & fileType) && (context->serial() == serial)) {
+			return context;
+		}
+	}
+	return NULL;
+}
+
 } // End of namespace Saga

Modified: scummvm/trunk/engines/saga/resource.h
===================================================================
--- scummvm/trunk/engines/saga/resource.h	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/resource.h	2009-12-04 17:52:42 UTC (rev 46254)
@@ -62,53 +62,111 @@
 	size_t size;
 	PatchData *patchData;
 
-	bool isExternal() { return ((offset & (1L<<31)) != 0L); }	// SAGA2
+	ResourceData() :
+		id(0), offset(0), size(0), patchData(NULL) {
+	}
+
+	~ResourceData() {
+		if (patchData) {
+			delete patchData;
+			patchData = NULL;
+		}
+	}
+
+	bool isExternal() {	// SAGA2
+		return ((offset & (1L<<31)) != 0L);
+	}
 };
 
-struct ResourceContext {
-	const char *fileName;
-	uint16 fileType;
-	Common::File *file;
-	int32 fileSize;
-	int serial;			// IHNM speech files
+class ResourceDataArray : public Common::Array<ResourceData> {
+};
 
-	bool isCompressed;
-	bool isBigEndian;
-	ResourceData *table;
-	size_t count;
-	ResourceData *categories;		// SAGA2
+class ResourceContext {
+friend class Resource;
+protected:
+	const char *_fileName;
+	uint16 _fileType;
+	bool _isCompressed;
+	int _serial;					// IHNM speech files
 
-	Common::File *getFile(ResourceData *resourceData) const {
-		if (resourceData->patchData != NULL) {
-			if (!resourceData->patchData->_patchFile->isOpen())
-				resourceData->patchData->_patchFile->open(resourceData->patchData->_patchDescription->fileName);
-			return resourceData->patchData->_patchFile;
+	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():
+		_fileName(NULL), _fileType(0), _isCompressed(false), _serial(0),
+		_isBigEndian(false),
+		_fileSize(0) {
+	}
+
+	bool isCompressed() const {
+		return _isCompressed;
+	}
+
+	uint16 fileType() const {
+		return _fileType;
+	}
+
+	int serial() const {
+		return _serial;
+	}
+
+	bool isBigEndian() const {
+		return _isBigEndian;
+	}
+
+	const char * fileName() const {
+		return _fileName;
+	}
+
+	Common::File *getFile(ResourceData *resourceData) {
+		Common::File *file;
+		const char * fn;
+		if (resourceData && resourceData->patchData != NULL) {
+			file = resourceData->patchData->_patchFile;
+			fn = resourceData->patchData->_patchDescription->fileName;
 		} else {
-			return file;
+			file = &_file;
+			fn = _fileName;
 		}
+		if (!file->isOpen())
+			file->open(fn);
+		return file;
 	}
 
 	bool validResourceId(uint32 resourceId) const {
-		return (resourceId < count);
+		return (resourceId < _table.size());
 	}
 
-	ResourceData *getResourceData(uint32 resourceId) const {
-		if (resourceId >= count) {
+	ResourceData *getResourceData(uint32 resourceId) {
+		if (resourceId >= _table.size()) {
 			error("ResourceContext::getResourceData() wrong resourceId %d", resourceId);
 		}
-		return &table[resourceId];
+		return &_table[resourceId];
 	}
 
 	// SAGA 2
 	int32 getEntryNum(uint32 id) {
-		for (int32 i = 0; i < (int32)count; i++) {
-			if (table[i].id == id) {
-				return i;
+		int32 num = 0;
+		for (ResourceDataArray::const_iterator i = _table.begin(); i != _table.end(); ++i) {
+			if (i->id == id) {
+				return num;
 			}
+			num++;
 		}
 		return -1;
 	}
+};
 
+class ResourceContextList : public Common::List<ResourceContext*> {
 };
 
 struct MetaResource {
@@ -145,32 +203,29 @@
 	virtual uint32 convertResourceId(uint32 resourceId) = 0;
 	virtual void loadGlobalResources(int chapter, int actorsEntrance) = 0;
 
-	ResourceContext *getContext(uint16 fileType, int serial = 0) {
-		for (int i = 0; i < _contextsCount; i++) {
-			if ((_contexts[i].fileType & fileType) && _contexts[i].serial == serial) {
-				return &_contexts[i];
-			}
-		}
-		return NULL;
-	}
-
+	ResourceContext *getContext(uint16 fileType, int serial = 0);
 protected:
 	SagaEngine *_vm;
-	ResourceContext *_contexts;
-	int _contextsCount;
+	ResourceContextList _contexts;
 	char _voicesFileName[8][256];
 	char _musicFileName[256];
 	char _soundFileName[256];
 
-	bool loadContext(ResourceContext *context);
-	virtual bool loadMacContext(ResourceContext *context) = 0;
-	virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) = 0;
-	bool loadResContext_v1(ResourceContext *context, uint32 contextOffset, uint32 contextSize);
+	void addContext(const char *fileName, uint16 fileType, bool isCompressed = false, int serial = 0);
+	virtual ResourceContext *createContext() = 0;
 public:
 	virtual MetaResource* getMetaResource() = 0;
 };
 
 // ITE
+class ResourceContext_RSC: public ResourceContext {
+protected:
+	virtual bool loadMac();
+	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
+		return loadResV1(contextOffset, contextSize);
+	}
+};
+
 class Resource_RSC : public Resource {
 public:
 	Resource_RSC(SagaEngine *vm) : Resource(vm) {}
@@ -180,32 +235,70 @@
 		MetaResource *dummy = 0;
 		return dummy;
 	}
-private:
-	virtual bool loadMacContext(ResourceContext *context);
-	virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
-		return loadResContext_v1(context, contextOffset, contextSize);
+protected:
+	virtual ResourceContext *createContext() {
+		return new ResourceContext_RSC();
 	}
 };
 
 #ifdef ENABLE_IHNM
 // IHNM
+class ResourceContext_RES: public ResourceContext {
+protected:
+	virtual bool loadMac() {
+		return false;
+	}
+	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
+		return loadResV1(0, contextSize);
+	}
+};
+
+//TODO: move load routines from sndres
+class VoiceResourceContext_RES: public ResourceContext {
+protected:
+	virtual bool loadMac() {
+		return false;
+	}
+	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
+		return false;
+	}
+public:
+	VoiceResourceContext_RES() : ResourceContext() {
+		_fileType = GAME_VOICEFILE;
+		_isBigEndian = true;
+	}
+};
+
 class Resource_RES : public Resource {
 public:
 	Resource_RES(SagaEngine *vm) : Resource(vm) {}
 	virtual uint32 convertResourceId(uint32 resourceId) { return resourceId; }
 	virtual void loadGlobalResources(int chapter, int actorsEntrance);
 	virtual MetaResource* getMetaResource() { return &_metaResource; };
+protected:
+	virtual ResourceContext *createContext() {
+		return new ResourceContext_RES();
+	}
 private:
-	virtual bool loadMacContext(ResourceContext *context) { return false; }
-	virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
-		return loadResContext_v1(context, 0, contextSize);
-	}
 	MetaResource _metaResource;
 };
 #endif
 
 #ifdef ENABLE_SAGA2
 // DINO, FTA2
+class ResourceContext_HRS: public ResourceContext {
+protected:
+	ResourceDataArray _categories;
+
+	virtual bool loadMac() {
+		return false;
+	}
+	virtual bool loadRes(uint32 contextOffset, uint32 contextSize) {
+		return loadResV2(contextSize);
+	}
+	bool loadResV2(uint32 contextSize);
+};
+
 class Resource_HRS : public Resource {
 public:
 	Resource_HRS(SagaEngine *vm) : Resource(vm) {}
@@ -215,12 +308,10 @@
 		MetaResource *dummy = 0;
 		return dummy;
 	}
-private:
-	virtual bool loadMacContext(ResourceContext *context) { return false; }
-	virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
-		return loadResContext_v2(context, contextSize);
+protected:
+	virtual ResourceContext *createContext() {
+		return new ResourceContext_HRS();
 	}
-	bool loadResContext_v2(ResourceContext *context, uint32 contextSize);
 };
 #endif
 

Modified: scummvm/trunk/engines/saga/resource_hrs.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_hrs.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/resource_hrs.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -42,64 +42,54 @@
 
 namespace Saga {
 
-void readElement(Common::File *file, Saga::ResourceData *element) {
-	element->id = file->readUint32BE();
-	element->offset = file->readUint32LE();
-	element->size = file->readUint32LE();
-	debug(3, "Entry: id %u, offset %u, size %u", element->id, (uint)element->offset, (uint)element->size);
+void readElement(Common::File &file, Saga::ResourceData &element) {
+	element.id = file.readUint32BE();
+	element.offset = file.readUint32LE();
+	element.size = file.readUint32LE();
+	debug(3, "Entry: id %u, offset %u, size %u", element.id, (uint)element.offset, (uint)element.size);
 }
 
-bool Resource_HRS::loadResContext_v2(ResourceContext *context, uint32 contextSize) {
-	ResourceData *origin = new ResourceData();
+bool ResourceContext_HRS::loadResV2(uint32 contextSize) {
+	ResourceData origin;
 	uint32 firstEntryOffset;
 	uint32 tableSize;
 	int i, count;
 	const uint32 resourceSize = 4 + 4 + 4;	// id, size, offset
 
-	debug(3, "Context %s =====", context->fileName);
-	context->file->seek(0, SEEK_SET);
+	debug(3, "Context %s =====", _fileName);
+	_file.seek(0, SEEK_SET);
 
-	readElement(context->file, origin);
+	readElement(_file, origin);
 
 	// Check if the file is valid
-	if (origin->id != MKID_BE('HRES')) {	// header
-		delete origin;
+	if (origin.id != MKID_BE('HRES')) {	// header
 		return false;
 	}
 
 	// Read offset of first entry
-	context->file->seek(origin->offset - sizeof(uint32), SEEK_SET);
-	firstEntryOffset = context->file->readUint32LE();
+	_file.seek(origin.offset - sizeof(uint32), SEEK_SET);
+	firstEntryOffset = _file.readUint32LE();
 
 	// Allocate buffers for table, categories and data
-	context->categories = (ResourceData *) calloc(origin->size / resourceSize, sizeof(*context->categories));
-	tableSize = origin->offset - firstEntryOffset - sizeof(uint32);
-	context->table = (ResourceData *) calloc(tableSize / resourceSize, sizeof(*context->table));
+	_categories.resize(origin.size / resourceSize);
+	tableSize = origin.offset - firstEntryOffset - sizeof(uint32);
+	_table.resize(tableSize / resourceSize);
 
-	if (context->categories == NULL || context->table == NULL) {
-		delete origin;
-		return false;
-	}
-
 	// Read categories
-	count = origin->size / resourceSize;
+	count = origin.size / resourceSize;
 	debug(3, "Categories: %d =====", count);
 	for (i = 0; i < count; i++) {
-		readElement(context->file, &context->categories[i]);
+		readElement(_file, _categories[i]);
 	}
 
-	context->file->seek(firstEntryOffset, SEEK_SET);
+	_file.seek(firstEntryOffset, SEEK_SET);
 
 	// Read table entries
 	count = tableSize / resourceSize;
 	debug(3, "Entries: %d =====", count);
 	for (i = 0; i < count; i++) {
-		readElement(context->file, &context->table[i]);
+		readElement(_file, _table[i]);
 	}
-
-	context->count = tableSize / resourceSize;
-
-	delete origin;
 	return true;
 }
 

Modified: scummvm/trunk/engines/saga/resource_rsc.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_rsc.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/resource_rsc.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -52,34 +52,30 @@
 	byte attr;
 	int32 dataOffset;
 	byte name[255];
+	MacResource() : id(0), nameOffset(0), attr(0), dataOffset(0) {
+		name[0] = 0;
+	}
 };
 
+class MacResourceArray : public Common::Array<MacResource> {
+};
+
 struct MacResType {
 	uint32 id;
 	int16 items;
 	int16 maxItemId;
 	int16 offset;
-	MacResource *resources;
+	MacResourceArray resources;
+	MacResType() : id(0), items(0), maxItemId(0), offset(0) {
+	}
 };
 
+class MacResTypeArray : public Common::Array<MacResType> {
+};
+
 #define ID_MIDI     MKID_BE('Midi')
 
-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;
-}
-
-bool Resource_RSC::loadMacContext(ResourceContext *context) {
+bool ResourceContext_RSC::loadMac() {
 	int32 macDataSize, macDataSizePad;
 	int32 macResSize, macResSizePad;
 	int32 macResOffset;
@@ -90,123 +86,127 @@
 	uint32 macDataOffset;
 
 	MacResMap macResMap;
-	MacResType *macResTypes;
+	MacResTypeArray macResTypes;
 
-	MacResType *macResType;
-	MacResource *macResource;
-	int i, j;
 	byte macNameLen;
 	bool notSagaContext = false;
 
-	if (context->fileSize < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE) {
+	if (_fileSize < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE) {
 		return false;
 	}
 
-	if (context->file->readByte() != 0) {
+	if (_file.readByte() != 0) {
 		return false;
 	}
-	context->file->readByte(); //MAX Name Len
-	context->file->seek(74);
-	if (context->file->readByte() != 0) {
+	_file.readByte(); //MAX Name Len
+	_file.seek(74);
+	if (_file.readByte() != 0) {
 		return false;
 	}
-	context->file->seek(82);
-	if (context->file->readByte() != 0) {
+	_file.seek(82);
+	if (_file.readByte() != 0) {
 		return false;
 	}
 
-	macDataSize = context->file->readSint32BE();
-	macResSize = context->file->readSint32BE();
+	macDataSize = _file.readSint32BE();
+	macResSize = _file.readSint32BE();
 	macDataSizePad = (((macDataSize + 127) >> 7) << 7);
 	macResSizePad = (((macResSize + 127) >> 7) << 7);
 
 	macResOffset = MAC_BINARY_HEADER_SIZE + macDataSizePad;
-	context->file->seek(macResOffset);
+	_file.seek(macResOffset);
 
-	macDataOffset = context->file->readUint32BE() + macResOffset;
-	macMapOffset = context->file->readUint32BE() + macResOffset;
-	macDataLength = context->file->readUint32BE();
-	macMapLength = context->file->readUint32BE();
+	macDataOffset = _file.readUint32BE() + macResOffset;
+	macMapOffset = _file.readUint32BE() + macResOffset;
+	macDataLength = _file.readUint32BE();
+	macMapLength = _file.readUint32BE();
 
-	if (macDataOffset >= (uint)context->fileSize || macMapOffset >= (uint)context->fileSize ||
-		macDataLength + macMapLength > (uint)context->fileSize) {
+	if (macDataOffset >= (uint)_fileSize || macMapOffset >= (uint)_fileSize ||
+		macDataLength + macMapLength > (uint)_fileSize) {
 			return false;
 	}
 
-	context->file->seek(macMapOffset + 22);
+	_file.seek(macMapOffset + 22);
 
-	macResMap.resAttr = context->file->readUint16BE();
-	macResMap.typeOffset = context->file->readUint16BE();
-	macResMap.nameOffset = context->file->readUint16BE();
-	macResMap.numTypes = context->file->readUint16BE();
+	macResMap.resAttr = _file.readUint16BE();
+	macResMap.typeOffset = _file.readUint16BE();
+	macResMap.nameOffset = _file.readUint16BE();
+	macResMap.numTypes = _file.readUint16BE();
 	macResMap.numTypes++;
 
-	context->file->seek(macMapOffset + macResMap.typeOffset + 2);
+	_file.seek(macMapOffset + macResMap.typeOffset + 2);
 
-	macResTypes = (MacResType *)calloc(macResMap.numTypes, sizeof(*macResTypes));
+	macResTypes.resize(macResMap.numTypes);
 
-	for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
-		macResType->id = context->file->readUint32BE();
-		macResType->items = context->file->readUint16BE();
-		macResType->offset = context->file->readUint16BE();
-		macResType->items++;
-		macResType->resources = (MacResource*)calloc(macResType->items, sizeof(*macResType->resources));
+	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
+		k->id = _file.readUint32BE();
+		k->items = _file.readUint16BE();
+		k->offset = _file.readUint16BE();
+		k->items++;
+		k->resources.resize(k->items);
 	}
 
-	for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
-		context->file->seek(macResType->offset + macMapOffset + macResMap.typeOffset);
+	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
+		_file.seek(k->offset + macMapOffset + macResMap.typeOffset);
 
-		for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
-			macResource->id = context->file->readUint16BE();
-			macResource->nameOffset = context->file->readUint16BE();
-			macResource->dataOffset = context->file->readUint32BE();
-			macResSize = context->file->readUint32BE();
+		for (MacResourceArray::iterator j = k->resources.begin(); j != k->resources.end(); ++j) {
+			j->id = _file.readUint16BE();
+			j->nameOffset = _file.readUint16BE();
+			j->dataOffset = _file.readUint32BE();
+			macResSize = _file.readUint32BE();
 
-			macResource->attr = macResource->dataOffset >> 24;
-			macResource->dataOffset &= 0xFFFFFF;
-			if (macResource->id > macResType->maxItemId) {
-				macResType->maxItemId = macResource->id;
+			j->attr = j->dataOffset >> 24;
+			j->dataOffset &= 0xFFFFFF;
+			if (j->id > k->maxItemId) {
+				k->maxItemId = j->id;
 			}
 		}
 
-		for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
-			if (macResource->nameOffset != -1) {
-				context->file->seek(macResource->nameOffset + macMapOffset + macResMap.nameOffset);
-				macNameLen = context->file->readByte();
-				context->file->read(macResource->name, macNameLen);
+		for (MacResourceArray::iterator j = k->resources.begin(); j != k->resources.end(); ++j) {
+			if (j->nameOffset != -1) {
+				_file.seek(j->nameOffset + macMapOffset + macResMap.nameOffset);
+				macNameLen = _file.readByte();
+				_file.read(j->name, macNameLen);
 			}
 		}
 	}
 
-//
-	for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
+	//
+	for (MacResTypeArray::iterator k = macResTypes.begin(); k != macResTypes.end(); ++k) {
 		//getting offsets & sizes of midi
-		if (((context->fileType & GAME_MUSICFILE_GM) > 0) && (macResType->id == ID_MIDI)) {
+		if (((_fileType & GAME_MUSICFILE_GM) > 0) && (k->id == ID_MIDI)) {
 
-			context->count = macResType->maxItemId + 1;
-			context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
-			for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
-				context->file->seek(macDataOffset + macResource->dataOffset);
-				context->table[macResource->id].size = context->file->readUint32BE();
-				context->table[macResource->id].offset = context->file->pos();
+			_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();
 			}
 			notSagaContext = true;
 			break;
 		}
 	}
 
-//free
-	for (i = 0; i < macResMap.numTypes; i++) {
-		free(macResTypes[i].resources);
-	}
-	free(macResTypes);
-
-	if ((!notSagaContext) && (!loadResContext(context, MAC_BINARY_HEADER_SIZE, macDataSize))) {
+	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

Modified: scummvm/trunk/engines/saga/saga.h
===================================================================
--- scummvm/trunk/engines/saga/saga.h	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/saga.h	2009-12-04 17:52:42 UTC (rev 46254)
@@ -79,7 +79,7 @@
 class Puzzle;
 class Resource;
 
-struct ResourceContext;
+class ResourceContext;
 struct StringList;
 
 using Common::MemoryReadStream;

Modified: scummvm/trunk/engines/saga/scene.cpp
===================================================================
--- scummvm/trunk/engines/saga/scene.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/scene.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -168,7 +168,7 @@
 		memoryError("Scene::Scene()");
 	}
 
-	MemoryReadStreamEndian readS(sceneLUTPointer, sceneLUTLength, _sceneContext->isBigEndian);
+	MemoryReadStreamEndian readS(sceneLUTPointer, sceneLUTLength, _sceneContext->isBigEndian());
 
 	for (i = 0; i < _sceneCount; i++) {
 		_sceneLUT[i] = readS.readUint16();
@@ -929,7 +929,7 @@
 	_vm->_resource->loadResource(_sceneContext, resourceId, sceneDescriptorData, sceneDescriptorDataLength);
 
 	if (sceneDescriptorDataLength == 16) {
-		MemoryReadStreamEndian readS(sceneDescriptorData, sceneDescriptorDataLength, _sceneContext->isBigEndian);
+		MemoryReadStreamEndian readS(sceneDescriptorData, sceneDescriptorDataLength, _sceneContext->isBigEndian());
 
 		_sceneDescription.flags = readS.readSint16();
 		_sceneDescription.resourceListResourceId = readS.readSint16();
@@ -960,7 +960,7 @@
 	_vm->_resource->loadResource(_sceneContext, resourceId, resourceListData, resourceListDataLength);
 
 	if ((resourceListDataLength % SAGA_RESLIST_ENTRY_LEN) == 0) {
-		MemoryReadStreamEndian readS(resourceListData, resourceListDataLength, _sceneContext->isBigEndian);
+		MemoryReadStreamEndian readS(resourceListData, resourceListDataLength, _sceneContext->isBigEndian());
 
 		// Allocate memory for scene resource list
 		_resourceListCount = resourceListDataLength / SAGA_RESLIST_ENTRY_LEN;
@@ -1302,7 +1302,7 @@
 
 	_entryList.entryListCount = resourceLength / 8;
 
-	MemoryReadStreamEndian readS(resourcePointer, resourceLength, _sceneContext->isBigEndian);
+	MemoryReadStreamEndian readS(resourcePointer, resourceLength, _sceneContext->isBigEndian());
 
 
 	if (_entryList.entryList)

Modified: scummvm/trunk/engines/saga/script.cpp
===================================================================
--- scummvm/trunk/engines/saga/script.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/script.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -109,7 +109,7 @@
 	}
 
 	// Convert LUT resource to logical LUT
-	MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, resourceContext->isBigEndian);
+	MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, resourceContext->isBigEndian());
 	for (i = 0; i < _modulesCount; i++) {
 		memset(&_modules[i], 0, sizeof(ModuleData));
 
@@ -1127,7 +1127,7 @@
 
 	memcpy(module.moduleBase, resourcePointer, resourceLength);
 
-	MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, _scriptContext->isBigEndian);
+	MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, _scriptContext->isBigEndian());
 
 	module.entryPointsCount = scriptS.readUint16();
 	scriptS.readUint16(); //skip
@@ -1177,7 +1177,7 @@
 		error("Script::loadVoiceLUT() not enough memory");
 	}
 
-	MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, _scriptContext->isBigEndian);
+	MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, _scriptContext->isBigEndian());
 
 	for (i = 0; i < voiceLUT.voicesCount; i++) {
 		voiceLUT.voices[i] = scriptS.readUint16();

Modified: scummvm/trunk/engines/saga/sndres.cpp
===================================================================
--- scummvm/trunk/engines/saga/sndres.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/sndres.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -48,15 +48,14 @@
 #define RID_IHNM_SFX_LUT 265
 #define RID_IHNMDEMO_SFX_LUT 222
 
-SndRes::SndRes(SagaEngine *vm) : _vm(vm) {
+SndRes::SndRes(SagaEngine *vm) : _vm(vm), _sfxContext(NULL), _voiceContext(NULL), _voiceSerial(-1) {
+
 	// Load sound module resource file contexts
 	_sfxContext = _vm->_resource->getContext(GAME_SOUNDFILE);
 	if (_sfxContext == NULL) {
 		error("SndRes::SndRes resource context not found");
 	}
 
-	_voiceSerial = -1;
-
 	setVoiceBank(0);
 
 	if (_vm->getGameId() == GID_ITE) {
@@ -117,6 +116,7 @@
 }
 
 void SndRes::setVoiceBank(int serial) {
+	Common::File *file;
 	if (_voiceSerial == serial)
 		return;
 
@@ -126,12 +126,7 @@
 	if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
 		_voiceSerial = serial;
 		// Set a dummy voice context
-		_voiceContext = new ResourceContext();
-		_voiceContext->fileType = GAME_VOICEFILE;
-		_voiceContext->count = 0;
-		_voiceContext->serial = 0;
-		_voiceContext->isBigEndian = true;
-		_voiceContext->isCompressed = false;
+		_voiceContext = new VoiceResourceContext_RES();
 		return;
 	}
 #endif
@@ -141,16 +136,16 @@
 		return;
 
 	// Close previous voice bank file
-	if (_voiceSerial >= 0 && _voiceContext->file->isOpen())
-		_voiceContext->file->close();
+	if (_voiceContext != NULL) {
+		file = _voiceContext->getFile(NULL);
+		if (file->isOpen()) {
+			file->close();
+		}
+	}
 
 	_voiceSerial = serial;
 
 	_voiceContext = _vm->_resource->getContext(GAME_VOICEFILE, _voiceSerial);
-
-	// Open new voice bank file
-	if (!_voiceContext->file->isOpen())
-		_voiceContext->file->open(_voiceContext->fileName);
 }
 
 void SndRes::playSound(uint32 resourceId, int volume, bool loop) {
@@ -199,11 +194,12 @@
 	}
 
 #ifdef ENABLE_IHNM
+	//TODO: move to resource_res so we can use normal "getResourceData" and "getFile" methods
 	if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
 		char soundFileName[40];
 		int dirIndex = resourceId / 64;
 
-		if ((context->fileType & GAME_VOICEFILE) != 0) {
+		if ((context->fileType() & GAME_VOICEFILE) != 0) {
 			if (_voiceSerial == 0) {
 				sprintf(soundFileName, "Voices/VoicesS/Voices%d/VoicesS%03x", dirIndex, resourceId);
 			} else {
@@ -217,7 +213,6 @@
 
 		file->open(soundFileName);
 		soundResourceLength = file->size();
-		context->isBigEndian = true;
 	} else
 #endif
 	{
@@ -249,14 +244,14 @@
 		bool uncompressedSound = false;
 		// If patch data exists for sound resource 4 (used in ITE intro), don't treat this sound as compressed
 		// Patch data for this resource is in file p2_a.iaf or p2_a.voc
-		if (_vm->getGameId() == GID_ITE && resourceId == 4 && context->table[resourceId].patchData != NULL)
+		if (_vm->getGameId() == GID_ITE && resourceId == 4 && context->getResourceData(resourceId)->patchData != NULL)
 			uncompressedSound = true;
 
 		// FIXME: Currently, the SFX.RES file in IHNM cannot be compressed
-		if (_vm->getGameId() == GID_IHNM && (context->fileType & GAME_SOUNDFILE))
+		if (_vm->getGameId() == GID_IHNM && (context->fileType() & GAME_SOUNDFILE))
 			uncompressedSound = true;
 
-		if (context->isCompressed && !uncompressedSound) {
+		if (context->isCompressed() && !uncompressedSound) {
 			if (header[0] == char(0)) {
 				resourceType = kSoundMP3;
 			} else if (header[0] == char(1)) {
@@ -269,7 +264,7 @@
 	}
 
 	// Default sound type is 16-bit signed PCM, used in ITE by PCM and VOX files
-	buffer.isCompressed = context->isCompressed;
+	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
@@ -281,20 +276,20 @@
 			buffer.flags &= ~Audio::Mixer::FLAG_16BITS;
 		} else {
 			// Voice files in newer ITE demo versions are OKI ADPCM (VOX) encoded
-			if (!scumm_stricmp(context->fileName, "voicesd.rsc"))
+			if (!scumm_stricmp(context->fileName(), "voicesd.rsc"))
 				resourceType = kSoundVOX;
 		}
 	}
 	buffer.buffer = NULL;
 
 	// Check for LE sounds
-	if (!context->isBigEndian)
+	if (!context->isBigEndian())
 		buffer.flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
-	if ((context->fileType & GAME_VOICEFILE) && (_vm->getFeatures() & GF_LE_VOICES))
+	if ((context->fileType() & GAME_VOICEFILE) && (_vm->getFeatures() & GF_LE_VOICES))
 		buffer.flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
 
 	// Older Mac versions of ITE were Macbinary packed
-	int soundOffset = (context->fileType & GAME_MACBINARY) ? 36 : 0;
+	int soundOffset = (context->fileType() & GAME_MACBINARY) ? 36 : 0;
 
 	switch (resourceType) {
 	case kSoundPCM:
@@ -404,7 +399,7 @@
 		return -1;
 	}
 
-	if (!_voiceContext->isCompressed || buffer.originalSize == 0)
+	if (!_voiceContext->isCompressed() || buffer.originalSize == 0)
 		msDouble = (double)buffer.size;
 	else
 		msDouble = (double)buffer.originalSize;

Modified: scummvm/trunk/engines/saga/sprite.cpp
===================================================================
--- scummvm/trunk/engines/saga/sprite.cpp	2009-12-04 17:42:32 UTC (rev 46253)
+++ scummvm/trunk/engines/saga/sprite.cpp	2009-12-04 17:52:42 UTC (rev 46254)
@@ -106,7 +106,7 @@
 		return;
 	}
 
-	MemoryReadStreamEndian readS(spriteListData, spriteListLength, _spriteContext->isBigEndian);
+	MemoryReadStreamEndian readS(spriteListData, spriteListLength, _spriteContext->isBigEndian());
 
 	spriteCount = readS.readUint16();
 
@@ -142,7 +142,7 @@
 		spritePointer += offset;
 
 		if (bigHeader) {
-			MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian);
+			MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian());
 
 			spriteInfo->xAlign = readS2.readSint16();
 			spriteInfo->yAlign = readS2.readSint16();


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