Ejemplo n.º 1
0
int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) {
#ifndef ENABLE_SCI32
	// SCI32 support is not built in. Check if this is a SCI32 game
	// and if it is abort here.
	if (_volVersion >= kResVersionSci2)
		return SCI_ERROR_RESMAP_NOT_FOUND;
#endif

	uint32 offset = 0;
	Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_mapNumber), false);

	if (!mapRes) {
		warning("Failed to open %i.MAP", map->_mapNumber);
		return SCI_ERROR_RESMAP_NOT_FOUND;
	}

	ResourceSource *src = findVolume(map, map->_volumeNumber);

	if (!src) {
		warning("Failed to find volume for %i.MAP", map->_mapNumber);
		return SCI_ERROR_NO_RESOURCE_FILES_FOUND;
	}

	byte *ptr = mapRes->data;

	// Heuristic to detect entry size
	uint32 entrySize = 0;
	for (int i = mapRes->size - 1; i >= 0; --i) {
		if (ptr[i] == 0xff)
			entrySize++;
		else
			break;
	}

	if (map->_mapNumber == 65535) {
		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_LE_UINT16(ptr);
			ptr += 2;

			if (n == 0xffff)
				break;

			if (entrySize == 6) {
				offset = READ_LE_UINT32(ptr);
				ptr += 4;
			} else {
				offset += READ_LE_UINT24(ptr);
				ptr += 3;
			}

			addResource(ResourceId(kResourceTypeAudio, n), src, offset);
		}
	} else if (map->_mapNumber == 0 && entrySize == 10 && ptr[3] == 0) {
		// QFG3 demo format
		// ptr[3] would be 'seq' in the normal format and cannot possibly be 0
		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_BE_UINT16(ptr);
			ptr += 2;

			if (n == 0xffff)
				break;

			offset = READ_LE_UINT32(ptr);
			ptr += 4;
			uint32 size = READ_LE_UINT32(ptr);
			ptr += 4;

			addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
		}
	} else if (map->_mapNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) {
		// LB2 Floppy/Mother Goose SCI1.1 format
		Common::SeekableReadStream *stream = getVolumeFile(src);

		while (ptr < mapRes->data + mapRes->size) {
			uint16 n = READ_LE_UINT16(ptr);
			ptr += 4;

			if (n == 0xffff)
				break;

			offset = READ_LE_UINT32(ptr);
			ptr += 4;

			// The size is not stored in the map and the entries have no order.
			// We need to dig into the audio resource in the volume to get the size.
			stream->seek(offset + 1);
			byte headerSize = stream->readByte();
			assert(headerSize == 11 || headerSize == 12);

			stream->skip(5);
			uint32 size = stream->readUint32LE() + headerSize + 2;

			addResource(ResourceId(kResourceTypeAudio, n), src, offset, size);
		}
	} else {
		bool isEarly = (entrySize != 11);

		if (!isEarly) {
			offset = READ_LE_UINT32(ptr);
			ptr += 4;
		}

		while (ptr < mapRes->data + mapRes->size) {
			uint32 n = READ_BE_UINT32(ptr);
			int syncSize = 0;
			ptr += 4;

			if (n == 0xffffffff)
				break;

			if (isEarly) {
				offset = READ_LE_UINT32(ptr);
				ptr += 4;
			} else {
				offset += READ_LE_UINT24(ptr);
				ptr += 3;
			}

			if (isEarly || (n & 0x80)) {
				syncSize = READ_LE_UINT16(ptr);
				ptr += 2;

				// FIXME: The sync36 resource seems to be two bytes too big in KQ6CD
				// (bytes taken from the RAVE resource right after it)
				if (syncSize > 0)
					addResource(ResourceId(kResourceTypeSync36, map->_mapNumber, n & 0xffffff3f), src, offset, syncSize);
			}

			if (n & 0x40) {
				// This seems to define the size of raw lipsync data (at least
				// in KQ6 CD Windows).
				int kq6HiresSyncSize = READ_LE_UINT16(ptr);
				ptr += 2;

				if (kq6HiresSyncSize > 0) {
					addResource(ResourceId(kResourceTypeRave, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
					syncSize += kq6HiresSyncSize;
				}
			}

			addResource(ResourceId(kResourceTypeAudio36, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize);
		}
	}

	return 0;
}
Ejemplo n.º 2
0
uint32 AGOSEngine_PN::getlong(uint32 pos) {
	// Only actually reads 24bit though
	if (pos > _dataBaseSize)
		error("getlong: Read beyond EOF (%d)", pos);
	return (uint32)READ_LE_UINT24(_dataBase + pos);
}