[Scummvm-cvs-logs] CVS: scummvm/scumm resource.cpp,1.295,1.296 resource_v2.cpp,1.46,1.47 resource_v3.cpp,1.29,1.30 resource_v4.cpp,1.10,1.11 script_v6.cpp,1.425,1.426 script_v72he.cpp,2.226,2.227 script_v8.cpp,2.284,2.285 scumm.cpp,1.390,1.391 scumm.h,1.553,1.554 sound.cpp,1.431,1.432 util.cpp,2.4,2.5 util.h,2.3,2.4

Eugene Sandulenko sev at users.sourceforge.net
Wed Mar 30 14:01:26 CEST 2005


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13648/scumm

Modified Files:
	resource.cpp resource_v2.cpp resource_v3.cpp resource_v4.cpp 
	script_v6.cpp script_v72he.cpp script_v8.cpp scumm.cpp scumm.h 
	sound.cpp util.cpp util.h 
Log Message:
Support for direct reading from NES ROM:
  o extend MemoryReadStream with XOR facility
  o implement MemoryWriteStream
  o _fileHandle now is a reference to BaseScummFile class and is created on the fly
  o implement ScummNESFile class which is basically extract_mm_nes utility
  o update NES MM md5's due to above changes

NOTE: to run MM NES now you need to remove *.LFL files and (probably) rename
ROM to standard conventional name 'Maniac Mansion (XXX).nes'


Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.cpp,v
retrieving revision 1.295
retrieving revision 1.296
diff -u -d -r1.295 -r1.296
--- resource.cpp	6 Mar 2005 13:23:29 -0000	1.295
+++ resource.cpp	30 Mar 2005 21:57:48 -0000	1.296
@@ -57,7 +57,7 @@
 	/* Room -1 means close file */
 	if (room == -1) {
 		deleteRoomOffsets();
-		_fileHandle.close();
+		_fileHandle->close();
 		return;
 	}
 
@@ -136,7 +136,7 @@
 		}
 
 		// If we have substitute
-		if (_substResFileNameIndex > 0) {
+		if (_substResFileNameIndex > 0 && !(_features & GF_NES)) {
 			char tmpBuf[128];
 
 			generateSubstResFileName(buf, tmpBuf, 128, 0, _substResFileNameIndex);
@@ -186,7 +186,7 @@
 	if (_lastLoadedRoom != -1) {
 		_lastLoadedRoom = -1;
 		deleteRoomOffsets();
-		_fileHandle.close();
+		_fileHandle->close();
 	}
 }
 
@@ -226,23 +226,23 @@
 		if (!_dynamicRoomOffsets)
 			return;
 
-		_fileHandle.seek(16, SEEK_SET);
+		_fileHandle->seek(16, SEEK_SET);
 	} else {
-		_fileHandle.seek(12, SEEK_SET);	// Directly searching for the room offset block would be more generic...
+		_fileHandle->seek(12, SEEK_SET);	// Directly searching for the room offset block would be more generic...
 	}
 
-	num = _fileHandle.readByte();
+	num = _fileHandle->readByte();
 	while (num--) {
-		room = _fileHandle.readByte();
+		room = _fileHandle->readByte();
 		if (res.roomoffs[rtRoom][room] != 0xFFFFFFFF) {
-			res.roomoffs[rtRoom][room] = _fileHandle.readUint32LE();
+			res.roomoffs[rtRoom][room] = _fileHandle->readUint32LE();
 		} else {
-			_fileHandle.readUint32LE();
+			_fileHandle->readUint32LE();
 		}
 	}
 }
 
