diff options
Diffstat (limited to 'engines/saga/rscfile.cpp')
| -rw-r--r-- | engines/saga/rscfile.cpp | 230 | 
1 files changed, 211 insertions, 19 deletions
| diff --git a/engines/saga/rscfile.cpp b/engines/saga/rscfile.cpp index 33e8a7d603..4d3ff1e47c 100644 --- a/engines/saga/rscfile.cpp +++ b/engines/saga/rscfile.cpp @@ -24,6 +24,7 @@   */  // RSC Resource file management module +  #include "saga/saga.h"  #include "saga/actor.h" @@ -329,6 +330,7 @@ bool Resource::loadContext(ResourceContext *context) {  				if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {  					resourceData->offset = 0;  					resourceData->size = resourceData->patchData->_patchFile->size(); +					resourceData->patchData->_patchFile->close();  				} else {  					delete resourceData->patchData;  					resourceData->patchData = NULL; @@ -343,18 +345,188 @@ bool Resource::loadContext(ResourceContext *context) {  bool Resource::createContexts() {  	int i;  	ResourceContext *context; +	char musicFileName[256]; +	char soundFileName[256]; +	char voicesFileName[256]; +	int soundFileIndex = 0; +	int voicesFileIndex = 0; +	bool digitalMusic = false; +	bool soundFileInArray = false; +	bool voicesFileInArray = false; +	bool multipleVoices = false; +	bool censoredVersion = false; +	uint16 voiceFileType = GAME_VOICEFILE;  	_contextsCount = 0; -	for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) +	for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {  		_contextsCount++; +		if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE) +			soundFileInArray = true; +		if (_vm->getFilesDescriptions()[i].fileType == GAME_VOICEFILE) +			voicesFileInArray = true; +	} + +	if (!soundFileInArray) { +		if (_vm->getGameType() == GType_ITE) { +			// If the sound file is not specified in the detector table, add it here +			if (Common::File::exists("sounds.rsc") || Common::File::exists("sounds.cmp")) { +				_contextsCount++; +				soundFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(soundFileName, "sounds.cmp"); +				else +					sprintf(soundFileName, "sounds.rsc"); +			} else if (Common::File::exists("soundsd.rsc") || Common::File::exists("soundsd.cmp")) { +				_contextsCount++; +				soundFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(soundFileName, "soundsd.cmp"); +				else +					sprintf(soundFileName, "soundsd.rsc"); +			} else { +				// No sound file found, don't add any file to the array +				soundFileInArray = true; +				// ITE floppy versions have both voices and sounds in voices.rsc +				voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE; +			} +		} else { +			// If the sound file is not specified in the detector table, add it here +			if (Common::File::exists("sfx.res") || Common::File::exists("sfx.cmp")) { +				_contextsCount++; +				soundFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(soundFileName, "sfx.cmp"); +				else +					sprintf(soundFileName, "sfx.res"); +			} else { +				// No sound file found, don't add any file to the array +				soundFileInArray = true; +			} +		} +	} + +	if (!voicesFileInArray) { +		if (_vm->getGameType() == GType_ITE) { +			// If the voices file is not specified in the detector table, add it here +			if (Common::File::exists("voices.rsc") || Common::File::exists("voices.cmp")) { +				_contextsCount++; +				voicesFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "voices.cmp"); +				else +					sprintf(voicesFileName, "voices.rsc"); +			} else if (Common::File::exists("voicesd.rsc") || Common::File::exists("voicesd.cmp")) { +				_contextsCount++; +				voicesFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "voicesd.cmp"); +				else +					sprintf(voicesFileName, "voicesd.rsc"); +			} else if (Common::File::exists("inherit the earth voices") ||  +					   Common::File::exists("inherit the earth voices.cmp")) { +				_contextsCount++; +				voicesFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "inherit the earth voices.cmp"); +				else +					sprintf(voicesFileName, "inherit the earth voices"); +					// 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 +			} else { +				// No voice file found, don't add any file to the array +				voicesFileInArray = true; +			} +		} else { +			// If the voices file is not specified in the detector table, add it here +			if (Common::File::exists("voicess.res") || Common::File::exists("voicess.cmp")) { +				_contextsCount++; +				voicesFileIndex = _contextsCount - 1; +				// IHNM has multiple voice files +				multipleVoices = true; +				// Note: it is assumed that the voices 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; +				} +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "voicess.cmp"); +				else +					sprintf(voicesFileName, "voicess.res"); +			} else if (Common::File::exists("voicesd.res") || Common::File::exists("voicesd.cmp")) { +				_contextsCount++; +				voicesFileIndex = _contextsCount - 1; +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "voicesd.cmp"); +				else +					sprintf(voicesFileName, "voicesd.res"); +			} else { +				// No voice file found, don't add any file to the array +				voicesFileInArray = true; +			} +		} +	} + +	if (_vm->getGameType() == GType_ITE) { +		// Check for digital music in ITE +		if (Common::File::exists("music.rsc") || Common::File::exists("music.cmp")) { +			_contextsCount++; +			digitalMusic = true; +			if (Common::File::exists("music.cmp")) +				sprintf(musicFileName, "music.cmp"); +			else +				sprintf(musicFileName, "music.rsc"); +		} else if (Common::File::exists("musicd.rsc") || Common::File::exists("musicd.cmp")) { +			_contextsCount++; +			digitalMusic = true; +			if (Common::File::exists("musicd.cmp")) +				sprintf(musicFileName, "musicd.cmp"); +			else +				sprintf(musicFileName, "musicd.rsc"); +		} else { +			digitalMusic = false; +		} +	}  	_contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));  	for (i = 0; i < _contextsCount; i++) {  		context = &_contexts[i];  		context->file = new Common::File(); -		context->fileName = _vm->getFilesDescriptions()[i].fileName; -		context->fileType = _vm->getFilesDescriptions()[i].fileType; + +		// For ITE, add the digital music file and sfx file information here +		if (_vm->getGameType() == GType_ITE && digitalMusic && i == _contextsCount - 1) { +			context->fileName = musicFileName; +			context->fileType = GAME_MUSICFILE; +		} else if (!soundFileInArray && i == soundFileIndex) { +			context->fileName = soundFileName; +			context->fileType = GAME_SOUNDFILE;	 +		} else if (!voicesFileInArray && i == voicesFileIndex) { +			context->fileName = voicesFileName; +			// can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN +			context->fileType = voiceFileType; +		} else { +			if (!(!voicesFileInArray && multipleVoices && (i > voicesFileIndex))) { +				context->fileName = _vm->getFilesDescriptions()[i].fileName; +				context->fileType = _vm->getFilesDescriptions()[i].fileType; +			} else { +				int token = (censoredVersion && (i - voicesFileIndex >= 4)) ? 1 : 0;	// censored versions don't have voice4 + +				if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS) +					sprintf(voicesFileName, "voices%i.cmp", i - voicesFileIndex + token); +				else +					sprintf(voicesFileName, "voices%i.res", i - voicesFileIndex + token); + +				context->fileName = voicesFileName; +				context->fileType = GAME_VOICEFILE; +			} +		}  		context->serial = 0;  		// IHNM has serveral different voice files, so we need to allow @@ -434,13 +606,20 @@ void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&r  	if (file->read(resourceBuffer, resourceSize) != resourceSize) {  		error("Resource::loadResource() failed to read");  	} +	if (resourceData->patchData != NULL) +		file->close();  }  static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 }; +static int metaResourceTableDemo[] = { 0, 0, 0, 0, 0, 0, 0, 285, 0 };  void Resource::loadGlobalResources(int chapter, int actorsEntrance) { -	if (chapter < 0) -		chapter = 8; +	if (chapter < 0) { +		if (_vm->getGameId() != GID_IHNM_DEMO) +			chapter = 8; +		else +			chapter = 7; +	}  	// TODO  	//if (module.voiceLUT) @@ -465,8 +644,13 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {  	byte *resourcePointer;  	size_t resourceLength; -	_vm->_resource->loadResource(resourceContext, metaResourceTable[chapter], -								 resourcePointer, resourceLength); +	if (_vm->getGameId() != GID_IHNM_DEMO) { +		_vm->_resource->loadResource(resourceContext, metaResourceTable[chapter], +									 resourcePointer, resourceLength); +	} else { +		_vm->_resource->loadResource(resourceContext, metaResourceTableDemo[chapter], +									 resourcePointer, resourceLength); +	}  	if (resourceLength == 0) {  		error("Resource::loadGlobalResources wrong metaResource"); @@ -555,22 +739,27 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {  	_vm->_anim->loadCutawayList(resourcePointer, resourceLength); -	_vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength); +	if (_metaResource.songTableID > 0) { +		_vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength); -	if (resourceLength == 0) { -		error("Resource::loadGlobalResources Can't load songs list for current track"); -	} +		if (resourceLength == 0) { +			error("Resource::loadGlobalResources Can't load songs list for current track"); +		} -	free(_vm->_music->_songTable); -	 -	_vm->_music->_songTableLen = resourceLength / 4; -	_vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen); +		free(_vm->_music->_songTable); +		 +		_vm->_music->_songTableLen = resourceLength / 4; +		_vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen); -	MemoryReadStream songS(resourcePointer, resourceLength); +		MemoryReadStream songS(resourcePointer, resourceLength); -	for (i = 0; i < _vm->_music->_songTableLen; i++) -		_vm->_music->_songTable[i] = songS.readSint32LE(); -	free(resourcePointer); +		for (i = 0; i < _vm->_music->_songTableLen; i++) +			_vm->_music->_songTable[i] = songS.readSint32LE(); +		free(resourcePointer); +	} else { +		// The IHNM demo has a fixed music track and doesn't load a song table +		_vm->_music->play(3, MUSIC_LOOP); +	}  	int voiceLUTResourceID = 0; @@ -602,6 +791,9 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {  		voiceLUTResourceID = 28;  		break;  	case 7: +		// IHNM demo +		_vm->_sndRes->setVoiceBank(0); +		voiceLUTResourceID = 17;  		break;  	case 8:  		_vm->_sndRes->setVoiceBank(0); | 