-bool ScummEngine::openFile(ScummFile &file, const char *filename) {
+bool ScummEngine::openFile(BaseScummFile &file, const char *filename) {
 	bool result = false;
 
 	if (!_containerFile.isEmpty()) {
@@ -264,8 +264,8 @@
 bool ScummEngine::openResourceFile(const char *filename, byte encByte) {
 	debugC(DEBUG_GENERAL, "openResourceFile(%s)", filename);
 	
-	if (openFile(_fileHandle, filename)) {
-		_fileHandle.setEnc(encByte);
+	if (openFile(*_fileHandle, filename)) {
+		_fileHandle->setEnc(encByte);
 		return true;
 	}
 	return false;
@@ -310,48 +310,48 @@
 
 	if (_version <= 5) {
 		/* Figure out the sizes of various resources */
-		while (!_fileHandle.eof()) {
+		while (!_fileHandle->eof()) {
 			blocktype = fileReadDword();
-			itemsize = _fileHandle.readUint32BE();
-			if (_fileHandle.ioFailed())
+			itemsize = _fileHandle->readUint32BE();
+			if (_fileHandle->ioFailed())
 				break;
 			switch (blocktype) {
 			case MKID('DOBJ'):
-				_numGlobalObjects = _fileHandle.readUint16LE();
+				_numGlobalObjects = _fileHandle->readUint16LE();
 				itemsize -= 2;
 				break;
 			case MKID('DROO'):
-				_numRooms = _fileHandle.readUint16LE();
+				_numRooms = _fileHandle->readUint16LE();
 				itemsize -= 2;
 				break;
 
 			case MKID('DSCR'):
-				_numScripts = _fileHandle.readUint16LE();
+				_numScripts = _fileHandle->readUint16LE();
 				itemsize -= 2;
 				break;
 
 			case MKID('DCOS'):
-				_numCostumes = _fileHandle.readUint16LE();
+				_numCostumes = _fileHandle->readUint16LE();
 				itemsize -= 2;
 				break;
 
 			case MKID('DSOU'):
-				_numSounds = _fileHandle.readUint16LE();
+				_numSounds = _fileHandle->readUint16LE();
 				itemsize -= 2;
 				break;
 			}
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 		}
-		_fileHandle.clearIOFailed();
-		_fileHandle.seek(0, SEEK_SET);
+		_fileHandle->clearIOFailed();
+		_fileHandle->seek(0, SEEK_SET);
 	}
 
 	while (!stop) {
 		blocktype = fileReadDword();
 
-		if (_fileHandle.ioFailed())
+		if (_fileHandle->ioFailed())
 			break;
-		itemsize = _fileHandle.readUint32BE();
+		itemsize = _fileHandle->readUint32BE();
 
 		numblock++;
 
@@ -364,34 +364,34 @@
 		case MKID('DOBJ'):
 			debug(9, "found DOBJ block, reading object table");
 			if (_version == 8)
-				num = _fileHandle.readUint32LE();
+				num = _fileHandle->readUint32LE();
 			else
-				num = _fileHandle.readUint16LE();
+				num = _fileHandle->readUint16LE();
 			assert(num == _numGlobalObjects);
 
 			if (_version == 8) {	/* FIXME: Not sure.. */
 				char buffer[40];
 				for (i = 0; i < num; i++) {
-					_fileHandle.read(buffer, 40);
+					_fileHandle->read(buffer, 40);
 					if (buffer[0]) {
 						// Add to object name-to-id map
 						_objectIDMap[buffer] = i;
 					}
-					_objectStateTable[i] = _fileHandle.readByte();
-					_objectRoomTable[i] = _fileHandle.readByte();
-					_classData[i] = _fileHandle.readUint32LE();
+					_objectStateTable[i] = _fileHandle->readByte();
+					_objectRoomTable[i] = _fileHandle->readByte();
+					_classData[i] = _fileHandle->readUint32LE();
 				}
 				memset(_objectOwnerTable, 0xFF, num);
 			} else if (_version == 7) {
-				_fileHandle.read(_objectStateTable, num);
-				_fileHandle.read(_objectRoomTable, num);
+				_fileHandle->read(_objectStateTable, num);
+				_fileHandle->read(_objectRoomTable, num);
 				memset(_objectOwnerTable, 0xFF, num);
 			} else if (_heversion >= 70) { // HE Windows titles
-				_fileHandle.read(_objectStateTable, num);
-				_fileHandle.read(_objectOwnerTable, num);
-				_fileHandle.read(_objectRoomTable, num);
+				_fileHandle->read(_objectStateTable, num);
+				_fileHandle->read(_objectOwnerTable, num);
+				_fileHandle->read(_objectRoomTable, num);
 			} else {
-				_fileHandle.read(_objectOwnerTable, num);
+				_fileHandle->read(_objectOwnerTable, num);
 				for (i = 0; i < num; i++) {
 					_objectStateTable[i] = _objectOwnerTable[i] >> OF_STATE_SHL;
 					_objectOwnerTable[i] &= OF_OWNER_MASK;
@@ -399,7 +399,7 @@
 			}
 			
 			if (_version != 8) {
-				_fileHandle.read(_classData, num * sizeof(uint32));
+				_fileHandle->read(_classData, num * sizeof(uint32));
 
 				// Swap flag endian where applicable
 #if defined(SCUMM_BIG_ENDIAN)
@@ -411,15 +411,15 @@
 
 		case MKID('RNAM'):
 			// Names of rooms
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 			debug(9, "found RNAM block, skipping");
 			break;
 		
 		case MKID('DLFL'):
-			i = _fileHandle.readUint16LE();
-			_fileHandle.seek(-2, SEEK_CUR);
+			i = _fileHandle->readUint16LE();
+			_fileHandle->seek(-2, SEEK_CUR);
 			_heV7RoomOffsets = (byte *)calloc(2 + (i * 4), 1);
-			_fileHandle.read(_heV7RoomOffsets, (2 + (i * 4)) );
+			_fileHandle->read(_heV7RoomOffsets, (2 + (i * 4)) );
 			break;
 
 		case MKID('DIRM'):
@@ -431,18 +431,18 @@
 			break;
 
 		case MKID('SVER'):
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 			warning("SVER index block not yet handled, skipping");
 			break;
 
 		case MKID('DISK'):
-			i = _fileHandle.readUint16LE();
+			i = _fileHandle->readUint16LE();
 			_heV7DiskOffsets = (byte *)calloc(i, 1);
-			_fileHandle.read(_heV7DiskOffsets, i);
+			_fileHandle->read(_heV7DiskOffsets, i);
 			break;
 
 		case MKID('INIB'):
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 			debug(2, "INIB index block not yet handled, skipping");
 			break;
 
@@ -452,9 +452,9 @@
 
 		case MKID('ANAM'):		// Used by: The Dig, FT
 			debug(9, "found ANAM block, reading audio names");
-			_numAudioNames = _fileHandle.readUint16LE();
+			_numAudioNames = _fileHandle->readUint16LE();
 			_audioNames = (char*)malloc(_numAudioNames * 9);
-			_fileHandle.read(_audioNames, _numAudioNames * 9);
+			_fileHandle->read(_audioNames, _numAudioNames * 9);
 			break;
 
 		case MKID('DIRR'):
@@ -490,7 +490,7 @@
 			break;
 
 		case MKID('LECF'):
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 			debug(2, "LECF index block not yet handled, skipping");
 			break;
 
@@ -518,11 +518,11 @@
 	debug(9, "readResTypeList(%s,%s,%s)", resTypeFromId(id), tag2str(TO_BE_32(tag)), name);
 
 	if (_version == 8)
-		num = _fileHandle.readUint32LE();
+		num = _fileHandle->readUint32LE();
 	else if (!(_features & GF_OLD_BUNDLE))
-		num = _fileHandle.readUint16LE();
+		num = _fileHandle->readUint16LE();
 	else
-		num = _fileHandle.readByte();
+		num = _fileHandle->readByte();
 
 	if (_features & GF_OLD_BUNDLE) {
 		if (num >= 0xFF) {
@@ -538,28 +538,28 @@
 		if (id == rtRoom) {
 			for (i = 0; i < num; i++)
 				res.roomno[id][i] = i;
-			_fileHandle.seek(num, SEEK_CUR);
+			_fileHandle->seek(num, SEEK_CUR);
 		} else {
 			for (i = 0; i < num; i++)
-				res.roomno[id][i] = _fileHandle.readByte();
+				res.roomno[id][i] = _fileHandle->readByte();
 		}
 		for (i = 0; i < num; i++) {
-			res.roomoffs[id][i] = _fileHandle.readUint16LE();
+			res.roomoffs[id][i] = _fileHandle->readUint16LE();
 			if (res.roomoffs[id][i] == 0xFFFF)
 				res.roomoffs[id][i] = 0xFFFFFFFF;
 		}
 
 	} else if (_features & GF_SMALL_HEADER) {
 		for (i = 0; i < num; i++) {
-			res.roomno[id][i] = _fileHandle.readByte();
-			res.roomoffs[id][i] = _fileHandle.readUint32LE();
+			res.roomno[id][i] = _fileHandle->readByte();
+			res.roomoffs[id][i] = _fileHandle->readUint32LE();
 		}
 	} else {
 		for (i = 0; i < num; i++) {
-			res.roomno[id][i] = _fileHandle.readByte();
+			res.roomno[id][i] = _fileHandle->readByte();
 		}
 		for (i = 0; i < num; i++) {
-			res.roomoffs[id][i] = _fileHandle.readUint32LE();
+			res.roomoffs[id][i] = _fileHandle->readUint32LE();
 
 			if (id == rtRoom && _heversion >= 70)
 				_heV7RoomIntOffsets[i] = res.roomoffs[id][i];
@@ -567,7 +567,7 @@
 
 		if (_heversion >= 70) {
 			for (i = 0; i < num; i++) {
-				res.globsize[id][i] = _fileHandle.readUint32LE();
+				res.globsize[id][i] = _fileHandle->readUint32LE();
 			}
 		}
 	}
@@ -704,21 +704,21 @@
 
 	openRoom(roomNr);
 
-	_fileHandle.seek(fileOffs + _fileOffset, SEEK_SET);
+	_fileHandle->seek(fileOffs + _fileOffset, SEEK_SET);
 
 	if (_features & GF_OLD_BUNDLE) {
 		if ((_version == 3) && !(_features & GF_AMIGA) && (type == rtSound)) {
 			return readSoundResourceSmallHeader(type, idx);
 		} else {
-			size = _fileHandle.readUint16LE();
-			_fileHandle.seek(-2, SEEK_CUR);
+			size = _fileHandle->readUint16LE();
+			_fileHandle->seek(-2, SEEK_CUR);
 		}
 	} else if (_features & GF_SMALL_HEADER) {
 		if (!(_features & GF_SMALL_NAMES))
-			_fileHandle.seek(8, SEEK_CUR);
-		size = _fileHandle.readUint32LE();
-		tag = _fileHandle.readUint16LE();
-		_fileHandle.seek(-6, SEEK_CUR);
+			_fileHandle->seek(8, SEEK_CUR);
+		size = _fileHandle->readUint32LE();
+		tag = _fileHandle->readUint16LE();
+		_fileHandle->seek(-6, SEEK_CUR);
 		if ((type == rtSound) && !(_features & GF_AMIGA) && !(_features & GF_FMTOWNS)) {
 			return readSoundResourceSmallHeader(type, idx);
 		}
@@ -732,20 +732,20 @@
 		if (tag != res.tags[type] && _heversion < 70) {
 			error("%s %d not in room %d at %d+%d in file %s",
 					res.name[type], idx, roomNr,
-					_fileOffset, fileOffs, _fileHandle.name());
+					_fileOffset, fileOffs, _fileHandle->name());
 		}
 
-		size = _fileHandle.readUint32BE();
-		_fileHandle.seek(-8, SEEK_CUR);
+		size = _fileHandle->readUint32BE();
+		_fileHandle->seek(-8, SEEK_CUR);
 	}
-	_fileHandle.read(createResource(type, idx, size), size);
+	_fileHandle->read(createResource(type, idx, size), size);
 
 	// dump the resource if requested
 	if (_dumpScripts && type == rtScript) {
 		dumpResource("script-", idx, getResourceAddress(rtScript, idx));
 	}
 
-	if (!_fileHandle.ioFailed()) {
+	if (!_fileHandle->ioFailed()) {
 		return 1;
 	}
 
@@ -1055,46 +1055,46 @@
 	debug(9, "readMAXS: MAXS has blocksize %d", blockSize);
 
 	if (_version == 8) {                    // CMI
-		_fileHandle.seek(50 + 50, SEEK_CUR);            // 176 - 8
-		_numVariables = _fileHandle.readUint32LE();     // 1500
-		_numBitVariables = _fileHandle.readUint32LE();  // 2048
-		_fileHandle.readUint32LE();                     // 40
-		_numScripts = _fileHandle.readUint32LE();       // 458
-		_numSounds = _fileHandle.readUint32LE();        // 789
-		_numCharsets = _fileHandle.readUint32LE();      // 1
-		_numCostumes = _fileHandle.readUint32LE();      // 446
-		_numRooms = _fileHandle.readUint32LE();         // 95
-		_fileHandle.readUint32LE();                     // 80
-		_numGlobalObjects = _fileHandle.readUint32LE(); // 1401
-		_fileHandle.readUint32LE();                     // 60
-		_numLocalObjects = _fileHandle.readUint32LE();  // 200
-		_numNewNames = _fileHandle.readUint32LE();      // 100
-		_numFlObject = _fileHandle.readUint32LE();      // 128
-		_numInventory = _fileHandle.readUint32LE();     // 80
-		_numArray = _fileHandle.readUint32LE();         // 200
-		_numVerbs = _fileHandle.readUint32LE();         // 50
+		_fileHandle->seek(50 + 50, SEEK_CUR);            // 176 - 8
+		_numVariables = _fileHandle->readUint32LE();     // 1500
+		_numBitVariables = _fileHandle->readUint32LE();  // 2048
+		_fileHandle->readUint32LE();                     // 40
+		_numScripts = _fileHandle->readUint32LE();       // 458
+		_numSounds = _fileHandle->readUint32LE();        // 789
+		_numCharsets = _fileHandle->readUint32LE();      // 1
+		_numCostumes = _fileHandle->readUint32LE();      // 446
+		_numRooms = _fileHandle->readUint32LE();         // 95
+		_fileHandle->readUint32LE();                     // 80
+		_numGlobalObjects = _fileHandle->readUint32LE(); // 1401
+		_fileHandle->readUint32LE();                     // 60
+		_numLocalObjects = _fileHandle->readUint32LE();  // 200
+		_numNewNames = _fileHandle->readUint32LE();      // 100
+		_numFlObject = _fileHandle->readUint32LE();      // 128
+		_numInventory = _fileHandle->readUint32LE();     // 80
+		_numArray = _fileHandle->readUint32LE();         // 200
+		_numVerbs = _fileHandle->readUint32LE();         // 50
 
 		_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
 		_numGlobalScripts = 2000;
 
 		_shadowPaletteSize = NUM_SHADOW_PALETTE * 256;
 	} else if (_version == 7) {
-		_fileHandle.seek(50 + 50, SEEK_CUR);
-		_numVariables = _fileHandle.readUint16LE();
-		_numBitVariables = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();                      // 40 in FT; 16 in Dig
-		_numGlobalObjects = _fileHandle.readUint16LE();
-		_numLocalObjects = _fileHandle.readUint16LE();
-		_numNewNames = _fileHandle.readUint16LE();
-		_numVerbs = _fileHandle.readUint16LE();
-		_numFlObject = _fileHandle.readUint16LE();
-		_numInventory = _fileHandle.readUint16LE();
-		_numArray = _fileHandle.readUint16LE();
-		_numRooms = _fileHandle.readUint16LE();
-		_numScripts = _fileHandle.readUint16LE();
-		_numSounds = _fileHandle.readUint16LE();
-		_numCharsets = _fileHandle.readUint16LE();
-		_numCostumes = _fileHandle.readUint16LE();
+		_fileHandle->seek(50 + 50, SEEK_CUR);
+		_numVariables = _fileHandle->readUint16LE();
+		_numBitVariables = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();                      // 40 in FT; 16 in Dig
+		_numGlobalObjects = _fileHandle->readUint16LE();
+		_numLocalObjects = _fileHandle->readUint16LE();
+		_numNewNames = _fileHandle->readUint16LE();
+		_numVerbs = _fileHandle->readUint16LE();
+		_numFlObject = _fileHandle->readUint16LE();
+		_numInventory = _fileHandle->readUint16LE();
+		_numArray = _fileHandle->readUint16LE();
+		_numRooms = _fileHandle->readUint16LE();
+		_numScripts = _fileHandle->readUint16LE();
+		_numSounds = _fileHandle->readUint16LE();
+		_numCharsets = _fileHandle->readUint16LE();
+		_numCostumes = _fileHandle->readUint16LE();
 
 		_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
 
@@ -1106,53 +1106,53 @@
 
 		_shadowPaletteSize = NUM_SHADOW_PALETTE * 256;
 	} else if (_heversion >= 70 && (blockSize == 44 + 8)) { // C++ based engine
-		_numVariables = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();
-		_numRoomVariables = _fileHandle.readUint16LE();
-		_numLocalObjects = _fileHandle.readUint16LE();
-		_numArray = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE(); // unknown
-		_fileHandle.readUint16LE(); // unknown
-		_numFlObject = _fileHandle.readUint16LE();
-		_numInventory = _fileHandle.readUint16LE();
-		_numRooms = _fileHandle.readUint16LE();
-		_numScripts = _fileHandle.readUint16LE();
-		_numSounds = _fileHandle.readUint16LE();
-		_numCharsets = _fileHandle.readUint16LE();
-		_numCostumes = _fileHandle.readUint16LE();
-		_numGlobalObjects = _fileHandle.readUint16LE();
-		_numImages = _fileHandle.readUint16LE();
-		_numSprites = _fileHandle.readUint16LE();
-		_numLocalScripts = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE(); // heap related
-		_numPalettes = _fileHandle.readUint16LE();
-		_numUnk = _fileHandle.readUint16LE();
-		_numTalkies = _fileHandle.readUint16LE();
+		_numVariables = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();
+		_numRoomVariables = _fileHandle->readUint16LE();
+		_numLocalObjects = _fileHandle->readUint16LE();
+		_numArray = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE(); // unknown
+		_fileHandle->readUint16LE(); // unknown
+		_numFlObject = _fileHandle->readUint16LE();
+		_numInventory = _fileHandle->readUint16LE();
+		_numRooms = _fileHandle->readUint16LE();
+		_numScripts = _fileHandle->readUint16LE();
+		_numSounds = _fileHandle->readUint16LE();
+		_numCharsets = _fileHandle->readUint16LE();
+		_numCostumes = _fileHandle->readUint16LE();
+		_numGlobalObjects = _fileHandle->readUint16LE();
+		_numImages = _fileHandle->readUint16LE();
+		_numSprites = _fileHandle->readUint16LE();
+		_numLocalScripts = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE(); // heap related
+		_numPalettes = _fileHandle->readUint16LE();
+		_numUnk = _fileHandle->readUint16LE();
+		_numTalkies = _fileHandle->readUint16LE();
 		_numNewNames = 10;
 
 		_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
 		_numGlobalScripts = 2048;
 
 	} else if (_heversion >= 70 && (blockSize == 38 + 8)) { // Scummsys.9x
-		_numVariables = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();
-		_numRoomVariables = _fileHandle.readUint16LE();
-		_numLocalObjects = _fileHandle.readUint16LE();
-		_numArray = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE(); // unknown
-		_fileHandle.readUint16LE(); // unknown
-		_numFlObject = _fileHandle.readUint16LE();
-		_numInventory = _fileHandle.readUint16LE();
-		_numRooms = _fileHandle.readUint16LE();
-		_numScripts = _fileHandle.readUint16LE();
-		_numSounds = _fileHandle.readUint16LE();
-		_numCharsets = _fileHandle.readUint16LE();
-		_numCostumes = _fileHandle.readUint16LE();
-		_numGlobalObjects = _fileHandle.readUint16LE();
-		_numImages = _fileHandle.readUint16LE();
-		_numSprites = _fileHandle.readUint16LE();
-		_numLocalScripts = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE(); // heap releated
+		_numVariables = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();
+		_numRoomVariables = _fileHandle->readUint16LE();
+		_numLocalObjects = _fileHandle->readUint16LE();
+		_numArray = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE(); // unknown
+		_fileHandle->readUint16LE(); // unknown
+		_numFlObject = _fileHandle->readUint16LE();
+		_numInventory = _fileHandle->readUint16LE();
+		_numRooms = _fileHandle->readUint16LE();
+		_numScripts = _fileHandle->readUint16LE();
+		_numSounds = _fileHandle->readUint16LE();
+		_numCharsets = _fileHandle->readUint16LE();
+		_numCostumes = _fileHandle->readUint16LE();
+		_numGlobalObjects = _fileHandle->readUint16LE();
+		_numImages = _fileHandle->readUint16LE();
+		_numSprites = _fileHandle->readUint16LE();
+		_numLocalScripts = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE(); // heap releated
 		_numNewNames = 10;
 
 		_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
@@ -1164,22 +1164,22 @@
 	} else if (_heversion >= 70 && blockSize > 38) { // sputm7.2
 		if (blockSize != 32 + 8)
 				error("MAXS block of size %d not supported, please report", blockSize);
-		_numVariables = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();
-		_numBitVariables = _numRoomVariables = _fileHandle.readUint16LE();
-		_numLocalObjects = _fileHandle.readUint16LE();
-		_numArray = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();
-		_numVerbs = _fileHandle.readUint16LE();
-		_numFlObject = _fileHandle.readUint16LE();
-		_numInventory = _fileHandle.readUint16LE();
-		_numRooms = _fileHandle.readUint16LE();
-		_numScripts = _fileHandle.readUint16LE();
-		_numSounds = _fileHandle.readUint16LE();
-		_numCharsets = _fileHandle.readUint16LE();
-		_numCostumes = _fileHandle.readUint16LE();
-		_numGlobalObjects = _fileHandle.readUint16LE();
-		_numImages = _fileHandle.readUint16LE();
+		_numVariables = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();
+		_numBitVariables = _numRoomVariables = _fileHandle->readUint16LE();
+		_numLocalObjects = _fileHandle->readUint16LE();
+		_numArray = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();
+		_numVerbs = _fileHandle->readUint16LE();
+		_numFlObject = _fileHandle->readUint16LE();
+		_numInventory = _fileHandle->readUint16LE();
+		_numRooms = _fileHandle->readUint16LE();
+		_numScripts = _fileHandle->readUint16LE();
+		_numSounds = _fileHandle->readUint16LE();
+		_numCharsets = _fileHandle->readUint16LE();
+		_numCostumes = _fileHandle->readUint16LE();
+		_numGlobalObjects = _fileHandle->readUint16LE();
+		_numImages = _fileHandle->readUint16LE();
 		_numNewNames = 10;
 
 		_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
@@ -1188,21 +1188,21 @@
 	} else if (_version == 6) {
 		if (blockSize != 30 + 8)
 			error("MAXS block of size %d not supported", blockSize);
-		_numVariables = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();                      // 16 in Sam/DOTT
-		_numBitVariables = _fileHandle.readUint16LE();
-		_numLocalObjects = _fileHandle.readUint16LE();
-		_numArray = _fileHandle.readUint16LE();
-		_fileHandle.readUint16LE();                      // 0 in Sam/DOTT
-		_numVerbs = _fileHandle.readUint16LE();
-		_numFlObject = _fileHandle.readUint16LE();
-		_numInventory = _fileHandle.readUint16LE();
-		_numRooms = _fileHandle.readUint16LE();
-		_numScripts = _fileHandle.readUint16LE();
-		_numSounds = _fileHandle.readUint16LE();
-		_numCharsets = _fileHandle.readUint16LE();
-		_numCostumes = _fileHandle.readUint16LE();
-		_numGlobalObjects = _fileHandle.readUint16LE();
+		_numVariables = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();                      // 16 in Sam/DOTT
+		_numBitVariables = _fileHandle->readUint16LE();
+		_numLocalObjects = _fileHandle->readUint16LE();
+		_numArray = _fileHandle->readUint16LE();
+		_fileHandle->readUint16LE();                      // 0 in Sam/DOTT
+		_numVerbs = _fileHandle->readUint16LE();
+		_numFlObject = _fileHandle->readUint16LE();
+		_numInventory = _fileHandle->readUint16LE();
+		_numRooms = _fileHandle->readUint16LE();
+		_numScripts = _fileHandle->readUint16LE();
+		_numSounds = _fileHandle->readUint16LE();
+		_numCharsets = _fileHandle->readUint16LE();
+		_numCostumes = _fileHandle->readUint16LE();
+		_numGlobalObjects = _fileHandle->readUint16LE();
 		_numNewNames = 50;
 
 		_objectRoomTable = NULL;
@@ -1214,10 +1214,10 @@
 			_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
 		}
 	} else {
-		_numVariables = _fileHandle.readUint16LE();      // 800
-		_fileHandle.readUint16LE();                      // 16
-		_numBitVariables = _fileHandle.readUint16LE();   // 2048
-		_numLocalObjects = _fileHandle.readUint16LE();   // 200
+		_numVariables = _fileHandle->readUint16LE();      // 800
+		_fileHandle->readUint16LE();                      // 16
+		_numBitVariables = _fileHandle->readUint16LE();   // 2048
+		_numLocalObjects = _fileHandle->readUint16LE();   // 200
 		_numArray = 50;
 		_numVerbs = 100;
 		// Used to be 50, which wasn't enough for MI2 and FOA. See bugs
@@ -1225,11 +1225,11 @@
 		_numNewNames = 150;
 		_objectRoomTable = NULL;
 
-		_fileHandle.readUint16LE();                      // 50
-		_numCharsets = _fileHandle.readUint16LE();       // 9
-		_fileHandle.readUint16LE();                      // 100
-		_fileHandle.readUint16LE();                      // 50
-		_numInventory = _fileHandle.readUint16LE();      // 80
+		_fileHandle->readUint16LE();                      // 50
+		_numCharsets = _fileHandle->readUint16LE();       // 9
+		_fileHandle->readUint16LE();                      // 100
+		_fileHandle->readUint16LE();                      // 50
+		_numInventory = _fileHandle->readUint16LE();      // 80
 		_numGlobalScripts = 200;
 
 		_shadowPaletteSize = 256;

Index: resource_v2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource_v2.cpp,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- resource_v2.cpp	27 Mar 2005 21:20:56 -0000	1.46
+++ resource_v2.cpp	30 Mar 2005 21:58:05 -0000	1.47
@@ -62,7 +62,7 @@
 		_numSounds = 120;
 	}
 
-	_fileHandle.seek(0, SEEK_SET);
+	_fileHandle->seek(0, SEEK_SET);
 
 	readMAXS();
 
@@ -71,9 +71,9 @@
 	_palManipPalette = 0; // Will allocate when needed
 	_palManipIntermediatePal = 0; // Will allocate when needed
 
-	_fileHandle.readUint16LE(); /* version magic number */
+	_fileHandle->readUint16LE(); /* version magic number */
 	for (i = 0; i != _numGlobalObjects; i++) {
-		byte tmp = _fileHandle.readByte();
+		byte tmp = _fileHandle->readByte();
 		_objectOwnerTable[i] = tmp & OF_OWNER_MASK;
 		_objectStateTable[i] = tmp >> OF_STATE_SHL;
 	}
@@ -81,36 +81,36 @@
 	for (i = 0; i < _numRooms; i++) {
 		res.roomno[rtRoom][i] = i;
 	}
-	_fileHandle.seek(_numRooms, SEEK_CUR);
+	_fileHandle->seek(_numRooms, SEEK_CUR);
 	for (i = 0; i < _numRooms; i++) {
-		res.roomoffs[rtRoom][i] = _fileHandle.readUint16LE();
+		res.roomoffs[rtRoom][i] = _fileHandle->readUint16LE();
 		if (res.roomoffs[rtRoom][i] == 0xFFFF)
 			res.roomoffs[rtRoom][i] = 0xFFFFFFFF;
 	}
 
 	for (i = 0; i < _numCostumes; i++) {
-		res.roomno[rtCostume][i] = _fileHandle.readByte();
+		res.roomno[rtCostume][i] = _fileHandle->readByte();
 	}
 	for (i = 0; i < _numCostumes; i++) {
-		res.roomoffs[rtCostume][i] = _fileHandle.readUint16LE();
+		res.roomoffs[rtCostume][i] = _fileHandle->readUint16LE();
 		if (res.roomoffs[rtCostume][i] == 0xFFFF)
 			res.roomoffs[rtCostume][i] = 0xFFFFFFFF;
 	}
 
 	for (i = 0; i < _numScripts; i++) {
-		res.roomno[rtScript][i] = _fileHandle.readByte();
+		res.roomno[rtScript][i] = _fileHandle->readByte();
 	}
 	for (i = 0; i < _numScripts; i++) {
-		res.roomoffs[rtScript][i] = _fileHandle.readUint16LE();
+		res.roomoffs[rtScript][i] = _fileHandle->readUint16LE();
 		if (res.roomoffs[rtScript][i] == 0xFFFF)
 			res.roomoffs[rtScript][i] = 0xFFFFFFFF;
 	}
 
 	for (i = 0; i < _numSounds; i++) {
-		res.roomno[rtSound][i] = _fileHandle.readByte();
+		res.roomno[rtSound][i] = _fileHandle->readByte();
 	}
 	for (i = 0; i < _numSounds; i++) {
-		res.roomoffs[rtSound][i] = _fileHandle.readUint16LE();
+		res.roomoffs[rtSound][i] = _fileHandle->readUint16LE();
 		if (res.roomoffs[rtSound][i] == 0xFFFF)
 			res.roomoffs[rtSound][i] = 0xFFFFFFFF;
 	}
@@ -121,18 +121,18 @@
 	if (!(_features & GF_AMIGA))
 		_musicEngine = new Player_V2(this, _midiDriver != MD_PCSPK);
 
-	_numGlobalObjects = _fileHandle.readUint16LE();
-	_fileHandle.seek(_numGlobalObjects, SEEK_CUR); // Skip object flags
-	_numRooms = _fileHandle.readByte();
-	_fileHandle.seek(_numRooms * 3, SEEK_CUR);
-	_numCostumes = _fileHandle.readByte();
-	_fileHandle.seek(_numCostumes * 3, SEEK_CUR);
-	_numScripts = _fileHandle.readByte();
-	_fileHandle.seek(_numScripts * 3, SEEK_CUR);
-	_numSounds = _fileHandle.readByte();
+	_numGlobalObjects = _fileHandle->readUint16LE();
+	_fileHandle->seek(_numGlobalObjects, SEEK_CUR); // Skip object flags
+	_numRooms = _fileHandle->readByte();
+	_fileHandle->seek(_numRooms * 3, SEEK_CUR);
+	_numCostumes = _fileHandle->readByte();
+	_fileHandle->seek(_numCostumes * 3, SEEK_CUR);
+	_numScripts = _fileHandle->readByte();
+	_fileHandle->seek(_numScripts * 3, SEEK_CUR);
+	_numSounds = _fileHandle->readByte();
 
-	_fileHandle.clearIOFailed();
-	_fileHandle.seek(0, SEEK_SET);
+	_fileHandle->clearIOFailed();
+	_fileHandle->seek(0, SEEK_SET);
 
 	readMAXS();
 
@@ -141,11 +141,11 @@
 	_palManipPalette = 0; // Will allocate when needed
 	_palManipIntermediatePal = 0; // Will allocate when needed
 
-	_fileHandle.readUint16LE(); /* version magic number */
-	int num = _fileHandle.readUint16LE();
+	_fileHandle->readUint16LE(); /* version magic number */
+	int num = _fileHandle->readUint16LE();
 	assert(num == _numGlobalObjects);
 	for (int i = 0; i != num; i++) {
-		byte tmp = _fileHandle.readByte();
+		byte tmp = _fileHandle->readByte();
 		_objectOwnerTable[i] = tmp & OF_OWNER_MASK;
 		_objectStateTable[i] = tmp >> OF_STATE_SHL;
 	}
@@ -162,7 +162,7 @@
 	closeRoom();
 	openRoom(0);
 
-	magic = _fileHandle.readUint16LE();
+	magic = _fileHandle->readUint16LE();
 
 	switch (magic) {
 		case 0x0100:

Index: resource_v3.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource_v3.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- resource_v3.cpp	1 Jan 2005 16:09:15 -0000	1.29
+++ resource_v3.cpp	30 Mar 2005 21:58:05 -0000	1.30
@@ -35,22 +35,22 @@
 		closeRoom();
 		openRoom(0);
 
-		magic = _fileHandle.readUint16LE();
+		magic = _fileHandle->readUint16LE();
 		if (magic != 0x0100)
 			warning("The magic id doesn't match (0x%X)", magic);
 
-		_numGlobalObjects = _fileHandle.readUint16LE();
-		_fileHandle.seek(_numGlobalObjects * 4, SEEK_CUR);
-		_numRooms = _fileHandle.readByte();
-		_fileHandle.seek(_numRooms * 3, SEEK_CUR);
-		_numCostumes = _fileHandle.readByte();
-		_fileHandle.seek(_numCostumes * 3, SEEK_CUR);
-		_numScripts = _fileHandle.readByte();
-		_fileHandle.seek(_numScripts * 3, SEEK_CUR);
-		_numSounds = _fileHandle.readByte();
+		_numGlobalObjects = _fileHandle->readUint16LE();
+		_fileHandle->seek(_numGlobalObjects * 4, SEEK_CUR);
+		_numRooms = _fileHandle->readByte();
+		_fileHandle->seek(_numRooms * 3, SEEK_CUR);
+		_numCostumes = _fileHandle->readByte();
+		_fileHandle->seek(_numCostumes * 3, SEEK_CUR);
+		_numScripts = _fileHandle->readByte();
+		_fileHandle->seek(_numScripts * 3, SEEK_CUR);
+		_numSounds = _fileHandle->readByte();
 
-		_fileHandle.clearIOFailed();
-		_fileHandle.seek(0, SEEK_SET);
+		_fileHandle->clearIOFailed();
+		_fileHandle->seek(0, SEEK_SET);
 
 		readMAXS();
 
@@ -59,7 +59,7 @@
 		_palManipPalette = 0; // Will allocate when needed
 		_palManipIntermediatePal = 0; // Will allocate when needed
 
-		_fileHandle.readUint16LE(); /* version magic number */
+		_fileHandle->readUint16LE(); /* version magic number */
 		readGlobalObjects();
 		readResTypeList(rtRoom, MKID('ROOM'), "room");
 		readResTypeList(rtCostume, MKID('COST'), "costume");
@@ -77,37 +77,37 @@
 		closeRoom();
 		openRoom(0);
 
-		while (!_fileHandle.eof()) {
-			itemsize = _fileHandle.readUint32LE();
-			blocktype = _fileHandle.readUint16LE();
-			if (_fileHandle.ioFailed())
+		while (!_fileHandle->eof()) {
+			itemsize = _fileHandle->readUint32LE();
+			blocktype = _fileHandle->readUint16LE();
+			if (_fileHandle->ioFailed())
 				break;
 
 			switch (blocktype) {
 			case 0x4E52:	// 'NR'
-				_fileHandle.readUint16LE();
+				_fileHandle->readUint16LE();
 				break;
 			case 0x5230:	// 'R0'
-				_numRooms = _fileHandle.readUint16LE();
+				_numRooms = _fileHandle->readUint16LE();
 				break;
 			case 0x5330:	// 'S0'
-				_numScripts = _fileHandle.readUint16LE();
+				_numScripts = _fileHandle->readUint16LE();
 				break;
 			case 0x4E30:	// 'N0'
-				_numSounds = _fileHandle.readUint16LE();
+				_numSounds = _fileHandle->readUint16LE();
 				break;
 			case 0x4330:	// 'C0'
-				_numCostumes = _fileHandle.readUint16LE();
+				_numCostumes = _fileHandle->readUint16LE();
 				break;
 			case 0x4F30:	// 'O0'
-				_numGlobalObjects = _fileHandle.readUint16LE();
+				_numGlobalObjects = _fileHandle->readUint16LE();
 				break;
 			}
-			_fileHandle.seek(itemsize - 8, SEEK_CUR);
+			_fileHandle->seek(itemsize - 8, SEEK_CUR);
 		}
 
-		_fileHandle.clearIOFailed();
-		_fileHandle.seek(0, SEEK_SET);
+		_fileHandle->clearIOFailed();
+		_fileHandle->seek(0, SEEK_SET);
 
 		readMAXS();
 
@@ -117,19 +117,19 @@
 		_palManipIntermediatePal = 0; // Will allocate when needed
 
 		while (1) {
-			itemsize = _fileHandle.readUint32LE();
+			itemsize = _fileHandle->readUint32LE();
 
-			if (_fileHandle.ioFailed())
+			if (_fileHandle->ioFailed())
 				break;
 
-			blocktype = _fileHandle.readUint16LE();
+			blocktype = _fileHandle->readUint16LE();
 
 			numblock++;
 
 			switch (blocktype) {
 
 			case 0x4E52:	// 'NR'
-				_fileHandle.seek(itemsize - 6, SEEK_CUR);
+				_fileHandle->seek(itemsize - 6, SEEK_CUR);
 				break;
 
 			case 0x5230:	// 'R0'
@@ -213,15 +213,15 @@
 }
 
 void ScummEngine_v3::readGlobalObjects() {
-	int num = _fileHandle.readUint16LE();
+	int num = _fileHandle->readUint16LE();
 	assert(num == _numGlobalObjects);
 	for (int i = 0; i != num; i++) {
-		uint32 bits = _fileHandle.readByte();
+		uint32 bits = _fileHandle->readByte();
 		byte tmp;
-		bits |= _fileHandle.readByte() << 8;
-		bits |= _fileHandle.readByte() << 16;
+		bits |= _fileHandle->readByte() << 8;
+		bits |= _fileHandle->readByte() << 16;
 		_classData[i] = bits;
-		tmp = _fileHandle.readByte();
+		tmp = _fileHandle->readByte();
 		_objectOwnerTable[i] = tmp & OF_OWNER_MASK;
 		_objectStateTable[i] = tmp >> OF_STATE_SHL;
 	}

Index: resource_v4.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource_v4.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- resource_v4.cpp	1 Jan 2005 16:09:15 -0000	1.10
+++ resource_v4.cpp	30 Mar 2005 21:58:06 -0000	1.11
@@ -35,9 +35,9 @@
 
 	openRoom(900 + no);
 
-	size = _fileHandle.readUint32LE() + 11;
+	size = _fileHandle->readUint32LE() + 11;
 
-	_fileHandle.read(createResource(6, no, size), size);
+	_fileHandle->read(createResource(6, no, size), size);
 	closeRoom();
 }
 

Index: script_v6.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v6.cpp,v
retrieving revision 1.425
retrieving revision 1.426
diff -u -d -r1.425 -r1.426
--- script_v6.cpp	28 Mar 2005 10:14:08 -0000	1.425
+++ script_v6.cpp	30 Mar 2005 21:58:07 -0000	1.426
@@ -569,10 +569,10 @@
 	int num;
 	int a, b, c;
 
-	while ((num = _fileHandle.readUint16LE()) != 0) {
-		a = _fileHandle.readUint16LE();
-		b = _fileHandle.readUint16LE();
-		c = _fileHandle.readUint16LE();
+	while ((num = _fileHandle->readUint16LE()) != 0) {
+		a = _fileHandle->readUint16LE();
+		b = _fileHandle->readUint16LE();
+		c = _fileHandle->readUint16LE();
 		if (c == kBitArray)
 			defineArray(num, kBitArray, a, b);
 		else

Index: script_v72he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v72he.cpp,v
retrieving revision 2.226
retrieving revision 2.227
diff -u -d -r2.226 -r2.227
--- script_v72he.cpp	30 Mar 2005 11:49:52 -0000	2.226
+++ script_v72he.cpp	30 Mar 2005 21:58:15 -0000	2.227
@@ -506,10 +506,10 @@
 	int num;
 	int a, b, c;
 
-	while ((num = _fileHandle.readUint16LE()) != 0) {
-		a = _fileHandle.readUint16LE();
-		b = _fileHandle.readUint16LE();
-		c = _fileHandle.readUint16LE();
+	while ((num = _fileHandle->readUint16LE()) != 0) {
+		a = _fileHandle->readUint16LE();
+		b = _fileHandle->readUint16LE();
+		c = _fileHandle->readUint16LE();
 
 		if (c == 1)
 			defineArray(num, kBitArray, 0, a, 0, b);

Index: script_v8.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v8.cpp,v
retrieving revision 2.284
retrieving revision 2.285
diff -u -d -r2.284 -r2.285
--- script_v8.cpp	30 Mar 2005 17:30:42 -0000	2.284
+++ script_v8.cpp	30 Mar 2005 21:58:31 -0000	2.285
@@ -519,9 +519,9 @@
 	int num;
 	int a, b;
 
-	while ((num = _fileHandle.readUint32LE()) != 0) {
-		a = _fileHandle.readUint32LE();
-		b = _fileHandle.readUint32LE();
+	while ((num = _fileHandle->readUint32LE()) != 0) {
+		a = _fileHandle->readUint32LE();
+		b = _fileHandle->readUint32LE();
 		
 		if (b != 0)
 			defineArray(num, kIntArray, b, a);

Index: scumm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.cpp,v
retrieving revision 1.390
retrieving revision 1.391
diff -u -d -r1.390 -r1.391
--- scumm.cpp	27 Mar 2005 21:21:05 -0000	1.390
+++ scumm.cpp	30 Mar 2005 21:58:34 -0000	1.391
@@ -422,10 +422,12 @@
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, // FIXME: number of actors
 	{"4dbff3787aedcd96b0b325f2d92d7ad9", "Freddi Fish and Luther's Maze Madness (Updated)", GID_HEGAME, 6, 100, 60, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
+	{"4f101be44a2a2323ae679e34a7c3f634", "Maniac Mansion (NES SW)", GID_MANIAC, 1, 0, 25, MDT_NONE,
+	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, "Maniac Mansion (SW).nes"},
 	{"51305e929e330e24a75a0351c8f9975e", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Updated)", GID_HEGAME, 6, 99, 30, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
-	{"635b821a347728268ca0636c45143ab2", "Maniac Mansion (NES U)", GID_MANIAC, 1, 0, 25, MDT_NONE,
-	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, 0},
+	{"59293b8524faee354f6ce7db9b5460d4", "Maniac Mansion (NES F)", GID_MANIAC, 1, 0, 25, MDT_NONE,
+	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, "Maniac Mansion (F).nes"},
 	{"6a30a07f353a75cdc602db27d73e1b42", "Putt-Putt Joins The Parade (Windows)", GID_HEGAME, 6, 70, 13, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES | GF_WINDOWS, 0, 0},
 	{"6af2419fe3db5c2fdb091ae4e5833770", "Putt-Putt Enters the Race (Demo Alt)", GID_FREDDI4, 6, 98, 61, MDT_NONE,
@@ -450,8 +452,8 @@
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
 	{"92e7727e67f5cd979d8a1070e4eb8cb3", "Putt-Putt Saves the Zoo (Updated)", GID_FREDDI4, 6, 98, 30, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
-	{"92fc0b874e44177215336568d9e6b9d5", "Maniac Mansion (NES SW)", GID_MANIAC, 1, 0, 25, MDT_NONE,
-	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, 0},
+	{"9a7f9443a7372f09f325c96176d9fec3", "Maniac Mansion (NES E)", GID_MANIAC, 1, 0, 25, MDT_NONE,
+	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, "Maniac Mansion (E).nes"},
 	{"9c143c5905055d5df7a0f014ab379aee", "Putt-Putt Goes To The Moon (Windows Demo)", GID_HEGAME, 6, 70, 13, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES | GF_WINDOWS, 0, 0},
 	{"9c92eeaf517a31b7221ec2546ab669fd", "Putt-Putt Goes To The Moon (Windows)", GID_HEGAME, 6, 70, 13, MDT_NONE,
@@ -464,8 +466,6 @@
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
 	{"b23f7cd7c304d7dff08e92a96120d5b4", "Zak McKracken and the Alien Mindbenders (v1)", GID_ZAK, 1, 0, 13, MDT_PCSPK,
 	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, 0, 0},
-	{"b5fa3b53523c849fbbcaeff86d5fd1ee", "Maniac Mansion (NES E)", GID_MANIAC, 1, 0, 25, MDT_NONE,
-	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, 0},
 	{"bf8b52fdd9a69c67f34e8e9fec72661c", "Let's Explore the Farm with Buzzy (Demo) (puttputt cd)", GID_HEGAME, 6, 71, 13, MDT_NONE,
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0},
 	{"d37c55388294b66e53e7ced3af88fa68", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Demo Updated)", GID_HEGAME, 6, 100, 30, MDT_NONE,
@@ -478,8 +478,8 @@
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, // PJSamDemo
 	{"e41de1c2a15abbcdbf9977e2d7e8a340", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Updated Ru)", GID_HEGAME, 6, 100, 61, MDT_NONE, // FIXME: number of actors
 	 GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, // FreddiCHSH
-	{"f77d2f0224042a21387899a54844fded", "Maniac Mansion (NES F)", GID_MANIAC, 1, 0, 25, MDT_NONE,
-	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, 0},
+	{"fcd1fb5aaae86dc0d23c624cd66c0aef", "Maniac Mansion (NES U)", GID_MANIAC, 1, 0, 25, MDT_NONE,
+	 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING | GF_NES, 0, "Maniac Mansion (U).nes"},
 #endif
 	{NULL, NULL, 0, 0, 0, MDT_NONE, 0, 0, 0, 0}
 };
@@ -487,7 +487,8 @@
 enum genMethods {
 	kGenMac,
 	kGenMacNoParens,
-	kGenPC
+	kGenPC,
+	kGenAsIs
 };
 
 struct SubstResFileNames {
@@ -498,6 +499,10 @@
 
 static SubstResFileNames substResFileNameTable[] = {
 	{ "Intentionally/left/blank", "", kGenMacNoParens},
+	{ "00.LFL", "Maniac Mansion (E).nes", kGenAsIs },
+	{ "00.LFL", "Maniac Mansion (F).nes", kGenAsIs },
+	{ "00.LFL", "Maniac Mansion (SW).nes", kGenAsIs },
+	{ "00.LFL", "Maniac Mansion (U).nes", kGenAsIs },
 	{ "racedemo", "500demo", kGenPC},
 	{ "Spydemo", "foxdemo", kGenPC},
 	{ "Spydemo", "FoxDemo", kGenMac },
@@ -654,6 +659,13 @@
 		File::addDefaultDirectory(_gameDataPath + "data/");
 	}
 
+	// We read data directly from NES ROM instead of extracting it with
+	// external tool
+	if (_features & GF_NES)
+		_fileHandle = new ScummNESFile();
+	else
+		_fileHandle = new ScummFile();
+
 	// The mac versions of Sam&Max, DOTT, FT and The Dig used a special meta
 	// (container) file format to store the actual SCUMM data files. The
 	// rescumm utility used to be used to extract those files. While that is
@@ -662,7 +674,7 @@
 	// here); the rest is handled by the  ScummFile class and code in
 	// openResourceFile() (and in the Sound class, for MONSTER.SOU handling).
 	if (gs.detectFilename) {
-		if (_fileHandle.open(gs.detectFilename)) {
+		if (_fileHandle->open(gs.detectFilename)) {
 			_containerFile = gs.detectFilename;
 		}
 	}
@@ -1150,6 +1162,7 @@
 	delete _pauseDialog;
 	delete _mainMenuDialog;
 	delete _versionDialog;
+	delete _fileHandle;
 
 	delete _sound;
 	free(_languageBuffer);
@@ -2880,6 +2893,8 @@
 		} else if (g->features & GF_HUMONGOUS) {
 			strcpy(detectName, base);
 			strcat(detectName, ".he0");
+		} else if (g->features & GF_NES) {
+			strcpy(detectName, base);
 		} else {
 			strcpy(detectName, base);
 			strcat(detectName, ".000");
@@ -3011,6 +3026,10 @@
 				snprintf(buf, bufsize, "%s%s", substResFileNameTable[i].macName, ext);
 				break;
 
+			case kGenAsIs:
+				strncpy(buf, substResFileNameTable[i].macName, bufsize);
+				break;
+
 			default:
 				*buf = 0;
 				break;

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.553
retrieving revision 1.554
diff -u -d -r1.553 -r1.554
--- scumm.h	28 Mar 2005 22:37:30 -0000	1.553
+++ scumm.h	30 Mar 2005 21:58:41 -0000	1.554
@@ -617,13 +617,13 @@
 	void doSentence(int c, int b, int a);
 
 	/* Should be in Resource class */
-	ScummFile _fileHandle;
+	BaseScummFile *_fileHandle;
 	uint32 _fileOffset;
 public:
 	/** The name of the (macintosh/rescumm style) container file, if any. */
 	Common::String _containerFile;
 	
-	bool openFile(ScummFile &file, const char *filename);
+	bool openFile(BaseScummFile &file, const char *filename);
 
 protected:
 	int _resourceHeaderSize;
@@ -1169,9 +1169,9 @@
 
 	
 #if defined(SCUMM_LITTLE_ENDIAN)
-	uint32 fileReadDword() { return _fileHandle.readUint32LE(); }
+	uint32 fileReadDword() { return _fileHandle->readUint32LE(); }
 #elif defined(SCUMM_BIG_ENDIAN)
-	uint32 fileReadDword() { return _fileHandle.readUint32BE(); }
+	uint32 fileReadDword() { return _fileHandle->readUint32BE(); }
 #endif
 
 public:

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.431
retrieving revision 1.432
diff -u -d -r1.431 -r1.432
--- sound.cpp	13 Mar 2005 06:07:25 -0000	1.431
+++ sound.cpp	30 Mar 2005 21:58:58 -0000	1.432
@@ -1239,24 +1239,24 @@
 
 	pos = 0;
 
-	_fileHandle.readUint32LE();
-	max_total_size = _fileHandle.readUint32BE() - 8;
+	_fileHandle->readUint32LE();
+	max_total_size = _fileHandle->readUint32BE() - 8;
 	basetag = fileReadDword();
-	total_size = _fileHandle.readUint32BE();
+	total_size = _fileHandle->readUint32BE();
 
 	debugC(DEBUG_RESOURCE, "  basetag: %s, total_size=%d", tag2str(TO_BE_32(basetag)), total_size);
 
 	if (basetag == MKID('MIDI') || basetag == MKID('iMUS')) {
 		if (_midiDriver != MD_PCSPK && _midiDriver != MD_PCJR) {
-			_fileHandle.seek(-8, SEEK_CUR);
-			_fileHandle.read(createResource(type, idx, total_size + 8), total_size + 8);
+			_fileHandle->seek(-8, SEEK_CUR);
+			_fileHandle->read(createResource(type, idx, total_size + 8), total_size + 8);
 			return 1;
 		}
 	} else if (basetag == MKID('SOU ')) {
 		best_pri = -1;
 		while (pos < total_size) {
 			tag = fileReadDword();
-			size = _fileHandle.readUint32BE() + 8;
+			size = _fileHandle->readUint32BE() + 8;
 			pos += size;
 
 			pri = -1;
@@ -1303,50 +1303,50 @@
 			if (pri > best_pri) {
 				best_pri = pri;
 				best_size = size;
-				best_offs = _fileHandle.pos();
+				best_offs = _fileHandle->pos();
 			}
 
-			_fileHandle.seek(size - 8, SEEK_CUR);
+			_fileHandle->seek(size - 8, SEEK_CUR);
 		}
 
 		if (best_pri != -1) {
-			_fileHandle.seek(best_offs - 8, SEEK_SET);
-			_fileHandle.read(createResource(type, idx, best_size), best_size);
+			_fileHandle->seek(best_offs - 8, SEEK_SET);
+			_fileHandle->read(createResource(type, idx, best_size), best_size);
 			return 1;
 		}
 	} else if (basetag == MKID('Mac0')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE() - 8;
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE() - 8;
 		byte *ptr = (byte *)calloc(total_size, 1);
-		_fileHandle.read(ptr, total_size);
+		_fileHandle->read(ptr, total_size);
 //		dumpResource("sound-", idx, ptr);
 		convertMac0Resource(type, idx, ptr, total_size);
 		free(ptr);
 		return 1;
 	} else if (basetag == MKID('Mac1')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (basetag == MKID('RIFF')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (basetag == MKID('HSHD')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (basetag == MKID('TALK')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (basetag == MKID('DIGI')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (basetag == MKID('FMUS')) {
 		// Used in 3DO version of puttputt joins the parade and probably others
@@ -1355,18 +1355,18 @@
 		File dmuFile;
 		char buffer[128];
 		debugC(DEBUG_SOUND, "Found base tag FMUS in sound %d, size %d", idx, total_size);
-		debugC(DEBUG_SOUND, "It was at position %d", _fileHandle.pos());
+		debugC(DEBUG_SOUND, "It was at position %d", _fileHandle->pos());
 		
-		_fileHandle.seek(4, SEEK_CUR);
+		_fileHandle->seek(4, SEEK_CUR);
 		// HSHD size
-		tmpsize = _fileHandle.readUint32BE();
+		tmpsize = _fileHandle->readUint32BE();
 		// skip to size part of the SDAT block
-		_fileHandle.seek(tmpsize - 4, SEEK_CUR);
+		_fileHandle->seek(tmpsize - 4, SEEK_CUR);
 		// SDAT size
-		tmpsize = _fileHandle.readUint32BE();
+		tmpsize = _fileHandle->readUint32BE();
 		
 		// SDAT contains name of file we want
-		_fileHandle.read(buffer, tmpsize - 8);
+		_fileHandle->read(buffer, tmpsize - 8);
 		// files seem to be 11 chars (8.3) unused space is replaced by spaces
 		*(strstr(buffer, " ")) = '\0';
 		
@@ -1384,15 +1384,15 @@
 		dmuFile.close();
 		return 1;
 	} else if (basetag == MKID('Crea')) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.read(createResource(type, idx, total_size), total_size - 8);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->read(createResource(type, idx, total_size), total_size - 8);
 		return 1;
 	} else if (FROM_LE_32(basetag) == max_total_size) {
-		_fileHandle.seek(-12, SEEK_CUR);
-		total_size = _fileHandle.readUint32BE();
-		_fileHandle.seek(-8, SEEK_CUR);
-		_fileHandle.read(createResource(type, idx, total_size), total_size);
+		_fileHandle->seek(-12, SEEK_CUR);
+		total_size = _fileHandle->readUint32BE();
+		_fileHandle->seek(-8, SEEK_CUR);
+		_fileHandle->read(createResource(type, idx, total_size), total_size);
 		return 1;
 	} else {
 		warning("Unrecognized base tag 0x%08x in sound %d", basetag, idx);
@@ -2164,42 +2164,42 @@
 		// Roland resources in Loom are tagless
 		// So we add an RO tag to allow imuse to detect format
 		byte *ptr, *src_ptr;
-		ro_offs = _fileHandle.pos();
-		ro_size = _fileHandle.readUint16LE();
+		ro_offs = _fileHandle->pos();
+		ro_size = _fileHandle->readUint16LE();
 
 		src_ptr = (byte *) calloc(ro_size - 4, 1);
-		_fileHandle.seek(ro_offs + 4, SEEK_SET);
-		_fileHandle.read(src_ptr, ro_size -4);
+		_fileHandle->seek(ro_offs + 4, SEEK_SET);
+		_fileHandle->read(src_ptr, ro_size -4);
 
 		ptr = createResource(type, idx, ro_size + 2);
 		memcpy(ptr, "RO", 2); ptr += 2;
 		memcpy(ptr, src_ptr, ro_size - 4); ptr += ro_size - 4;
 		return 1;
 	} else if (_features & GF_OLD_BUNDLE) {
-		wa_offs = _fileHandle.pos();
-		wa_size = _fileHandle.readUint16LE();
-		_fileHandle.seek(wa_size - 2, SEEK_CUR);
+		wa_offs = _fileHandle->pos();
+		wa_size = _fileHandle->readUint16LE();
+		_fileHandle->seek(wa_size - 2, SEEK_CUR);
 
 		if (!(_features & GF_ATARI_ST || _features & GF_MACINTOSH)) {
-			ad_offs = _fileHandle.pos();
-			ad_size = _fileHandle.readUint16LE();
+			ad_offs = _fileHandle->pos();
+			ad_size = _fileHandle->readUint16LE();
 		}
-		_fileHandle.seek(4, SEEK_CUR);
+		_fileHandle->seek(4, SEEK_CUR);
 		total_size = wa_size + ad_size;
 	} else {
-		total_size = size = _fileHandle.readUint32LE();
-		tag = _fileHandle.readUint16LE();
+		total_size = size = _fileHandle->readUint32LE();
+		tag = _fileHandle->readUint16LE();
 		debug(4, "  tag='%c%c', size=%d", (char) (tag & 0xff),
 				(char) ((tag >> 8) & 0xff), size);
 
 		if (tag == 0x4F52) { // RO
-			ro_offs = _fileHandle.pos();
+			ro_offs = _fileHandle->pos();
 			ro_size = size;
 		} else {
 			pos = 6;
 			while (pos < total_size) {
-				size = _fileHandle.readUint32LE();
-				tag = _fileHandle.readUint16LE();
+				size = _fileHandle->readUint32LE();
+				tag = _fileHandle->readUint16LE();
 				debug(4, "  tag='%c%c', size=%d", (char) (tag & 0xff),
 						(char) ((tag >> 8) & 0xff), size);
 				pos += size;
@@ -2208,10 +2208,10 @@
 				// resources.
 				if ((tag == 0x4441) && !(ad_offs)) { // AD
 					ad_size = size;
-					ad_offs = _fileHandle.pos();
+					ad_offs = _fileHandle->pos();
 				} else if ((tag == 0x4157) && !(wa_offs)) { // WA
 					wa_size = size;
-					wa_offs = _fileHandle.pos();
+					wa_offs = _fileHandle->pos();
 				} else { // other AD, WA and nested SO resources
 					if (tag == 0x4F53) { // SO
 						pos -= size;
@@ -2219,7 +2219,7 @@
 						pos += 6;
 					}
 				}
-				_fileHandle.seek(size - 6, SEEK_CUR);
+				_fileHandle->seek(size - 6, SEEK_CUR);
 			}
 		}
 	}
@@ -2236,31 +2236,31 @@
 		byte *ptr;
 		if (_features & GF_OLD_BUNDLE) {
 			ptr = (byte *) calloc(ad_size - 4, 1);
-			_fileHandle.seek(ad_offs + 4, SEEK_SET);
-			_fileHandle.read(ptr, ad_size - 4);
+			_fileHandle->seek(ad_offs + 4, SEEK_SET);
+			_fileHandle->read(ptr, ad_size - 4);
 			convertADResource(type, idx, ptr, ad_size - 4);
 			free(ptr);
 			return 1;
 		} else {
 			ptr = (byte *) calloc(ad_size - 6, 1);
-			_fileHandle.seek(ad_offs, SEEK_SET);
-			_fileHandle.read(ptr, ad_size - 6);
+			_fileHandle->seek(ad_offs, SEEK_SET);
+			_fileHandle->read(ptr, ad_size - 6);
 			convertADResource(type, idx, ptr, ad_size - 6);
 			free(ptr);
 			return 1;
 		} 
 	} else if (((_midiDriver == MD_PCJR) || (_midiDriver == MD_PCSPK)) && wa_offs != 0) {
 		if (_features & GF_OLD_BUNDLE) {
-			_fileHandle.seek(wa_offs, SEEK_SET);
-			_fileHandle.read(createResource(type, idx, wa_size), wa_size);
+			_fileHandle->seek(wa_offs, SEEK_SET);
+			_fileHandle->read(createResource(type, idx, wa_size), wa_size);
 		} else {
-			_fileHandle.seek(wa_offs - 6, SEEK_SET);
-			_fileHandle.read(createResource(type, idx, wa_size + 6), wa_size + 6);
+			_fileHandle->seek(wa_offs - 6, SEEK_SET);
+			_fileHandle->read(createResource(type, idx, wa_size + 6), wa_size + 6);
 		}
 		return 1;
 	} else if (ro_offs != 0) {
-		_fileHandle.seek(ro_offs - 2, SEEK_SET);
-		_fileHandle.read(createResource(type, idx, ro_size - 4), ro_size - 4);
+		_fileHandle->seek(ro_offs - 2, SEEK_SET);
+		_fileHandle->read(createResource(type, idx, ro_size - 4), ro_size - 4);
 		return 1;
 	}
 	res.roomoffs[type][idx] = 0xFFFFFFFF;

Index: util.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/util.cpp,v
retrieving revision 2.4
retrieving revision 2.5
diff -u -d -r2.4 -r2.5
--- util.cpp	28 Jan 2005 20:47:50 -0000	2.4
+++ util.cpp	30 Mar 2005 21:59:11 -0000	2.5
@@ -21,6 +21,7 @@
 
 #include "scumm/util.h"
 #include "common/util.h"
+#include "common/md5.h"
 
 namespace Scumm {
 
@@ -28,7 +29,6 @@
 #pragma mark --- ScummFile ---
 #pragma mark -
 
-
 ScummFile::ScummFile() : _encbyte(0), _subFileStart(0), _subFileLen(0) {
 }
 
@@ -271,4 +271,943 @@
 	return str;
 }
 
+#pragma mark -
+#pragma mark --- ScummNESFile ---
+#pragma mark -
+
+	ScummNESFile::ScummNESFile() : _stream(0), _buf(0), _ROMset(kROMsetNum) {
+}
+
+uint32 ScummNESFile::write(const void *, uint32) {
+	error("ScummNESFile does not support writing!");
+	return 0;
+}
+
+void ScummNESFile::setEnc(byte enc) {
+	_stream->setEnc(enc);
+}
+
+static ScummNESFile::t_resource res_roomgfx[40] = {
+	{ {0x04001,0x04001,0x04001,0x04001}, {0x03C9,0x03B9,0x03F0,0x0426}, NES_ROOMGFX },
+	{ {0x043CA,0x043BA,0x043F1,0x04427}, {0x069E,0x069E,0x069E,0x069E}, NES_ROOMGFX },
+	{ {0x04A68,0x04A58,0x04A8F,0x04AC5}, {0x0327,0x0327,0x0327,0x0327}, NES_ROOMGFX },
+	{ {0x04D8F,0x04D7F,0x04DB6,0x04DEC}, {0x053B,0x053B,0x053B,0x053B}, NES_ROOMGFX },
+	{ {0x052CA,0x052BA,0x052F1,0x05327}, {0x06BE,0x06BE,0x06BE,0x06BE}, NES_ROOMGFX },
+	{ {0x05988,0x05978,0x059AF,0x059E5}, {0x0682,0x0682,0x0682,0x0682}, NES_ROOMGFX },
+	{ {0x0600A,0x05FFA,0x06031,0x06067}, {0x0778,0x0778,0x0778,0x0778}, NES_ROOMGFX },
+	{ {0x06782,0x06772,0x067A9,0x067DF}, {0x0517,0x0517,0x0517,0x0517}, NES_ROOMGFX },
+	{ {0x06C99,0x06C89,0x06CC0,0x06CF6}, {0x07FB,0x07FB,0x07FB,0x07FB}, NES_ROOMGFX },
+	{ {0x07494,0x07484,0x074BB,0x074F1}, {0x07BE,0x07BE,0x07BE,0x07BE}, NES_ROOMGFX },
+	{ {0x08001,0x08001,0x08001,0x08001}, {0x07A5,0x07A5,0x07A5,0x07A5}, NES_ROOMGFX },
+	{ {0x087A6,0x087A6,0x087A6,0x087A6}, {0x06DD,0x06DD,0x06DD,0x06DD}, NES_ROOMGFX },
+	{ {0x08E83,0x08E83,0x08E83,0x08E83}, {0x04EA,0x04EA,0x04EA,0x04EA}, NES_ROOMGFX },
+	{ {0x0936D,0x0936D,0x0936D,0x0936D}, {0x0846,0x0846,0x07E2,0x07E2}, NES_ROOMGFX },
+	{ {0x09BB3,0x09BB3,0x09B4F,0x09B4F}, {0x08C8,0x08C8,0x0791,0x0791}, NES_ROOMGFX },
+	{ {0x0A47B,0x0A47B,0x0A2E0,0x0A2E0}, {0x0844,0x0844,0x07B5,0x07B5}, NES_ROOMGFX },
+	{ {0x0ACBF,0x0ACBF,0x0AA95,0x0AA95}, {0x0515,0x0515,0x0515,0x0515}, NES_ROOMGFX },
+	{ {0x0B1D4,0x0B1D4,0x0AFAA,0x0AFAA}, {0x0799,0x0799,0x0799,0x0799}, NES_ROOMGFX },
+	{ {0x0B96D,0x0B96D,0x0B743,0x0B743}, {0x04BB,0x04BB,0x04BF,0x04BB}, NES_ROOMGFX },
+	{ {0x07C52,0x07C42,0x0BC02,0x0BBFE}, {0x0319,0x0319,0x0319,0x0319}, NES_ROOMGFX },
+	{ {0x0C001,0x0C001,0x0C001,0x0C001}, {0x0464,0x0464,0x0464,0x0464}, NES_ROOMGFX },
+	{ {0x0C465,0x0C465,0x0C465,0x0C465}, {0x076D,0x076D,0x072C,0x072C}, NES_ROOMGFX },
+	{ {0x0CBD2,0x0CBD2,0x0CB91,0x0CB91}, {0x0827,0x0827,0x0827,0x0827}, NES_ROOMGFX },
+	{ {0x0D3F9,0x0D3F9,0x0D3B8,0x0D3B8}, {0x0515,0x0515,0x0515,0x0515}, NES_ROOMGFX },
+	{ {0x0D90E,0x0D90E,0x0D8CD,0x0D8CD}, {0x064E,0x064E,0x064E,0x064E}, NES_ROOMGFX },
+	{ {0x0DF5C,0x0DF5C,0x0DF1B,0x0DF1B}, {0x0775,0x0775,0x0775,0x0775}, NES_ROOMGFX },
+	{ {0x0E6D1,0x0E6D1,0x0E690,0x0E690}, {0x06DD,0x06DD,0x06DD,0x06DD}, NES_ROOMGFX },
+	{ {0x0EDAE,0x0EDAE,0x0ED6D,0x0ED6D}, {0x0376,0x0376,0x0376,0x0376}, NES_ROOMGFX },
+	{ {0x0F124,0x0F124,0x0F0E3,0x0F0E3}, {0x05F7,0x05F7,0x05F7,0x05F7}, NES_ROOMGFX },
+	{ {0x0F71B,0x0F71B,0x0F6DA,0x0F6DA}, {0x0787,0x0787,0x0791,0x0787}, NES_ROOMGFX },
+	{ {0x10001,0x10001,0x07C79,0x10001}, {0x02D6,0x02D6,0x02D6,0x02D6}, NES_ROOMGFX },
+	{ {0x102D7,0x102D7,0x10001,0x102D7}, {0x06A3,0x06A3,0x06A3,0x06A3}, NES_ROOMGFX },
+	{ {0x1097A,0x1097A,0x106A4,0x1097A}, {0x099F,0x099F,0x0921,0x0921}, NES_ROOMGFX },
+	{ {0x11319,0x11319,0x10FC5,0x1129B}, {0x0361,0x0361,0x0361,0x0361}, NES_ROOMGFX },
+	{ {0x1167A,0x1167A,0x11326,0x115FC}, {0x0489,0x0489,0x0489,0x0489}, NES_ROOMGFX },
+	{ {0x11B03,0x11B03,0x117AF,0x11A85}, {0x0437,0x0437,0x0437,0x0437}, NES_ROOMGFX },
+	{ {0x11F3A,0x11F3A,0x11BE6,0x11EBC}, {0x084D,0x084D,0x084F,0x070D}, NES_ROOMGFX },
+	{ {0x0BE28,0x12787,0x12435,0x07CAF}, {0x0199,0x0199,0x0199,0x0199}, NES_ROOMGFX },
+	{ {0x12787,0x12920,0x125CE,0x125C9}, {0x09A7,0x09A7,0x0947,0x0947}, NES_ROOMGFX },
+	{ {0x1312E,0x132C7,0x12F15,0x12F10}, {0x037A,0x037A,0x037A,0x037A}, NES_ROOMGFX }
+};
+
+static ScummNESFile::t_resource res_costumegfx[2] = {
+	{ {0x30001,0x30001,0x2EFE1,0x30001}, {0x0EB8,0x0EB8,0x0EB8,0x0EB8}, NES_COSTUMEGFX },
+	{ {0x2F9F1,0x2F9F1,0x30001,0x2F608}, {0x0340,0x0340,0x0340,0x0340}, NES_COSTUMEGFX }
+};
+
+static ScummNESFile::t_resource res_rooms[55] = {
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_ROOM },
+	{ {0x14001,0x14001,0x14001,0x14001}, {0x0D0C,0x0D0C,0x0D12,0x0D76}, NES_ROOM },
+	{ {0x134A8,0x13641,0x1328F,0x1328A}, {0x04B3,0x04B3,0x04B3,0x04C6}, NES_ROOM },
+	{ {0x15397,0x15397,0x15367,0x15451}, {0x0849,0x0849,0x0859,0x0885}, NES_ROOM },
+	{ {0x15C68,0x15C68,0x13742,0x13750}, {0x0685,0x0685,0x0694,0x0693}, NES_ROOM },
+	{ {0x16381,0x16381,0x15C45,0x15D68}, {0x0715,0x0715,0x0707,0x0709}, NES_ROOM },
+	{ {0x1395B,0x16CE8,0x1658F,0x166D4}, {0x04E7,0x04E7,0x04E0,0x0528}, NES_ROOM },
+	{ {0x16CE8,0x18001,0x16A6F,0x16BFC}, {0x0AC0,0x0ABF,0x0AC8,0x0ACC}, NES_ROOM },
+	{ {0x18001,0x171CF,0x18001,0x18001}, {0x06BA,0x06BA,0x06C7,0x06E2}, NES_ROOM },
+	{ {0x17AED,0x13AF4,0x1789C,0x17A63}, {0x03CB,0x03D2,0x03EA,0x03E5}, NES_ROOM },
+	{ {0x18BE7,0x18E1A,0x18C09,0x18C3B}, {0x0663,0x0663,0x0649,0x066A}, NES_ROOM },
+	{ {0x192A6,0x194D9,0x192AE,0x19301}, {0x0580,0x04A9,0x04AB,0x049E}, NES_ROOM },
+	{ {0x19A44,0x19BA0,0x19982,0x199C8}, {0x0443,0x0443,0x0447,0x044B}, NES_ROOM },
+	{ {0x1A106,0x1A262,0x1A04D,0x1A0B1}, {0x0563,0x047C,0x047E,0x0478}, NES_ROOM },
+	{ {0x1A669,0x1A6DE,0x1A4CB,0x1A529}, {0x0446,0x0446,0x0444,0x043F}, NES_ROOM },
+	{ {0x1AAAF,0x1AB24,0x1A90F,0x1A968}, {0x03A7,0x03A7,0x03B9,0x03C8}, NES_ROOM },
+	{ {0x1AE56,0x1AECB,0x1ACC8,0x1AD30}, {0x07E3,0x07E3,0x07E9,0x086F}, NES_ROOM },
+	{ {0x1B699,0x1B70E,0x1B511,0x1B5FF}, {0x0692,0x0692,0x06A4,0x069B}, NES_ROOM },
+	{ {0x1C001,0x1C001,0x1C001,0x1C001}, {0x0B49,0x0ACA,0x0B1A,0x0AA9}, NES_ROOM },
+	{ {0x1CD09,0x1CC8A,0x1CCFD,0x1CC97}, {0x04C6,0x04C6,0x0486,0x049E}, NES_ROOM },
+	{ {0x1D4C2,0x1D443,0x1D482,0x1D42C}, {0x0568,0x0568,0x0579,0x05A8}, NES_ROOM },
+	{ {0x1DF6C,0x1DEED,0x1DF61,0x1DF71}, {0x0514,0x0514,0x051E,0x054E}, NES_ROOM },
+	{ {0x1E8FA,0x1E87B,0x1E8EC,0x1E9D1}, {0x05CC,0x05CC,0x05CF,0x0606}, NES_ROOM },
+	{ {0x1EF83,0x1EF04,0x1EF73,0x1F0A2}, {0x0389,0x0389,0x0398,0x039A}, NES_ROOM },
+	{ {0x1F5E4,0x1F565,0x1F5F0,0x1F74E}, {0x0723,0x0723,0x071A,0x071C}, NES_ROOM },
+	{ {0x20001,0x20001,0x20001,0x20001}, {0x049A,0x049A,0x049C,0x04B5}, NES_ROOM },
+	{ {0x20511,0x20511,0x2051E,0x2052E}, {0x04F8,0x04F8,0x051E,0x04FF}, NES_ROOM },
+	{ {0x21666,0x21666,0x21725,0x2172E}, {0x05CB,0x05D5,0x05D5,0x05DB}, NES_ROOM },
+	{ {0x21DD6,0x21DE0,0x21EA5,0x21EAD}, {0x046B,0x046B,0x047F,0x0489}, NES_ROOM },
+	{ {0x222F0,0x222FA,0x223D1,0x223E1}, {0x0460,0x0460,0x0460,0x0465}, NES_ROOM },
+	{ {0x227B6,0x227C0,0x22897,0x228AC}, {0x0909,0x0909,0x090D,0x0957}, NES_ROOM },
+	{ {0x24001,0x24001,0x24001,0x24001}, {0x0366,0x0366,0x0378,0x037E}, NES_ROOM },
+	{ {0x23BDF,0x247DB,0x247C9,0x2481A}, {0x03CA,0x03CA,0x03CA,0x03CA}, NES_ROOM },
+	{ {0x247DB,0x24BA5,0x24B93,0x24BE4}, {0x050D,0x050D,0x050D,0x050D}, NES_ROOM },
+	{ {0x25ACF,0x23BE9,0x25267,0x252C0}, {0x0346,0x0346,0x0346,0x0346}, NES_ROOM },
+	{ {0x1BDBD,0x17DB5,0x17CD0,0x1BD30}, {0x01CA,0x01CA,0x01CA,0x01CA}, NES_ROOM },
+	{ {0x25E15,0x25E99,0x255AD,0x25606}, {0x0457,0x0457,0x0453,0x046D}, NES_ROOM },
+	{ {0x2626C,0x262F0,0x25A00,0x25A73}, {0x0547,0x0547,0x053E,0x055A}, NES_ROOM },
+	{ {0x267B3,0x26837,0x25F3E,0x25FCD}, {0x064A,0x064A,0x0647,0x0654}, NES_ROOM },
+	{ {0x1FD72,0x1FCF3,0x1BC49,0x26C98}, {0x024B,0x024B,0x024B,0x024B}, NES_ROOM },
+	{ {0x2739A,0x2741E,0x26B58,0x26EE3}, {0x01FA,0x01FA,0x01FA,0x01FA}, NES_ROOM },
+	{ {0x2766D,0x276F1,0x26E27,0x271DD}, {0x0219,0x0219,0x0217,0x0217}, NES_ROOM },
+	{ {0x28001,0x28001,0x27345,0x27713}, {0x02F4,0x02F4,0x02F4,0x02F4}, NES_ROOM },
+	{ {0x284D6,0x284D6,0x27829,0x28001}, {0x045C,0x045C,0x045C,0x045C}, NES_ROOM },
+	{ {0x289A3,0x289A3,0x28001,0x284CE}, {0x09CF,0x09CF,0x098A,0x0975}, NES_ROOM },
+	{ {0x293C6,0x293C6,0x289DF,0x28E97}, {0x05A0,0x05A0,0x05A1,0x05E6}, NES_ROOM },
+	{ {0x27B65,0x27BE9,0x2A442,0x27C3A}, {0x0201,0x0201,0x0201,0x0201}, NES_ROOM },
+	{ {0x2ADD1,0x2ADE3,0x2A6E9,0x2A9D6}, {0x0325,0x0325,0x0325,0x0325}, NES_ROOM },
+	{ {0x2B339,0x2B34B,0x1FD75,0x2AF88}, {0x01FC,0x01FC,0x01FC,0x01FC}, NES_ROOM },
+	{ {0x2B535,0x2B547,0x2AC64,0x2B184}, {0x02A9,0x02A9,0x02A9,0x02A9}, NES_ROOM },
+	{ {0x2B7DE,0x2B7F0,0x2AF0D,0x2B42D}, {0x02DE,0x02DE,0x02D1,0x02DF}, NES_ROOM },
+	{ {0x2C001,0x2C001,0x2B2E6,0x2B818}, {0x03CE,0x03CE,0x03CC,0x03EC}, NES_ROOM },
+	{ {0x2BBC0,0x2BBD2,0x23D61,0x2BD67}, {0x0205,0x0205,0x0205,0x0209}, NES_ROOM },
+	{ {0x2C53A,0x2C53A,0x2B818,0x2C001}, {0x0170,0x0170,0x0168,0x0168}, NES_ROOM },
+	{ {0x13E42,0x2BDD7,0x27CF6,0x2C4BF}, {0x0169,0x0169,0x0169,0x0169}, NES_ROOM }
+};
+
+static ScummNESFile::t_resource res_scripts[179] = {
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT }, // 0
+	{ {0x29966,0x29966,0x28F80,0x2947D}, {0x044D,0x044D,0x043B,0x0480}, NES_SCRIPT },
+	{ {0x29DB3,0x29DB3,0x293BB,0x298FD}, {0x0207,0x0207,0x0209,0x0226}, NES_SCRIPT },
+	{ {0x29FBA,0x29FBA,0x295C4,0x29B23}, {0x009F,0x009F,0x00AB,0x0092}, NES_SCRIPT },
+	{ {0x2A059,0x2A059,0x2966F,0x29BB5}, {0x03F4,0x03F4,0x03FD,0x040C}, NES_SCRIPT },
+	{ {0x2A44D,0x2A44D,0x29A6C,0x29FC1}, {0x01A1,0x01A1,0x01A1,0x01A1}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x2A5EE,0x2A5EE,0x29C0D,0x2A162}, {0x004A,0x005C,0x005C,0x005C}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x2A638,0x2A64A,0x29C69,0x2A1BE}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x2C6AA,0x2C6AA,0x2B980,0x2C169}, {0x000D,0x000D,0x000D,0x000D}, NES_SCRIPT }, // 10
+	{ {0x2C6B7,0x2C6B7,0x2B98D,0x2C176}, {0x000D,0x000D,0x000D,0x000D}, NES_SCRIPT },
+	{ {0x186BB,0x17889,0x186C8,0x186E3}, {0x0040,0x0040,0x0040,0x0040}, NES_SCRIPT },
+	{ {0x186FB,0x178C9,0x18708,0x18723}, {0x0016,0x0016,0x0016,0x0016}, NES_SCRIPT },
+	{ {0x1B639,0x1B6AE,0x1B4B1,0x1B59F}, {0x0046,0x0046,0x0046,0x0046}, NES_SCRIPT },
+	{ {0x1EEC6,0x1EE47,0x1EEBB,0x1EFD7}, {0x00BD,0x00BD,0x00B8,0x00CB}, NES_SCRIPT },
+	{ {0x21C31,0x21C3B,0x21CFA,0x21D09}, {0x0055,0x0055,0x005C,0x0054}, NES_SCRIPT },
+	{ {0x177A8,0x18AC0,0x17537,0x176C8}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT },
+	{ {0x1FD07,0x1FC88,0x1FD0A,0x1FE6A}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT },
+	{ {0x1FD2E,0x1FCAF,0x1FD31,0x1FE91}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT },
+	{ {0x1BD2B,0x1BDA0,0x1BBB5,0x1BC9A}, {0x0022,0x0022,0x0022,0x0022}, NES_SCRIPT }, // 20
+	{ {0x15BE0,0x15BE0,0x15BC0,0x15CD6}, {0x0088,0x0088,0x0085,0x0092}, NES_SCRIPT },
+	{ {0x22241,0x2224B,0x22324,0x22336}, {0x0020,0x0020,0x001E,0x001C}, NES_SCRIPT },
+	{ {0x22261,0x2226B,0x22342,0x22352}, {0x008F,0x008F,0x008F,0x008F}, NES_SCRIPT },
+	{ {0x1924A,0x1947D,0x19252,0x192A5}, {0x002B,0x002B,0x002B,0x002B}, NES_SCRIPT },
+	{ {0x1CB4A,0x1CACB,0x1CB1B,0x1CAAA}, {0x0061,0x0061,0x006D,0x0069}, NES_SCRIPT },
+	{ {0x1CBAB,0x1CB2C,0x1CB88,0x1CB13}, {0x003C,0x003C,0x004C,0x0054}, NES_SCRIPT },
+	{ {0x1CBE7,0x1CB68,0x1CBD4,0x1CB67}, {0x0042,0x0042,0x0044,0x0048}, NES_SCRIPT },
+	{ {0x1CC29,0x1CBAA,0x1CC18,0x1CBAF}, {0x004F,0x004F,0x0053,0x0058}, NES_SCRIPT },
+	{ {0x2049B,0x2049B,0x2049D,0x204B6}, {0x0076,0x0076,0x0081,0x0078}, NES_SCRIPT },
+	{ {0x16A96,0x16A96,0x1634C,0x16471}, {0x0035,0x0035,0x0035,0x0035}, NES_SCRIPT }, // 30
+	{ {0x16ACB,0x16ACB,0x16381,0x164A6}, {0x001C,0x001C,0x001C,0x001C}, NES_SCRIPT },
+	{ {0x16AE7,0x16AE7,0x1639D,0x164C2}, {0x0014,0x0014,0x0014,0x0014}, NES_SCRIPT },
+	{ {0x16AFB,0x16AFB,0x163B1,0x164D6}, {0x001C,0x001C,0x001C,0x001C}, NES_SCRIPT },
+	{ {0x16B17,0x16B17,0x163CD,0x164F2}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT },
+	{ {0x16B3E,0x16B3E,0x163F4,0x16519}, {0x01AA,0x01AA,0x019B,0x01BB}, NES_SCRIPT },
+	{ {0x1D1CF,0x1D150,0x1D183,0x1D135}, {0x0096,0x0096,0x0094,0x008D}, NES_SCRIPT },
+	{ {0x1D265,0x1D1E6,0x1D217,0x1D1C2}, {0x010E,0x010E,0x0117,0x0119}, NES_SCRIPT },
+	{ {0x1D373,0x1D2F4,0x1D32E,0x1D2DB}, {0x001C,0x001C,0x001C,0x001C}, NES_SCRIPT },
+	{ {0x1D38F,0x1D310,0x1D34A,0x1D2F7}, {0x0056,0x0056,0x0056,0x0056}, NES_SCRIPT },
+	{ {0x1D3E5,0x1D366,0x1D3A0,0x1D34D}, {0x0072,0x0072,0x0072,0x0072}, NES_SCRIPT }, // 40
+	{ {0x1E480,0x1E401,0x1E47F,0x1E4BF}, {0x0028,0x0028,0x0028,0x0028}, NES_SCRIPT },
+	{ {0x1E4A8,0x1E429,0x1E4A7,0x1E4E7}, {0x017D,0x017D,0x0175,0x01E0}, NES_SCRIPT },
+	{ {0x1E625,0x1E5A6,0x1E61C,0x1E6C7}, {0x0229,0x0229,0x022B,0x0241}, NES_SCRIPT },
+	{ {0x28932,0x28932,0x27C85,0x2845D}, {0x0071,0x0071,0x0071,0x0071}, NES_SCRIPT },
+	{ {0x17EB8,0x13EC6,0x17C86,0x17E48}, {0x004D,0x004D,0x004A,0x004C}, NES_SCRIPT },
+	{ {0x162ED,0x162ED,0x13DD6,0x13DE3}, {0x0039,0x0039,0x0039,0x0039}, NES_SCRIPT },
+	{ {0x18711,0x178DF,0x1871E,0x18739}, {0x028B,0x028B,0x0270,0x0296}, NES_SCRIPT },
+	{ {0x1899C,0x17B6A,0x1898E,0x189CF}, {0x00BB,0x00BB,0x00C0,0x00C2}, NES_SCRIPT },
+	{ {0x18A57,0x17C25,0x18A4E,0x18A91}, {0x018B,0x018B,0x01B6,0x01A5}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT }, // 50
+	{ {0x19E87,0x19FE3,0x19DC9,0x19E13}, {0x00ED,0x00ED,0x00EE,0x00F3}, NES_SCRIPT },
+	{ {0x21C86,0x21C90,0x21D56,0x21D5D}, {0x00F6,0x00F6,0x00F5,0x00F6}, NES_SCRIPT },
+	{ {0x1E84E,0x1E7CF,0x1E847,0x1E908}, {0x009B,0x009B,0x0094,0x00B8}, NES_SCRIPT },
+	{ {0x21D7C,0x21D86,0x21E4B,0x21E53}, {0x0047,0x0047,0x0047,0x0047}, NES_SCRIPT },
+	{ {0x2C6C4,0x2C6C4,0x2B99A,0x2C183}, {0x004D,0x004D,0x004D,0x004D}, NES_SCRIPT },
+	{ {0x16326,0x16326,0x13E0F,0x13E1C}, {0x0024,0x0024,0x0024,0x0024}, NES_SCRIPT },
+	{ {0x14D0D,0x14D0D,0x14D13,0x14D77}, {0x0014,0x0014,0x0014,0x0014}, NES_SCRIPT },
+	{ {0x177CF,0x18AE7,0x1755E,0x176EF}, {0x0059,0x0059,0x0054,0x0059}, NES_SCRIPT },
+	{ {0x17828,0x18B40,0x175B2,0x17748}, {0x0109,0x011E,0x011A,0x013F}, NES_SCRIPT },
+	{ {0x17931,0x18C5E,0x176CC,0x17887}, {0x0009,0x0009,0x0009,0x0009}, NES_SCRIPT }, // 60
+	{ {0x14D21,0x14D21,0x14D27,0x14D8B}, {0x01B6,0x01B6,0x01B9,0x01D4}, NES_SCRIPT },
+	{ {0x2B0F6,0x2B108,0x2AA0E,0x2ACFB}, {0x0243,0x0243,0x0256,0x028D}, NES_SCRIPT },
+	{ {0x230BF,0x230C9,0x231A4,0x23203}, {0x067F,0x067F,0x06D2,0x0779}, NES_SCRIPT },
+	{ {0x2C711,0x2C711,0x2B9E7,0x2C1D0}, {0x001C,0x001C,0x001D,0x001B}, NES_SCRIPT },
+	{ {0x2C72D,0x2C72D,0x2BA04,0x2C1EB}, {0x001A,0x001A,0x0016,0x001F}, NES_SCRIPT },
+	{ {0x2C747,0x2C747,0x2BA1A,0x2C20A}, {0x0021,0x0021,0x002D,0x0024}, NES_SCRIPT },
+	{ {0x2C768,0x2C768,0x2BA47,0x2C22E}, {0x0024,0x0024,0x0027,0x0019}, NES_SCRIPT },
+	{ {0x2C78C,0x2C78C,0x2BA6E,0x2C247}, {0x0017,0x0017,0x0016,0x0018}, NES_SCRIPT },
+	{ {0x2C7A3,0x2C7A3,0x2BA84,0x2C25F}, {0x0017,0x0017,0x0014,0x001D}, NES_SCRIPT },
+	{ {0x2C7BA,0x2C7BA,0x2BA98,0x2C27C}, {0x0014,0x0014,0x0015,0x0016}, NES_SCRIPT }, // 70
+	{ {0x2C7CE,0x2C7CE,0x2BAAD,0x2C292}, {0x0024,0x0024,0x0029,0x0027}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x2C7F2,0x2C7F2,0x2BAD6,0x2C2B9}, {0x0011,0x0011,0x0010,0x0011}, NES_SCRIPT },
+	{ {0x1793A,0x18C67,0x176D5,0x17890}, {0x009D,0x009D,0x00A2,0x00AA}, NES_SCRIPT },
+	{ {0x22750,0x2275A,0x22831,0x22846}, {0x0066,0x0066,0x0066,0x0066}, NES_SCRIPT },
+	{ {0x14ED7,0x14ED7,0x14EE0,0x14F5F}, {0x0075,0x0075,0x0077,0x0083}, NES_SCRIPT },
+	{ {0x1F30C,0x1F28D,0x1F30B,0x1F43C}, {0x0120,0x0120,0x011A,0x013A}, NES_SCRIPT },
+	{ {0x1FD55,0x1FCD6,0x1FD58,0x1FEB8}, {0x001D,0x001D,0x001D,0x001D}, NES_SCRIPT },
+	{ {0x1F42C,0x1F3AD,0x1F425,0x1F576}, {0x008F,0x008F,0x0095,0x0098}, NES_SCRIPT },
+	{ {0x1F4BB,0x1F43C,0x1F4BA,0x1F60E}, {0x0097,0x0097,0x009E,0x009B}, NES_SCRIPT }, // 80
+	{ {0x179D7,0x18D04,0x17777,0x1793A}, {0x006A,0x006A,0x006F,0x006E}, NES_SCRIPT },
+	{ {0x17A41,0x18D6E,0x177E6,0x179A8}, {0x0030,0x0030,0x002F,0x0033}, NES_SCRIPT },
+	{ {0x1F552,0x1F4D3,0x1F558,0x1F6A9}, {0x0092,0x0092,0x0098,0x00A5}, NES_SCRIPT },
+	{ {0x2C803,0x2C803,0x2BAE6,0x2C2CA}, {0x00CC,0x00CC,0x00C4,0x00BA}, NES_SCRIPT },
+	{ {0x2C8CF,0x2C8CF,0x2BBAA,0x2C384}, {0x00BA,0x00BA,0x00AE,0x00AC}, NES_SCRIPT },
+	{ {0x2C989,0x2C989,0x2BC58,0x2C430}, {0x0088,0x0088,0x0088,0x008F}, NES_SCRIPT },
+	{ {0x20A09,0x20A09,0x20A3C,0x20A2D}, {0x01B0,0x01B0,0x01BB,0x01BE}, NES_SCRIPT },
+	{ {0x20BB9,0x20BB9,0x20BF7,0x20BEB}, {0x0168,0x0168,0x0197,0x0158}, NES_SCRIPT },
+	{ {0x20D21,0x20D21,0x20D8E,0x20D43}, {0x006C,0x006C,0x006E,0x0079}, NES_SCRIPT },
+	{ {0x20D8D,0x20D8D,0x20DFC,0x20DBC}, {0x0037,0x0037,0x0028,0x002B}, NES_SCRIPT }, // 90
+	{ {0x20DC4,0x20DC4,0x20E24,0x20DE7}, {0x00E4,0x00E4,0x00EA,0x00E8}, NES_SCRIPT },
+	{ {0x20EA8,0x20EA8,0x20F0E,0x20ECF}, {0x0045,0x0045,0x0049,0x004A}, NES_SCRIPT },
+	{ {0x20EED,0x20EED,0x20F57,0x20F19}, {0x00E1,0x00E1,0x00E7,0x0110}, NES_SCRIPT },
+	{ {0x20FCE,0x20FCE,0x2103E,0x21029}, {0x00F6,0x00F6,0x010C,0x0136}, NES_SCRIPT },
+	{ {0x210C4,0x210C4,0x2114A,0x2115F}, {0x0141,0x0141,0x0151,0x0152}, NES_SCRIPT },
+	{ {0x21205,0x21205,0x2129B,0x212B1}, {0x0183,0x0183,0x01B0,0x01B3}, NES_SCRIPT },
+	{ {0x21388,0x21388,0x2144B,0x21464}, {0x0034,0x0034,0x0034,0x0032}, NES_SCRIPT },
+	{ {0x213BC,0x213BC,0x2147F,0x21496}, {0x00A9,0x00A9,0x00A9,0x00A9}, NES_SCRIPT },
+	{ {0x24367,0x24367,0x24379,0x2437F}, {0x011B,0x011B,0x010E,0x0133}, NES_SCRIPT },
+	{ {0x1BD4D,0x1BDC2,0x1BBD7,0x1BCBC}, {0x0070,0x0070,0x0072,0x0074}, NES_SCRIPT }, // 100
+	{ {0x1CC78,0x1CBF9,0x1CC6B,0x1CC07}, {0x0091,0x0091,0x0092,0x0090}, NES_SCRIPT },
+	{ {0x29372,0x29372,0x2898B,0x28E43}, {0x0054,0x0054,0x0054,0x0054}, NES_SCRIPT },
+	{ {0x19F74,0x1A0D0,0x19EB7,0x19F06}, {0x00CE,0x00CE,0x00D3,0x00DB}, NES_SCRIPT },
+	{ {0x1A042,0x1A19E,0x19F8A,0x19FE1}, {0x0077,0x0077,0x0077,0x0080}, NES_SCRIPT },
+	{ {0x14F4C,0x14F4C,0x14F57,0x14FE2}, {0x0057,0x0057,0x0057,0x0057}, NES_SCRIPT },
+	{ {0x27886,0x2790A,0x2703E,0x273F4}, {0x02DF,0x02DF,0x0307,0x031F}, NES_SCRIPT },
+	{ {0x1DA2A,0x1D9AB,0x1D9FB,0x1D9D4}, {0x0219,0x0219,0x024F,0x0238}, NES_SCRIPT },
+	{ {0x1DC43,0x1DBC4,0x1DC4A,0x1DC0C}, {0x00F9,0x00F9,0x00E4,0x00FE}, NES_SCRIPT },
+	{ {0x1DD3C,0x1DCBD,0x1DD2E,0x1DD0A}, {0x0056,0x0056,0x0059,0x005A}, NES_SCRIPT },
+	{ {0x1DD92,0x1DD13,0x1DD87,0x1DD64}, {0x01C2,0x01C2,0x01C2,0x01F5}, NES_SCRIPT }, // 110
+	{ {0x14FA3,0x14FA3,0x14FAE,0x15039}, {0x004D,0x004D,0x004D,0x004D}, NES_SCRIPT },
+	{ {0x27594,0x27618,0x26D52,0x270DD}, {0x00D9,0x00D9,0x00D5,0x0100}, NES_SCRIPT },
+	{ {0x21DC3,0x21DCD,0x21E92,0x21E9A}, {0x0013,0x0013,0x0013,0x0013}, NES_SCRIPT },
+	{ {0x2A63D,0x2A64F,0x29C6E,0x2A1C3}, {0x00F0,0x00F0,0x00F0,0x00F0}, NES_SCRIPT },
+	{ {0x24482,0x24482,0x24487,0x244B2}, {0x00E7,0x00E7,0x00E0,0x00E4}, NES_SCRIPT },
+	{ {0x21465,0x21465,0x21528,0x2153F}, {0x00F2,0x00F2,0x00F2,0x00EC}, NES_SCRIPT },
+	{ {0x24569,0x24569,0x24567,0x24596}, {0x002B,0x002B,0x0023,0x0033}, NES_SCRIPT },
+	{ {0x2C3CF,0x2C3CF,0x2B6B2,0x2BC04}, {0x010F,0x010F,0x010B,0x0108}, NES_SCRIPT },
+	{ {0x24594,0x24594,0x2458A,0x245C9}, {0x00AA,0x00AA,0x00A1,0x009F}, NES_SCRIPT },
+	{ {0x24CE8,0x250B2,0x250A0,0x250F1}, {0x0DAB,0x0DAB,0x018B,0x0193}, NES_SCRIPT }, // 120
+	{ {0x1B67F,0x1B6F4,0x1B4F7,0x1B5E5}, {0x000D,0x000D,0x000D,0x000D}, NES_SCRIPT },
+	{ {0x1B68C,0x1B701,0x1B504,0x1B5F2}, {0x000D,0x000D,0x000D,0x000D}, NES_SCRIPT },
+	{ {0x2373E,0x23748,0x23876,0x2397C}, {0x017C,0x017C,0x018E,0x0199}, NES_SCRIPT },
+	{ {0x282F5,0x282F5,0x27639,0x27A07}, {0x01E1,0x01E1,0x01F0,0x0233}, NES_SCRIPT },
+	{ {0x238BA,0x238C4,0x23A04,0x23B15}, {0x0153,0x0153,0x017B,0x0171}, NES_SCRIPT },
+	{ {0x23A0D,0x23A17,0x23B7F,0x23C86}, {0x019C,0x019C,0x01AC,0x01BC}, NES_SCRIPT },
+	{ {0x23BA9,0x23BB3,0x23D2B,0x23E42}, {0x0016,0x0016,0x0016,0x0016}, NES_SCRIPT },
+	{ {0x2C4DE,0x2C4DE,0x2B7BD,0x2BD0C}, {0x005C,0x005C,0x005B,0x005B}, NES_SCRIPT },
+	{ {0x23BBF,0x23BC9,0x23D41,0x23E58}, {0x0020,0x0020,0x0020,0x0020}, NES_SCRIPT },
+	{ {0x27D66,0x27DEA,0x2A643,0x27E3B}, {0x00A5,0x00A5,0x00A6,0x00B9}, NES_SCRIPT }, // 130
+	{ {0x2A72D,0x2A73F,0x29D5E,0x2A2B3}, {0x034D,0x034D,0x0399,0x03D3}, NES_SCRIPT },
+	{ {0x14FF0,0x14FF0,0x14FFB,0x15086}, {0x00E3,0x00E3,0x00D2,0x00E4}, NES_SCRIPT },
+	{ {0x2BABC,0x2BACE,0x2B1DE,0x2B70C}, {0x005F,0x005F,0x0063,0x0067}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x25A93,0x25E5D,0x2522B,0x25284}, {0x003C,0x003C,0x003C,0x003C}, NES_SCRIPT },
+	{ {0x1E8E9,0x1E86A,0x1E8DB,0x1E9C0}, {0x0011,0x0011,0x0011,0x0011}, NES_SCRIPT },
+	{ {0x1634A,0x1634A,0x13E33,0x13E40}, {0x0018,0x0018,0x0018,0x0018}, NES_SCRIPT },
+	{ {0x26DFD,0x26E81,0x26585,0x26621}, {0x001F,0x001F,0x001F,0x001F}, NES_SCRIPT },
+	{ {0x26E1C,0x26EA0,0x265A4,0x26640}, {0x0054,0x0054,0x0054,0x0054}, NES_SCRIPT },
+	{ {0x26E70,0x26EF4,0x265F8,0x26694}, {0x0149,0x0149,0x017D,0x0173}, NES_SCRIPT }, // 140
+	{ {0x26FB9,0x2703D,0x26775,0x26807}, {0x004B,0x004B,0x004B,0x004B}, NES_SCRIPT },
+	{ {0x27004,0x27088,0x267C0,0x26852}, {0x017D,0x017D,0x0165,0x0190}, NES_SCRIPT },
+	{ {0x27181,0x27205,0x26925,0x269E2}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT },
+	{ {0x271A8,0x2722C,0x2694C,0x26A09}, {0x0041,0x0041,0x0041,0x0041}, NES_SCRIPT },
+	{ {0x271E9,0x2726D,0x2698D,0x26A4A}, {0x01B1,0x01B1,0x01CB,0x024E}, NES_SCRIPT },
+	{ {0x16362,0x16362,0x13E4B,0x13E58}, {0x001F,0x001F,0x001F,0x001F}, NES_SCRIPT },
+	{ {0x2463E,0x2463E,0x2462B,0x24668}, {0x002A,0x002A,0x002A,0x002A}, NES_SCRIPT },
+	{ {0x150D3,0x150D3,0x150CD,0x1516A}, {0x019E,0x019E,0x0187,0x01C9}, NES_SCRIPT },
+	{ {0x19275,0x194A8,0x1927D,0x192D0}, {0x0031,0x0031,0x0031,0x0031}, NES_SCRIPT },
+	{ {0x17A71,0x18D9E,0x17815,0x179DB}, {0x007C,0x007C,0x0087,0x0088}, NES_SCRIPT }, // 150
+	{ {0x21557,0x21557,0x2161A,0x2162B}, {0x00DC,0x00DC,0x00D8,0x00D0}, NES_SCRIPT },
+	{ {0x1D457,0x1D3D8,0x1D412,0x1D3BF}, {0x0018,0x0018,0x0018,0x0018}, NES_SCRIPT },
+	{ {0x1D46F,0x1D3F0,0x1D42A,0x1D3D7}, {0x0053,0x0053,0x0058,0x0055}, NES_SCRIPT },
+	{ {0x18BE2,0x17DB0,0x18C04,0x18C36}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x15271,0x15271,0x15254,0x15333}, {0x011B,0x011B,0x0108,0x0113}, NES_SCRIPT },
+	{ {0x1538C,0x1538C,0x1535C,0x15446}, {0x000B,0x000B,0x000B,0x000B}, NES_SCRIPT },
+	{ {0x24668,0x24668,0x24655,0x24692}, {0x0138,0x0138,0x0139,0x014D}, NES_SCRIPT },
+	{ {0x247A0,0x247A0,0x2478E,0x247DF}, {0x0014,0x0014,0x0014,0x0014}, NES_SCRIPT },
+	{ {0x1DF54,0x1DED5,0x1DF49,0x1DF59}, {0x0018,0x0018,0x0018,0x0018}, NES_SCRIPT },
+	{ {0x247B4,0x247B4,0x247A2,0x247F3}, {0x0027,0x0027,0x0027,0x0027}, NES_SCRIPT }, // 160
+	{ {0x1A0B9,0x1A215,0x1A001,0x1A061}, {0x004D,0x004D,0x004C,0x0050}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x2BB1B,0x2BB2D,0x2B241,0x2B773}, {0x00A5,0x00A5,0x00A5,0x00A5}, NES_SCRIPT },
+	{ {0x2AA7A,0x2AA8C,0x2A0F7,0x2A686}, {0x00C1,0x00C1,0x00B5,0x00BA}, NES_SCRIPT },
+	{ {0x2AB3B,0x2AB4D,0x2A1AC,0x2A740}, {0x0140,0x0140,0x0140,0x0140}, NES_SCRIPT },
+	{ {0x19826,0x19982,0x19759,0x1979F}, {0x00BF,0x00BF,0x00CA,0x00CA}, NES_SCRIPT },
+	{ {0x198E5,0x19A41,0x19823,0x19869}, {0x014D,0x014D,0x014D,0x014D}, NES_SCRIPT },
+	{ {0x19A32,0x19B8E,0x19970,0x199B6}, {0x0012,0x0012,0x0012,0x0012}, NES_SCRIPT },
+	{ {0x2AC7B,0x2AC8D,0x2A2EC,0x2A880}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x2AC80,0x2AC92,0x2A2F1,0x2A885}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT }, // 170
+	{ {0x2AC85,0x2AC97,0x2A2F6,0x2A88A}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x2AC8A,0x2AC9C,0x2A2FB,0x2A88F}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x2AC8F,0x2ACA1,0x2A300,0x2A894}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x21633,0x21633,0x216F2,0x216FB}, {0x0033,0x0033,0x0033,0x0033}, NES_SCRIPT },
+	{ {0x2AC94,0x2ACA6,0x2A305,0x2A899}, {0x0005,0x0005,0x0005,0x0005}, NES_SCRIPT },
+	{ {0x00000,0x00000,0x00000,0x00000}, {0x0000,0x0000,0x0000,0x0000}, NES_SCRIPT },
+	{ {0x2AC99,0x2ACAB,0x2A30A,0x2A89E}, {0x009C,0x009C,0x009C,0x009C}, NES_SCRIPT },
+	{ {0x2AD35,0x2AD47,0x2A3A6,0x2A93A}, {0x009C,0x009C,0x009C,0x009C}, NES_SCRIPT }
+};
+
+static ScummNESFile::t_resource res_sounds[82] = {
+	{ {0x0FFE8,0x0BF54,0x0BF58,0x07F74}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x17FCA,0x0BF5E,0x0BF62,0x0BF6C}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x27E0B,0x27ECB,0x27E5F,0x1BEFA}, {0x0073,0x0073,0x0073,0x0073}, NES_SOUND },
+	{ {0x17FDB,0x0BF6F,0x17F5A,0x17F10}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x17FEC,0x0FF5D,0x17F6B,0x17F21}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x27E7E,0x316FC,0x27ED2,0x1FED5}, {0x0056,0x0056,0x0056,0x0056}, NES_SOUND },
+	{ {0x27ED4,0x13F4E,0x1BF55,0x17F32}, {0x001F,0x001F,0x001F,0x001F}, NES_SOUND },
+	{ {0x23FEE,0x0FF6E,0x23F66,0x17F51}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x0FFF2,0x13F6D,0x0BF73,0x0FF76}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x27EF3,0x1BF47,0x1BF74,0x17F62}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x27EFD,0x1BF51,0x27F28,0x1FF2B}, {0x0019,0x0019,0x0019,0x0019}, NES_SOUND },
+	{ {0x27F16,0x31752,0x2BF0A,0x23E78}, {0x004B,0x004B,0x004B,0x004B}, NES_SOUND },
+	{ {0x27F61,0x1BF6A,0x1FF71,0x17F6C}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x27F6B,0x27F3E,0x27F41,0x1BF6D}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x27F7A,0x27F4D,0x27F50,0x1FF44}, {0x001D,0x001D,0x001D,0x001D}, NES_SOUND },
+	{ {0x27F97,0x3179D,0x2FEAA,0x23EC3}, {0x0045,0x0045,0x0045,0x0045}, NES_SOUND },
+	{ {0x27FDC,0x27F6A,0x27F6D,0x1FF61}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x2FD42,0x2BF40,0x2BF55,0x23F08}, {0x001B,0x001B,0x001B,0x001B}, NES_SOUND },
+	{ {0x2FD5D,0x317E2,0x2FEEF,0x23F23}, {0x0033,0x0033,0x0033,0x0033}, NES_SOUND },
+	{ {0x27FEB,0x2BF5B,0x2FF22,0x23F56}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x2BFEF,0x2BF6C,0x2BF70,0x1FF70}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x2FD90,0x31815,0x30B84,0x27EF4}, {0x0075,0x0075,0x0075,0x0075}, NES_SOUND },
+	{ {0x2FE05,0x2FF6C,0x2FF33,0x23F67}, {0x0014,0x0014,0x0014,0x0014}, NES_SOUND },
+	{ {0x0FFE8,0x0BF54,0x0BF58,0x07F74}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x2FE19,0x3188A,0x30BF9,0x2FB83}, {0x00FF,0x00FF,0x00FF,0x00FF}, NES_SOUND },
+	{ {0x2FF18,0x31989,0x2FF47,0x27F69}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x2FF27,0x31998,0x2FF56,0x2BF70}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x2FF36,0x319A7,0x30CF8,0x2FC82}, {0x0092,0x0092,0x0092,0x0092}, NES_SOUND },
+	{ {0x2FF36,0x319A7,0x30CF8,0x2FC82}, {0x0092,0x0092,0x0092,0x0092}, NES_SOUND },
+	{ {0x2FFC8,0x31A39,0x30D8A,0x2FD14}, {0x002D,0x002D,0x002D,0x002D}, NES_SOUND },
+	{ {0x316FC,0x31A66,0x30DB7,0x2FD41}, {0x00F8,0x00F8,0x00F8,0x00F8}, NES_SOUND },
+	{ {0x317F4,0x31B5E,0x2FF65,0x2FE39}, {0x0016,0x0016,0x0016,0x0016}, NES_SOUND },
+	{ {0x3180A,0x31B74,0x30EAF,0x2FE4F}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x3181B,0x31B85,0x30EC0,0x2FE60}, {0x004B,0x004B,0x004B,0x004B}, NES_SOUND },
+	{ {0x31866,0x31BD0,0x30F0B,0x2FEAB}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x31877,0x31BE1,0x30F1C,0x2FEBC}, {0x003B,0x003B,0x003B,0x003B}, NES_SOUND },
+	{ {0x318B2,0x31C1C,0x30F57,0x316FC}, {0x008A,0x008A,0x008A,0x008A}, NES_SOUND },
+	{ {0x3193C,0x31CA6,0x30FE1,0x2FEF7}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x3194D,0x31CB7,0x30FF2,0x2FF08}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x3195C,0x31CC6,0x31001,0x31786}, {0x00A2,0x00A2,0x00A2,0x00A2}, NES_SOUND },
+	{ {0x319FE,0x31D68,0x310A3,0x31828}, {0x00D3,0x00D3,0x00D3,0x00D3}, NES_SOUND },
+	{ {0x31AD1,0x31E3B,0x31176,0x318FB}, {0x0097,0x0097,0x0097,0x0097}, NES_SOUND },
+	{ {0x2BFEF,0x2BF6C,0x2BF70,0x1FF70}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x3195C,0x31CC6,0x31001,0x31786}, {0x00A2,0x00A2,0x00A2,0x00A2}, NES_SOUND },
+	{ {0x31B68,0x31ED2,0x3120D,0x31992}, {0x05D1,0x05D1,0x05D1,0x05D1}, NES_SOUND },
+	{ {0x31B68,0x31ED2,0x3120D,0x31992}, {0x05D1,0x05D1,0x05D1,0x05D1}, NES_SOUND },
+	{ {0x32139,0x324A3,0x317DE,0x2FF17}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x0FFE8,0x0BF54,0x0BF58,0x07F74}, {0x000A,0x000A,0x000A,0x000A}, NES_SOUND },
+	{ {0x2FD90,0x31815,0x30B84,0x27EF4}, {0x0075,0x0075,0x0075,0x0075}, NES_SOUND },
+	{ {0x27ED4,0x13F4E,0x1BF55,0x17F32}, {0x001F,0x001F,0x001F,0x001F}, NES_SOUND },
+	{ {0x3214A,0x324B4,0x317EF,0x31F63}, {0x098E,0x098E,0x098E,0x098E}, NES_SOUND },
+	{ {0x3181B,0x31B85,0x30EC0,0x2FE60}, {0x004B,0x004B,0x004B,0x004B}, NES_SOUND },
+	{ {0x32AD8,0x32E42,0x3217D,0x2FF28}, {0x0011,0x0011,0x0011,0x0011}, NES_SOUND },
+	{ {0x30ECA,0x30ECA,0x30352,0x30ECA}, {0x0832,0x0832,0x0832,0x0832}, NES_SOUND },
+	{ {0x32AE9,0x32E53,0x3218E,0x2FF39}, {0x000F,0x000F,0x000F,0x000F}, NES_SOUND },
+	{ {0x32AF8,0x32E62,0x3219D,0x2FF48}, {0x002F,0x002F,0x002F,0x002F}, NES_SOUND },
+	{ {0x32B27,0x32E91,0x321CC,0x328F1}, {0x001D,0x001D,0x001D,0x001D}, NES_SOUND },
+	{ {0x32B44,0x32EAE,0x321E9,0x3290E}, {0x0018,0x0018,0x0018,0x0018}, NES_SOUND },
+	{ {0x32B5C,0x32EC6,0x32201,0x32926}, {0x0016,0x0016,0x0016,0x0016}, NES_SOUND },
+	{ {0x32B72,0x32EDC,0x32217,0x3293C}, {0x001B,0x001B,0x001B,0x001B}, NES_SOUND },
+	{ {0x32B8D,0x32EF7,0x32232,0x32957}, {0x0088,0x0088,0x0088,0x0088}, NES_SOUND },
+	{ {0x32C15,0x32F7F,0x322BA,0x329DF}, {0x0065,0x0065,0x0065,0x0065}, NES_SOUND },
+	{ {0x32C7A,0x32FE4,0x3231F,0x32A44}, {0x0065,0x0065,0x0065,0x0065}, NES_SOUND },
+	{ {0x32CDF,0x33049,0x32384,0x32AA9}, {0x0073,0x0073,0x0073,0x0073}, NES_SOUND },
+	{ {0x32D52,0x330BC,0x323F7,0x32B1C}, {0x00F9,0x00F9,0x00F9,0x00F9}, NES_SOUND },
+	{ {0x32E4B,0x331B5,0x324F0,0x32C15}, {0x049E,0x049E,0x049E,0x049E}, NES_SOUND },
+	{ {0x34001,0x34001,0x3298E,0x330B3}, {0x0EA8,0x0EA8,0x0EA8,0x0EA8}, NES_SOUND },
+	{ {0x332E9,0x34EA9,0x34001,0x34001}, {0x0B18,0x0B18,0x0B18,0x0B18}, NES_SOUND },
+	{ {0x34EA9,0x359C1,0x34B19,0x34B19}, {0x0B9C,0x0B9C,0x0B9C,0x0B9C}, NES_SOUND },
+	{ {0x35A45,0x3655D,0x356B5,0x356B5}, {0x0C6B,0x0C6B,0x0C6B,0x0C6B}, NES_SOUND },
+	{ {0x366B0,0x38001,0x36320,0x36320}, {0x0E56,0x0E56,0x0E56,0x0E56}, NES_SOUND },
+	{ {0x38001,0x371C8,0x37176,0x37176}, {0x0C70,0x0C70,0x0C70,0x0C70}, NES_SOUND },
+	{ {0x38C71,0x38E57,0x38001,0x38001}, {0x0DEC,0x0DEC,0x0DEC,0x0DEC}, NES_SOUND },
+	{ {0x39A5D,0x39C43,0x38DED,0x38DED}, {0x0B77,0x0B77,0x0B77,0x0B77}, NES_SOUND },
+	{ {0x37506,0x33653,0x33836,0x39964}, {0x042F,0x042F,0x042F,0x042F}, NES_SOUND },
+	{ {0x3A5D4,0x3A7BA,0x39964,0x39D93}, {0x0AC5,0x0AC5,0x0AC5,0x0AC5}, NES_SOUND },
+	{ {0x3B099,0x3B27F,0x3A429,0x3A858}, {0x0BE4,0x0BE4,0x0BE4,0x0BE4}, NES_SOUND }
+};
+
+static ScummNESFile::t_resource res_costumes[25] = {
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x13FAB,0x0FEA2,0x17E9A,0x13E77}, {0x004B,0x004B,0x004B,0x004B}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x17F5A,0x0FEED,0x0FF4A,0x07F3E}, {0x0036,0x0036,0x0036,0x0036}, NES_COSTUME },
+	{ {0x17F90,0x0FF23,0x17EE5,0x13EC2}, {0x003A,0x003A,0x003A,0x003A}, NES_COSTUME },
+	{ {0x17F90,0x0FF23,0x17EE5,0x13EC2}, {0x003A,0x003A,0x003A,0x003A}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x1BF87,0x13F13,0x17F1F,0x13EFC}, {0x003B,0x003B,0x003B,0x003B}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x23FA9,0x23F2F,0x1BE94,0x13F37}, {0x0045,0x0045,0x0045,0x0045}, NES_COSTUME },
+	{ {0x1FFBD,0x1FF3E,0x1BED9,0x17E94}, {0x0040,0x0040,0x0040,0x0040}, NES_COSTUME },
+	{ {0x1BFC2,0x27E8F,0x1BF19,0x17ED4}, {0x003C,0x003C,0x003C,0x003C}, NES_COSTUME },
+	{ {0x17F90,0x0FF23,0x17EE5,0x13EC2}, {0x003A,0x003A,0x003A,0x003A}, NES_COSTUME },
+	{ {0x17F90,0x0FF23,0x17EE5,0x13EC2}, {0x003A,0x003A,0x003A,0x003A}, NES_COSTUME },
+	{ {0x17F05,0x0BEFF,0x0FEF5,0x0BF17}, {0x0055,0x0055,0x0055,0x0055}, NES_COSTUME },
+	{ {0x13FAB,0x0FEA2,0x17E9A,0x13E77}, {0x004B,0x004B,0x004B,0x004B}, NES_COSTUME }
+};
+
+static ScummNESFile::t_resource res_globdata =
+	{ {0x2CA11,0x2CA11,0x2C001,0x2C628}, {0x0307,0x0307,0x0307,0x0307}, NES_GLOBDATA };
+
+// sprite palette data
+static ScummNESFile::t_resource res_sprpals[2] = {
+	{ {0x0BFC1,0x07F61,0x07F55,0x07ED8}, {0x0010,0x0010,0x0010,0x0010}, NES_SPRPALS },
+	{ {0x0BFD1,0x0BEB2,0x07F65,0x07EE8}, {0x0010,0x0010,0x0010,0x0010}, NES_SPRPALS }
+};
+
+// associates costume IDs with sprite sets (indexes into SPRLENS/SPROFFS)
+static ScummNESFile::t_resource res_sprdesc[2] = {
+	{ {0x0FFB7,0x0BEC2,0x0BF1B,0x07EF8}, {0x0031,0x0031,0x0031,0x0031}, NES_SPRDESC },
+	{ {0x0BFE1,0x07F71,0x07F75,0x07F29}, {0x0009,0x0009,0x0009,0x0009}, NES_SPRDESC }
+};
+
+// number of sprites in each set (indicates length within SPRDATA)
+static ScummNESFile::t_resource res_sprlens[2] = {
+	{ {0x0FEA2,0x1BE32,0x13E6A,0x0FE61}, {0x0115,0x0115,0x0115,0x0115}, NES_SPRLENS },
+	{ {0x07FF5,0x07F5B,0x07F4F,0x07ED2}, {0x0006,0x0006,0x0006,0x0006}, NES_SPRLENS }
+};
+
+// offset of each sprite set (indexes into SPRDATA)
+static ScummNESFile::t_resource res_sproffs[2] = {
+	{ {0x2BDC5,0x2FD42,0x2BCE0,0x2F959}, {0x022A,0x022A,0x022A,0x022A}, NES_SPROFFS },
+	{ {0x0BFEA,0x0BEF3,0x0BF4C,0x07F32}, {0x000C,0x000C,0x000C,0x000C}, NES_SPROFFS }
+};
+
+
+// sprite data sets (packed NES sprite data)
+static ScummNESFile::t_resource res_sprdata[2] = {
+	{ {0x2CE11,0x2CE11,0x2C401,0x2CA28}, {0x2BE0,0x2BE0,0x2BE0,0x2BE0}, NES_SPRDATA },
+	{ {0x07F6B,0x0BE28,0x0FE6B,0x07E48}, {0x008A,0x008A,0x008A,0x008A}, NES_SPRDATA }
+};
+
+uint16 write_byte(Common::MemoryWriteStream *out, byte val) {
+	val ^= 0xFF;
+	if (out != 0)
+		out->writeByte(val);
+	return 1;
+}
+
+uint16 write_word(Common::MemoryWriteStream *out, uint16 val) {
+	val ^= 0xFFFF;
+	if (out != 0)
+		out->writeUint16LE(val);
+	return 2;
+}
+
+byte ScummNESFile::FileReadByte() {
+	byte b = 0;
+	File::read(&b, 1);
+	return b;
+}
+
+uint16 ScummNESFile::FileReadUint16LE() {
+	uint16 a = FileReadByte();
+	uint16 b = FileReadByte();
+	return a | (b << 8);
+}
+uint32 ScummNESFile::resOffset(p_resource res) {
+	return res->offset[_ROMset];
+}
+uint16 ScummNESFile::resLength(p_resource res) {
+	return res->length[_ROMset];
+}
+
+uint16 ScummNESFile::extractResource(Common::MemoryWriteStream *output, p_resource res) {
+	uint16 len, i, j;
+	byte val;
+	byte cnt;
+	uint16 reslen = 0;
+
+	if (res == NULL)
+		error("extract_resource - no resource specified");
+
+	if ((resOffset(res) == 0) && (resLength(res) == 0))
+		return 0;	/* there are 8 scripts that are zero bytes long, so we should skip them */
+
+	File::seek(16 + resOffset(res),SEEK_SET);
+
+	switch (res->type) {
+	case NES_GLOBDATA:
+		len = resLength(res);
+
+		for (i = 0; i < len; i++)
+			reslen += write_byte(output, FileReadByte());
+
+		break;
+
+	case NES_ROOMGFX:
+	case NES_COSTUMEGFX:
+		reslen += write_word(output, (uint16)(resLength(res) + 2));
+		len = FileReadByte();
+		reslen += write_byte(output, (byte)len);
+
+		if (!len)
+			len = 256;
+		len = len << 4;
+
+		for (i = 0; i < len;) {
+			reslen += write_byte(output, cnt = FileReadByte());
+			for (j = 0; j < (cnt & 0x7F); j++, i++)
+				if ((cnt & 0x80) || (j == 0))
+					reslen += write_byte(output, FileReadByte());
+		}
+
+		if (File::pos() - resOffset(res) - 16 != resLength(res))
+			error("extract_resource - length mismatch while extracting graphics resource (was %04X, should be %04X)", File::pos() - resOffset(res) - 16, resLength(res));
+
+		break;
+
+	case NES_ROOM:
+	case NES_SCRIPT:
+		len = FileReadUint16LE();
+
+		if (len != resLength(res))
+			error("extract_resource - length mismatch while extracting room/script resource (was %04X, should be %04X)", len, resLength(res));
+
+		File::seek(-2, SEEK_CUR);
+
+		for (i = 0; i < len; i++)
+			reslen += write_byte(output, FileReadByte());
+
+		break;
+
+	case NES_SOUND:
+		len = resLength(res) + 2;
+		val = FileReadByte();
+		cnt = FileReadByte();
+
+		if ((val == 2) && (cnt == 100)) {
+			reslen += write_word(output, len);
+			reslen += write_byte(output, val);
+			reslen += write_byte(output, cnt);
+			while (1) {
+				reslen += write_byte(output, val = FileReadByte());
+				if (val >= 0xFE)
+					break;
+			}
+		} else if (((val == 0) || (val == 1) || (val == 4)) && (cnt == 10)) {
+			reslen += write_word(output, len);
+			reslen += write_byte(output, val);
+			reslen += write_byte(output, cnt);
+			while (1) {
+				reslen += write_byte(output, val = FileReadByte());
+
+				if (val >= 0xFE)
+					break;
+
+				if (val >= 0x10)
+					reslen += write_byte(output, FileReadByte());
+				else {
+					reslen += write_byte(output, FileReadByte());
+					reslen += write_byte(output, FileReadByte());
+					reslen += write_byte(output, FileReadByte());
+					reslen += write_byte(output, FileReadByte());
+				}
+			}
+		} else
+			error("extract_resource - unknown sound type %d/%d detected",val,cnt);
+
+		if (File::pos() - resOffset(res) - 16 != resLength(res))
+			error("extract_resource - length mismatch while extracting sound resource (was %04X, should be %04X)", File::pos() - resOffset(res) - 16, resLength(res));
+
+		break;
+
+	case NES_COSTUME:
+	case NES_SPRPALS:
+	case NES_SPRDESC:
+	case NES_SPRLENS:
+	case NES_SPROFFS:
+	case NES_SPRDATA:
+		len = resLength(res);
+		reslen += write_word(output, (uint16)(len + 2));
+
+		for (i = 0; i < len; i++)
+			reslen += write_byte(output, FileReadByte());
+
+		break;
+
+	default:
+		error("extract_resource - unknown resource type %d specified!", res->type);
+	}
+
+	return reslen;
+}
+
+// based on structure of Classic PC Maniac Mansion LFL files
+// (roomgfx resources are arranged in order, one per file, 
+// after the room blocks) */
+static ScummNESFile::p_resource lfl_01[] = { &res_rooms[1], &res_roomgfx[1], &res_scripts[57], &res_scripts[61], &res_scripts[76], &res_scripts[105], &res_scripts[111], &res_sounds[5], &res_scripts[132], &res_scripts[148], &res_scripts[155], &res_scripts[156], &res_sounds[39], NULL };
+static ScummNESFile::p_resource lfl_02[] = { &res_rooms[2], &res_roomgfx[2], NULL };
+static ScummNESFile::p_resource lfl_03[] = { &res_rooms[3], &res_roomgfx[3], &res_scripts[21], &res_sounds[26], NULL };
+static ScummNESFile::p_resource lfl_04[] = { &res_rooms[4], &res_roomgfx[4], &res_scripts[46], &res_scripts[56], &res_scripts[137], &res_scripts[146], &res_sounds[12], &res_sounds[11], &res_sounds[13], &res_sounds[42], NULL };
+static ScummNESFile::p_resource lfl_05[] = { &res_rooms[5], &res_roomgfx[5], &res_scripts[30], &res_scripts[31], &res_scripts[32], &res_scripts[33], &res_scripts[34], &res_scripts[35], &res_sounds[22], &res_sounds[23], &res_sounds[24], &res_sounds[21], &res_sounds[46], NULL };
+static ScummNESFile::p_resource lfl_06[] = { &res_rooms[6], &res_roomgfx[6], NULL };
+static ScummNESFile::p_resource lfl_07[] = { &res_rooms[7], &res_roomgfx[7], &res_scripts[17], &res_scripts[58], &res_scripts[59], &res_scripts[60], &res_scripts[74], &res_scripts[81], &res_scripts[82], &res_scripts[150], &res_sounds[14], &res_sounds[15], &res_sounds[16], &res_sounds[17], NULL };
+static ScummNESFile::p_resource lfl_08[] = { &res_rooms[8], &res_roomgfx[8], &res_scripts[7], &res_scripts[12], &res_scripts[13], &res_scripts[47], &res_scripts[48], &res_scripts[49], &res_scripts[154], &res_sounds[32], &res_sounds[33], &res_sounds[36], NULL };
+static ScummNESFile::p_resource lfl_09[] = { &res_rooms[9], &res_roomgfx[9], &res_scripts[10], &res_scripts[11], &res_scripts[45], &res_scripts[55], &res_scripts[84], &res_scripts[85], &res_scripts[86], NULL };
+static ScummNESFile::p_resource lfl_10[] = { &res_rooms[10], &res_roomgfx[10], &res_scripts[24], &res_scripts[149], &res_sounds[28], NULL };
+static ScummNESFile::p_resource lfl_11[] = { &res_rooms[11], &res_roomgfx[11], &res_scripts[166], &res_scripts[167], &res_scripts[168], NULL };
+static ScummNESFile::p_resource lfl_12[] = { &res_rooms[12], &res_roomgfx[12], &res_scripts[51], &res_scripts[103], &res_scripts[104], &res_scripts[161], &res_sounds[63], &res_costumes[14], NULL };
+static ScummNESFile::p_resource lfl_13[] = { &res_rooms[13], &res_roomgfx[13], NULL };
+static ScummNESFile::p_resource lfl_14[] = { &res_rooms[14], &res_roomgfx[14], NULL };
+static ScummNESFile::p_resource lfl_15[] = { &res_rooms[15], &res_roomgfx[15], &res_sounds[27], NULL };
+static ScummNESFile::p_resource lfl_16[] = { &res_rooms[16], &res_roomgfx[16], &res_scripts[14], &res_scripts[121], &res_scripts[122], &res_sounds[40], &res_sounds[64], &res_sounds[68], NULL };
+static ScummNESFile::p_resource lfl_17[] = { &res_rooms[17], &res_roomgfx[17], &res_scripts[20], &res_scripts[100], &res_sounds[25], &res_sounds[44], &res_sounds[2], &res_sounds[50], &res_sounds[52], NULL };
+static ScummNESFile::p_resource lfl_18[] = { &res_rooms[18], &res_roomgfx[18], &res_scripts[25], &res_scripts[26], &res_scripts[27], &res_scripts[28], &res_scripts[64], &res_scripts[65], &res_scripts[66], &res_scripts[67], &res_scripts[68], &res_scripts[69], &res_scripts[70], &res_scripts[71], &res_scripts[73], &res_scripts[101], &res_sounds[35], NULL };
+static ScummNESFile::p_resource lfl_19[] = { &res_rooms[19], &res_roomgfx[19], &res_scripts[36], &res_scripts[37], &res_scripts[38], &res_scripts[39], &res_scripts[40], &res_scripts[152], &res_scripts[153], &res_costumes[10], NULL };
+static ScummNESFile::p_resource lfl_20[] = { &res_rooms[20], &res_roomgfx[20], &res_scripts[107], &res_scripts[108], &res_scripts[109], &res_scripts[110], &res_scripts[159], NULL };
+static ScummNESFile::p_resource lfl_21[] = { &res_rooms[21], &res_roomgfx[21], &res_scripts[41], &res_scripts[42], &res_scripts[43], &res_scripts[53], &res_scripts[136], &res_sounds[29], &res_sounds[20], &res_sounds[37], NULL };
+static ScummNESFile::p_resource lfl_22[] = { &res_rooms[22], &res_roomgfx[22], &res_scripts[15], NULL };
+static ScummNESFile::p_resource lfl_23[] = { &res_rooms[23], &res_roomgfx[23], &res_scripts[77], &res_scripts[79], &res_scripts[80], &res_scripts[83], &res_sounds[41], NULL };
+static ScummNESFile::p_resource lfl_24[] = { &res_rooms[24], &res_roomgfx[24], &res_scripts[18], &res_scripts[19], &res_scripts[78], &res_sounds[7], &res_sounds[3], &res_sounds[18], &res_sounds[34], &res_costumes[12], NULL };
+static ScummNESFile::p_resource lfl_25[] = { &res_rooms[25], &res_roomgfx[25], &res_scripts[29], &res_sounds[30], &res_sounds[31], NULL };
+static ScummNESFile::p_resource lfl_26[] = { &res_rooms[26], &res_roomgfx[26], &res_scripts[87], &res_scripts[88], &res_scripts[89], &res_scripts[90], &res_scripts[91], &res_scripts[92], &res_scripts[93], &res_scripts[94], &res_scripts[95], &res_scripts[96], &res_scripts[97], &res_scripts[98], &res_scripts[116], &res_scripts[151], &res_scripts[174], &res_costumes[11], NULL };
+static ScummNESFile::p_resource lfl_27[] = { &res_rooms[27], &res_roomgfx[27], &res_scripts[16], &res_scripts[52], &res_scripts[54], &res_scripts[113], &res_sounds[45], &res_costumes[19], NULL };
+static ScummNESFile::p_resource lfl_28[] = { &res_rooms[28], &res_roomgfx[28], &res_scripts[22], &res_scripts[23], NULL };
+static ScummNESFile::p_resource lfl_29[] = { &res_rooms[29], &res_roomgfx[29], &res_scripts[75], &res_sounds[43], NULL };
+static ScummNESFile::p_resource lfl_30[] = { &res_rooms[30], &res_roomgfx[30], &res_scripts[63], &res_sounds[0], &res_scripts[123], &res_scripts[125], &res_scripts[126], &res_scripts[127], &res_scripts[129], &res_sounds[55], &res_sounds[59], &res_sounds[60], &res_costumes[8], NULL };
+static ScummNESFile::p_resource lfl_31[] = { &res_rooms[31], &res_roomgfx[31], &res_scripts[99], &res_scripts[115], &res_scripts[117], &res_scripts[119], &res_scripts[147], &res_scripts[157], &res_scripts[158], &res_scripts[160], &res_costumes[13], &res_costumes[9], &res_costumes[23], &res_costumes[24], NULL };
+static ScummNESFile::p_resource lfl_32[] = { &res_rooms[32], &res_roomgfx[32], &res_costumes[15], NULL };
+static ScummNESFile::p_resource lfl_33[] = { &res_rooms[33], &res_roomgfx[33], &res_scripts[120], &res_scripts[135], &res_sounds[56], &res_sounds[57], &res_sounds[58], &res_sounds[1], &res_costumes[22], NULL };
+static ScummNESFile::p_resource lfl_34[] = { &res_rooms[34], &res_roomgfx[34], NULL };
+static ScummNESFile::p_resource lfl_35[] = { &res_rooms[35], &res_roomgfx[35], NULL };
+static ScummNESFile::p_resource lfl_36[] = { &res_rooms[36], &res_roomgfx[36], &res_sounds[10], &res_sounds[4], NULL };
+static ScummNESFile::p_resource lfl_37[] = { &res_rooms[37], &res_roomgfx[37], NULL };
+static ScummNESFile::p_resource lfl_38[] = { &res_rooms[38], &res_roomgfx[38], &res_scripts[138], &res_scripts[139], &res_scripts[140], &res_scripts[141], &res_scripts[142], &res_scripts[143], &res_scripts[144], &res_scripts[145], NULL };
+static ScummNESFile::p_resource lfl_39[] = { &res_rooms[39], &res_roomgfx[39], NULL };
+static ScummNESFile::p_resource lfl_40[] = { &res_rooms[40], &res_roomgfx[0], &res_scripts[112], &res_costumes[17], NULL };
+static ScummNESFile::p_resource lfl_41[] = { &res_rooms[41], &res_scripts[106], &res_sounds[47], &res_sounds[48], &res_sounds[53], &res_sounds[49], &res_sounds[51], NULL };
+static ScummNESFile::p_resource lfl_42[] = { &res_rooms[42], &res_scripts[124], &res_costumes[18],  NULL };
+static ScummNESFile::p_resource lfl_43[] = { &res_rooms[43], &res_scripts[44], &res_sounds[19], NULL };
+static ScummNESFile::p_resource lfl_44[] = { &res_rooms[44], &res_scripts[102], &res_sounds[6], &res_sounds[38], &res_sounds[8], &res_sounds[9], &res_costumes[1], &res_costumes[2], &res_costumes[5], &res_costumes[6], &res_costumes[3], &res_costumes[4], &res_costumes[7], NULL };
+static ScummNESFile::p_resource lfl_45[] = { &res_rooms[45], &res_scripts[1], &res_scripts[2], &res_scripts[3], &res_scripts[4], &res_scripts[5], &res_scripts[9], &res_scripts[114], &res_scripts[131], &res_scripts[164], &res_scripts[165], &res_scripts[169], &res_scripts[170], &res_scripts[171], &res_scripts[172], &res_scripts[173], &res_scripts[175], &res_sounds[54], NULL };
+static ScummNESFile::p_resource lfl_46[] = { &res_rooms[46], &res_scripts[130], &res_sounds[65], &res_costumes[0], &res_costumes[21], NULL };
+static ScummNESFile::p_resource lfl_47[] = { &res_rooms[47], &res_scripts[62], &res_sounds[69], NULL };
+static ScummNESFile::p_resource lfl_48[] = { &res_rooms[48], NULL };
+static ScummNESFile::p_resource lfl_49[] = { &res_rooms[49], NULL };
+static ScummNESFile::p_resource lfl_50[] = { &res_rooms[50], &res_scripts[133], &res_scripts[163], NULL };
+static ScummNESFile::p_resource lfl_51[] = { &res_rooms[51], &res_scripts[118], &res_scripts[128], &res_sounds[61], &res_sounds[62], &res_sounds[67], &res_sounds[66], &res_costumes[16], &res_costumes[20], NULL };
+static ScummNESFile::p_resource lfl_52[] = { &res_rooms[52], NULL };
+/*	remaining 'standard' resources (not used by any of the original LFL files) */
+static ScummNESFile::p_resource lfl_53[] = { &res_rooms[53], &res_scripts[177], &res_scripts[178], &res_sounds[70], &res_sounds[71], &res_sounds[72], &res_sounds[73], &res_sounds[74], &res_sounds[75], &res_sounds[76], &res_sounds[77], &res_sounds[78], &res_sounds[79], &res_sounds[80], &res_sounds[81], NULL };
+/*	all 'non-standard' resources (the costume-related stuff) */
+static ScummNESFile::p_resource lfl_54[] = { &res_rooms[54], &res_sprdesc[0], &res_sprdesc[1], &res_sprlens[0], &res_sprlens[1], &res_sproffs[0], &res_sproffs[1], &res_sprdata[0], &res_sprdata[1], &res_costumegfx[0], &res_costumegfx[1], &res_sprpals[0], &res_sprpals[1], NULL };
+
+typedef	struct _lfl {
+	int num;
+	ScummNESFile::p_resource *entries;
+} t_lfl, *p_lfl;
+
+t_lfl lfls[] = {
+	{  1, lfl_01 },
+	{  2, lfl_02 },
+	{  3, lfl_03 },
+	{  4, lfl_04 },
+	{  5, lfl_05 },
+	{  6, lfl_06 },
+	{  7, lfl_07 },
+	{  8, lfl_08 },
+	{  9, lfl_09 },
+	{ 10, lfl_10 },
+	{ 11, lfl_11 },
+	{ 12, lfl_12 },
+	{ 13, lfl_13 },
+	{ 14, lfl_14 },
+	{ 15, lfl_15 },
+	{ 16, lfl_16 },
+	{ 17, lfl_17 },
+	{ 18, lfl_18 },
+	{ 19, lfl_19 },
+	{ 20, lfl_20 },
+	{ 21, lfl_21 },
+	{ 22, lfl_22 },
+	{ 23, lfl_23 },
+	{ 24, lfl_24 },
+	{ 25, lfl_25 },
+	{ 26, lfl_26 },
+	{ 27, lfl_27 },
+	{ 28, lfl_28 },
+	{ 29, lfl_29 },
+	{ 30, lfl_30 },
+	{ 31, lfl_31 },
+	{ 32, lfl_32 },
+	{ 33, lfl_33 },
+	{ 34, lfl_34 },
+	{ 35, lfl_35 },
+	{ 36, lfl_36 },
+	{ 37, lfl_37 },
+	{ 38, lfl_38 },
+	{ 39, lfl_39 },
+	{ 40, lfl_40 },
+	{ 41, lfl_41 },
+	{ 42, lfl_42 },
+	{ 43, lfl_43 },
+	{ 44, lfl_44 },
+	{ 45, lfl_45 },
+	{ 46, lfl_46 },
+	{ 47, lfl_47 },
+	{ 48, lfl_48 },
+	{ 49, lfl_49 },
+	{ 50, lfl_50 },
+	{ 51, lfl_51 },
+	{ 52, lfl_52 },
+	{ 53, lfl_53 },
+	{ 54, lfl_54 },
+	{ -1, NULL }
+};
+
+#pragma START_PACK_STRUCTS
+struct _lfl_index {
+	byte	room_lfl[55];
+	uint16	room_addr[55];
+	byte	costume_lfl[77];
+	uint16	costume_addr[77];
+	byte	script_lfl[200];
+	uint16	script_addr[200];
+	byte	sound_lfl[100];
+	uint16	sound_addr[100];
+} GCC_PACK lfl_index;
+#pragma END_PACK_STRUCTS
+
+
+bool ScummNESFile::generateResource(int res) {
+	p_lfl lfl = &lfls[res - 1];
+	int j;
+	int bufsize = 2;
+
+	for (j = 0; lfl->entries[j] != NULL; j++)
+		bufsize += extractResource(0, lfl->entries[j]);
+
+	free(_buf);
+	_buf = (byte *)calloc(1, bufsize);
+
+	Common::MemoryWriteStream out(_buf, bufsize);
+
+	for (j = 0; lfl->entries[j] != NULL; j++) {
+		p_resource entry = lfl->entries[j];
+		extractResource(&out, entry);
+	}
+	write_byte(&out, 0xD1);
+	write_byte(&out, 0xF5);
+
+	if (_stream)
+		delete _stream;
+
+	_stream = new Common::MemoryReadStream(_buf, bufsize);
+
+	return true;
+}
+
+bool ScummNESFile::generateIndex() {
+	int i, j;
+
+	for (i = 0; lfls[i].num != -1; i++) {
+		p_lfl lfl = &lfls[i];
+		uint16 respos = 0;
+
+		for (j = 0; lfl->entries[j] != NULL; j++) {
+			p_resource entry = lfl->entries[j];
+			
+			switch (entry->type) {
+			case NES_ROOM:
+				lfl_index.room_lfl[entry - res_rooms] = lfl->num;
+				lfl_index.room_addr[entry - res_rooms] = TO_LE_16(respos);
+				break;
+			case NES_COSTUME:
+				lfl_index.costume_lfl[entry - res_costumes] = lfl->num;
+				lfl_index.costume_addr[entry - res_costumes] = TO_LE_16(respos);
+				break;
+			case NES_SPRDESC:
+				lfl_index.costume_lfl[entry - res_sprdesc + 25] = lfl->num;
+				lfl_index.costume_addr[entry - res_sprdesc + 25] = TO_LE_16(respos);
+				break;
+			case NES_SPRLENS:
+				lfl_index.costume_lfl[entry - res_sprlens + 27] = lfl->num;
+				lfl_index.costume_addr[entry - res_sprlens + 27] = TO_LE_16(respos);
+				break;
+			case NES_SPROFFS:
+				lfl_index.costume_lfl[entry - res_sproffs + 29] = lfl->num;
+				lfl_index.costume_addr[entry - res_sproffs + 29] = TO_LE_16(respos);
+				break;
+			case NES_SPRDATA:
+				lfl_index.costume_lfl[entry - res_sprdata + 31] = lfl->num;
+				lfl_index.costume_addr[entry - res_sprdata + 31] = TO_LE_16(respos);
+				break;
+			case NES_COSTUMEGFX:
+				lfl_index.costume_lfl[entry - res_costumegfx + 33] = lfl->num;
+				lfl_index.costume_addr[entry - res_costumegfx + 33] = TO_LE_16(respos);
+				break;
+			case NES_SPRPALS:
+				lfl_index.costume_lfl[entry - res_sprpals + 35] = lfl->num;
+				lfl_index.costume_addr[entry - res_sprpals + 35] = TO_LE_16(respos);
+				break;
+			case NES_ROOMGFX:
+				lfl_index.costume_lfl[entry - res_roomgfx + 37] = lfl->num;
+				lfl_index.costume_addr[entry - res_roomgfx + 37] = TO_LE_16(respos);
+				break;
+			case NES_SCRIPT:
+				lfl_index.script_lfl[entry - res_scripts] = lfl->num;
+				lfl_index.script_addr[entry - res_scripts] = TO_LE_16(respos);
+				break;
+			case NES_SOUND:
+				lfl_index.sound_lfl[entry - res_sounds] = lfl->num;
+				lfl_index.sound_addr[entry - res_sounds] = TO_LE_16(respos);
+				break;
+			default:
+				error("Unindexed entry found!");
+				break;
+			}
+			respos += extractResource(0, entry);
+		}
+	}
+
+	int bufsize = 2;
+
+	bufsize += 775;
+	bufsize += sizeof(lfl_index);
+
+	free(_buf);
+	_buf = (byte *)calloc(1, bufsize);
+
+	Common::MemoryWriteStream out(_buf, bufsize);
+
+	write_byte(&out, 0x43);
+	write_byte(&out, 0x46);
+
+	extractResource(&out, &res_globdata);
+
+	for (i = res_globdata.length[_ROMset]; i < 775; i++)
+		write_byte(&out, 0);
+
+	for (i = 0; i < (int)sizeof(lfl_index); i++)
+		write_byte(&out, ((byte *)&lfl_index)[i]);
+
+	if (_stream)
+		delete _stream;
+
+	_stream = new Common::MemoryReadStream(_buf, bufsize);
+
+	return true;
+}
+
+bool ScummNESFile::open(const char *filename, AccessMode mode) {
+	uint8 md5sum[16];
+
+	if (_ROMset == kROMsetNum) {
+		// calculate md5 of first 900 bytes which is enough to tell the difference
+		if (md5_file(filename, md5sum, 0, 900)) {
+			char md5str[32+1];
+			for (int j = 0; j < 16; j++) {
+				sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
+			}
+
+			if (!strcmp(md5str, "27b1163056a66b16f862345ecb433890")) {
+				_ROMset = kROMsetUSA;
+				debug(1, "ROM contents verified as Maniac Mansion (USA)");
+			} else if (!strcmp(md5str, "3a831207809d1dc8e6ca323102827ec1")) {
+				_ROMset = kROMsetEurope;
+				debug(1, "ROM contents verified as Maniac Mansion (Europe)");
+			} else if (!strcmp(md5str, "96129094b3e09b7e3292b132bf345b17")) {
+				_ROMset = kROMsetSweden;
+				debug(1, "ROM contents verified as Maniac Mansion (Sweden)");
+			} else if (!strcmp(md5str, "95274b9e82c15b1be98ba6e99122196d")) {
+				_ROMset = kROMsetFrance;
+				debug(2, "ROM contents verified as Maniac Mansion (France)");
+			} else {
+				error("Unsupported Maniac Mansion ROM, md5: %s", md5str);
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	if (File::open(filename, mode)) {
+		if (_stream)
+			delete _stream;
+		_stream = 0;
+
+		free(_buf);
+		_buf = 0;
+
+		return true;
+	} else {
+		return false;
+	}
+}
+
+void ScummNESFile::close() {
+	if (_stream)
+		delete _stream;
+	_stream = 0;
+
+	free(_buf);
+	_buf = 0;
+
+	File::close();
+}
+
+bool ScummNESFile::openSubFile(const char *filename) {
+	assert(isOpen());
+
+	const char *ext = strrchr(filename, '.');
+	char resNum[3];
+	int res;
+	
+	// We always have file name in form of XX.lfl
+	resNum[0] = ext[-2];
+	resNum[1] = ext[-1];
+	resNum[2] = 0;
+
+	res = atoi(resNum);
+
+	if (res == 0) {
+		return generateIndex();
+	} else {
+		return generateResource(res);
+	}
+}
+
 } // End of namespace Scumm

Index: util.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/util.h,v
retrieving revision 2.3
retrieving revision 2.4
diff -u -d -r2.3 -r2.4
--- util.h	10 Jan 2005 22:51:41 -0000	2.3
+++ util.h	30 Mar 2005 21:59:12 -0000	2.4
@@ -23,10 +23,26 @@
 #define SCUMM_UTIL_H
 
 #include "common/file.h"
+#include "common/stream.h"
 
 namespace Scumm {
 
-class ScummFile : public File {
+class BaseScummFile : public File {
+public:
+	virtual void setEnc(byte value) = 0;
+	
+	virtual bool open(const char *filename, AccessMode mode = kFileReadMode) = 0;
+	virtual bool openSubFile(const char *filename) = 0;
+
+	virtual bool eof() = 0;
+	virtual uint32 pos() = 0;
+	virtual uint32 size() = 0;
+	virtual void seek(int32 offs, int whence = SEEK_SET) = 0;
+	virtual uint32 read(void *ptr, uint32 size) = 0;
+	virtual uint32 write(const void *ptr, uint32 size) = 0;
+};
+
+class ScummFile : public BaseScummFile {
 private:
 	byte _encbyte;
 	uint32	_subFileStart;
@@ -50,6 +66,71 @@
 };
 
 
+typedef enum _res_type {
+	NES_UNKNOWN,
+	NES_GLOBDATA,
+	NES_ROOM,
+	NES_SCRIPT, 
+	NES_SOUND,
+	NES_COSTUME,
+	NES_ROOMGFX,
+	NES_COSTUMEGFX,
+	NES_SPRPALS,
+	NES_SPRDESC,
+	NES_SPRLENS,
+	NES_SPROFFS,
+	NES_SPRDATA 
+} res_type;
+
+class ScummNESFile : public BaseScummFile {
+	typedef	enum _romset {
+		kROMsetUSA,
+		kROMsetEurope,
+		kROMsetSweden,
+		kROMsetFrance,
+		kROMsetNum 
+	} t_romset;
+
+public:
+
+	typedef	struct	_resource {
+		uint32 offset[kROMsetNum];
+		uint16 length[kROMsetNum];
+		res_type type;
+	}	t_resource, *p_resource;
+
+private:
+	Common::MemoryReadStream *_stream;
+	t_romset _ROMset;
+	byte *_buf;
+
+	bool generateIndex();
+	bool generateResource(int res);
+	uint16 extractResource(Common::MemoryWriteStream *out, p_resource res);
+
+	uint32 resOffset(p_resource res);
+	uint16 resLength(p_resource res);
+
+	byte FileReadByte();
+	uint16 FileReadUint16LE();
+
+public:
+	ScummNESFile();
+	void setEnc(byte value);
+	
+	bool open(const char *filename, AccessMode mode = kFileReadMode);
+	bool openSubFile(const char *filename);
+
+	void close();
+	bool eof() { return _stream->eof(); }
+	uint32 pos() { return _stream->pos(); }
+	uint32 size() { return _stream->size(); }
+	void seek(int32 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
+	uint32 read(void *ptr, uint32 len) { return _stream->read(ptr, len); }
+	uint32 write(const void *ptr, uint32 size);
+};
+
+
 // This is a constant lookup table of reverse bit masks
 extern const byte revBitMask[8];
 





More information about the Scummvm-git-logs mailing list