Пример #1
0
Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile,
		bool suppressErrors) {
	// Open up the library for access
	Common::SeekableReadStream *libStream = load(libraryFile);

	// Check if the library has already had its index read, and if not, load it
	if (!_indexes.contains(libraryFile))
		loadLibraryIndex(libraryFile, libStream, false);
	LibraryIndex &libIndex = _indexes[libraryFile];

	// Handle if resource is not present
	if (!libIndex.contains(filename)) {
		if (!suppressErrors)
			error("Could not find resource - %s", filename.c_str());

		delete libStream;
		return nullptr;
	}

	// Extract the data for the specified resource and return it
	LibraryEntry &entry = libIndex[filename];
	libStream->seek(entry._offset);
	Common::SeekableReadStream *stream = libStream->readStream(entry._size);
	decompressIfNecessary(stream);

	delete libStream;
	return stream;
}
Пример #2
0
Common::SeekableReadStream *HERFFile::getResource(uint32 index) const {
	const IResource &res = getIResource(index);
	if (res.size == 0)
		return new Common::MemoryReadStream(0, 0);

	Common::SeekableReadStream *herf = ResMan.getResource(TypeMan.setFileType(_fileName, kFileTypeNone), kFileTypeHERF);
	if (!herf)
		throw Common::Exception(Common::kOpenError);

	if (!herf->seek(res.offset)) {
		delete herf;
		throw Common::Exception(Common::kSeekError);
	}

	Common::SeekableReadStream *resStream = herf->readStream(res.size);

	if (!resStream || (((uint32) resStream->size()) != res.size)) {
		delete herf;
		delete resStream;
		throw Common::Exception(Common::kReadError);
	}

	delete herf;
	return resStream;
}
Пример #3
0
void ASFStream::parseStreamHeader() {
	ASFGUID guid = ASFGUID(*_stream);

	if (guid != s_asfAudioStream)
		throw Common::Exception("ASFStream::parseStreamHeader(): Found non-audio stream");

	_stream->skip(16); // skip a guid
	_stream->readUint64LE(); // total size
	uint32 typeSpecificSize = _stream->readUint32LE();
	_stream->readUint32LE();
	_streamID = _stream->readUint16LE();
	_stream->readUint32LE();

	// Parse the wave header
	_compression = _stream->readUint16LE();
	_channels = _stream->readUint16LE();
	_sampleRate = _stream->readUint32LE();
	_bitRate = _stream->readUint32LE() * 8;
	_blockAlign = _stream->readUint16LE();
	_bitsPerCodedSample = (typeSpecificSize == 14) ? 8 : _stream->readUint16LE();

	if (typeSpecificSize >= 18) {
		uint32 cbSize = _stream->readUint16LE();
		cbSize = MIN<int>(cbSize, typeSpecificSize - 18);
		_extraData = _stream->readStream(cbSize);
	}

	_codec = createCodec();
}
Пример #4
0
Common::SeekableReadStream *Resources::load(const Common::String &filename) {
	// First check if the file is directly in the cache
	if (_cache.isCached(filename))
		return _cache.get(filename);

	// Secondly, iterate through any loaded library file looking for a resource
	// that has the same name
	for (LibraryIndexes::iterator i = _indexes.begin(); i != _indexes.end(); ++i) {
		if (i->_value.contains(filename)) {
			// Get a stream reference to the given library file
			Common::SeekableReadStream *stream = load(i->_key);
			LibraryEntry &entry = i->_value[filename];
			_resourceIndex = entry._index;

			stream->seek(entry._offset);
			Common::SeekableReadStream *resStream = stream->readStream(entry._size);
			decompressIfNecessary(resStream);

			delete stream;
			return resStream;
		}
	}

	// At this point, fall back on a physical file with the given name
	Common::File f;
	if (!f.open(filename))
		error("Could not load file - %s", filename.c_str());

	Common::SeekableReadStream *stream = f.readStream(f.size());
	f.close();
	decompressIfNecessary(stream);

	return stream;
}
Пример #5
0
Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePacket(uint32 &descId) {
	// First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
	int32 totalSampleCount = 0;
	int32 sampleInChunk = 0;
	int32 actualChunk = -1;
	uint32 sampleToChunkIndex = 0;

	for (uint32 i = 0; i < _parent->chunkCount; i++) {
		if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first)
			sampleToChunkIndex++;

		totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count;

		if (totalSampleCount > _curFrame) {
			actualChunk = i;
			descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id;
			sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame;
			break;
		}
	}

	if (actualChunk < 0) {
		warning("Could not find data for frame %d", _curFrame);
		return 0;
	}

	// Next seek to that frame
	Common::SeekableReadStream *stream = _decoder->_fd;
	stream->seek(_parent->chunkOffsets[actualChunk]);

	// Then, if the chunk holds more than one frame, seek to where the frame we want is located
	for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) {
		if (_parent->sampleSize != 0)
			stream->skip(_parent->sampleSize);
		else
			stream->skip(_parent->sampleSizes[i]);
	}

	// Finally, read in the raw data for the frame
	//debug("Frame Data[%d]: Offset = %d, Size = %d", _curFrame, stream->pos(), _parent->sampleSizes[_curFrame]);

	if (_parent->sampleSize != 0)
		return stream->readStream(_parent->sampleSize);

	return stream->readStream(_parent->sampleSizes[_curFrame]);
}
Пример #6
0
void TPC::readTXI(Common::SeekableReadStream &tpc) {
	const size_t txiDataSize = tpc.size() - tpc.pos();
	if (txiDataSize == 0)
		return;

	Common::SeekableReadStream *txiData = tpc.readStream(txiDataSize);

	try {
		_txi.load(*txiData);
	} catch (...) {
	}

	delete txiData;
}
Пример #7
0
bool CWaveFile::loadMusic(const CString &name) {
    assert(!_stream);

    StdCWadFile file;
    if (!file.open(name))
        return false;

    Common::SeekableReadStream *stream = file.readStream();
    _size = stream->size();
    _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES);
    _soundType = Audio::Mixer::kMusicSoundType;

    return true;
}
Пример #8
0
void LocString::readString(uint32 languageID, Common::SeekableReadStream &stream) {
	uint32 length = stream.readUint32LE();

	std::pair<StringMap::iterator, bool> s = _strings.insert(std::make_pair(languageID, ""));
	if (length == 0)
		return;

	s.first->second = "[???]";

	Common::ScopedPtr<Common::MemoryReadStream> data(stream.readStream(length));
	Common::ScopedPtr<Common::MemoryReadStream> parsed(LangMan.preParseColorCodes(*data));

	Common::Encoding encoding = LangMan.getEncodingLocString(LangMan.getLanguageGendered(languageID));
	if (encoding != Common::kEncodingInvalid)
		s.first->second = Common::readString(*parsed, encoding);
}
Пример #9
0
Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile) {
	// Open up the library for access
	Common::SeekableReadStream *libStream = load(libraryFile);

	// Check if the library has already had it's index read, and if not, load it
	if (!_indexes.contains(libraryFile))
		loadLibraryIndex(libraryFile, libStream, false);

	// Extract the data for the specified resource and return it
	LibraryEntry &entry = _indexes[libraryFile][filename];
	libStream->seek(entry._offset);
	Common::SeekableReadStream *stream = libStream->readStream(entry._size);
	decompressIfNecessary(stream);

	delete libStream;
	return stream;
}
Пример #10
0
void LocString::readString(uint32 languageID, Common::SeekableReadStream &stream) {
	uint32 length = stream.readUint32LE();

	std::pair<StringMap::iterator, bool> s = _strings.insert(std::make_pair(languageID, ""));
	if (length == 0)
		return;

	Common::MemoryReadStream *data   = stream.readStream(length);
	Common::MemoryReadStream *parsed = LangMan.preParseColorCodes(*data);

	Common::Encoding encoding = LangMan.getEncodingLocString(LangMan.getLanguageGendered(languageID));
	if (encoding == Common::kEncodingInvalid)
		encoding = Common::kEncodingUTF8;

	try {
		s.first->second = Common::readString(*parsed, encoding);
	} catch (...) {
		parsed->seek(0);
		s.first->second = Common::readString(*parsed, Common::kEncodingCP1252);
	}

	delete parsed;
	delete data;
}
Пример #11
0
void RivenGraphics::scheduleWaterEffect(uint16 sfxeID) {
	Common::SeekableReadStream *sfxeStream = _vm->getResource(ID_SFXE, sfxeID);

	if (sfxeStream->readUint16BE() != 'SL')
		error ("Unknown sfxe tag");

	// Read in header info
	SFXERecord sfxeRecord;
	sfxeRecord.frameCount = sfxeStream->readUint16BE();
	uint32 offsetTablePosition = sfxeStream->readUint32BE();
	sfxeRecord.rect.left = sfxeStream->readUint16BE();
	sfxeRecord.rect.top = sfxeStream->readUint16BE();
	sfxeRecord.rect.right = sfxeStream->readUint16BE();
	sfxeRecord.rect.bottom = sfxeStream->readUint16BE();
	sfxeRecord.speed = sfxeStream->readUint16BE();
	// Skip the rest of the fields...

	// Read in offsets
	sfxeStream->seek(offsetTablePosition);
	uint32 *frameOffsets = new uint32[sfxeRecord.frameCount];
	for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
		frameOffsets[i] = sfxeStream->readUint32BE();
	sfxeStream->seek(frameOffsets[0]);

	// Read in the scripts
	for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
		sfxeRecord.frameScripts.push_back(sfxeStream->readStream((i == sfxeRecord.frameCount - 1) ? sfxeStream->size() - frameOffsets[i] : frameOffsets[i + 1] - frameOffsets[i]));

	// Set it to the first frame
	sfxeRecord.curFrame = 0;
	sfxeRecord.lastFrameTime = 0;

	delete[] frameOffsets;
	delete sfxeStream;
	_waterEffects.push_back(sfxeRecord);
}
Пример #12
0
ASFStream::Packet *ASFStream::readPacket() {
	if (_curPacket == _packetCount)
		throw Common::Exception("ASFStream::readPacket(): Reading too many packets");

	uint32 packetStartPos = _stream->pos();

	// Read a single ASF packet
	if (_stream->readByte() != 0x82)
		throw Common::Exception("ASFStream::readPacket(): Missing packet header");

	if (_stream->readUint16LE() != 0)
		throw Common::Exception("ASFStream::readPacket(): Unknown is not zero");

	Packet *packet = new Packet();
	packet->flags = _stream->readByte();
	packet->segmentType = _stream->readByte();
	packet->packetSize = (packet->flags & 0x40) ? _stream->readUint16LE() : 0;

	uint16 paddingSize = 0;
	if (packet->flags & 0x10)
		paddingSize = _stream->readUint16LE();
	else if (packet->flags & 0x08)
		paddingSize = _stream->readByte();

	packet->sendTime = _stream->readUint32LE();
	packet->duration = _stream->readUint16LE();

	byte segmentCount = (packet->flags & 0x01) ? _stream->readByte() : 1;
	packet->segments.resize(segmentCount & 0x3F);

	for (uint32 i = 0; i < packet->segments.size(); i++) {
		Packet::Segment &segment = packet->segments[i];

		segment.streamID = _stream->readByte();
		segment.sequenceNumber = _stream->readByte();
		segment.isKeyframe = (segment.streamID & 0x80) != 0;
		segment.streamID &= 0x7F;

		uint32 fragmentOffset = 0;
		if (packet->segmentType == 0x55)
			fragmentOffset = _stream->readByte();
		else if (packet->segmentType == 0x59)
			fragmentOffset = _stream->readUint16LE();
		else if (packet->segmentType == 0x5D)
			fragmentOffset = _stream->readUint32LE();
		else
			throw Common::Exception("ASFStream::readPacket(): Unknown packet segment type 0x%02x", packet->segmentType);

		byte flags = _stream->readByte();
		if (flags == 1) {
			//uint32 objectStartTime = fragmentOffset; // reused purpose
			_stream->readByte(); // unknown

			uint32 dataLength = (packet->segments.size() == 1) ? (_maxPacketSize - (_stream->pos() - packetStartPos) - paddingSize) : _stream->readUint16LE();
			uint32 startObjectPos = _stream->pos();

			while ((uint32)_stream->pos() < dataLength + startObjectPos)
				segment.data.push_back(_stream->readStream(_stream->readByte()));
		} else if (flags == 8) {
			/* uint32 objectLength = */ _stream->readUint32LE();
			/* uint32 objectStartTime = */ _stream->readUint32LE();

			uint32 dataLength = 0;
			if (packet->segments.size() == 1)
				dataLength = _maxPacketSize - (_stream->pos() - packetStartPos) - fragmentOffset - paddingSize;
			else if (segmentCount & 0x40)
				dataLength = _stream->readByte();
			else
				dataLength = _stream->readUint16LE();

			_stream->skip(fragmentOffset);
			segment.data.push_back(_stream->readStream(dataLength));
		} else
			throw Common::Exception("ASFStream::readPacket(): Unknown packet flags 0x%02x", flags);
	}

	// Skip any padding
	_stream->skip(paddingSize);

	// We just read a packet
	_curPacket++;

	if ((uint32)_stream->pos() != packetStartPos + _maxPacketSize)
		throw Common::Exception("ASFStream::readPacket(): Mismatching packet pos: %d (should be %d)", _stream->pos(), _maxPacketSize + packetStartPos);

	return packet;
}
Пример #13
0
void ConversationData::load(const Common::String &filename) {
	Common::File inFile;
	char buffer[16];

	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);

	// **** Section 0: Header *************************************************
	Common::SeekableReadStream *convFile = convFileUnpacked.getItemStream(0);

	_nodeCount = convFile->readUint16LE();
	_dialogCount = convFile->readUint16LE();
	_messageCount = convFile->readUint16LE();
	_textLineCount = convFile->readUint16LE();
	_unk2 = convFile->readUint16LE();
	_maxImports = convFile->readUint16LE();
	_speakerCount = convFile->readUint16LE();

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		convFile->read(buffer, 16);
		_portraits[idx] = buffer;
	}

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		_speakerFrame[idx] = convFile->readUint16LE();
	}

	convFile->read(buffer, 14);
	_speechFile = Common::String(buffer);

	// Total text length in section 5
	_textSize = convFile->readUint32LE();
	_commandsSize = convFile->readUint32LE();

	// The rest of the section 0 is padding to allow room for a set of pointers
	// to the contents of the remaining sections loaded into memory as a
	// continuous data block containing both the header and the sections
	delete convFile;

	// **** Section 1: Nodes **************************************************
	convFile = convFileUnpacked.getItemStream(1);

	_nodes.clear();
	for (uint i = 0; i < _nodeCount; i++) {
		ConvNode node;
		node._index = convFile->readUint16LE();
		node._dialogCount = convFile->readUint16LE();
		node._unk1 = convFile->readSint16LE();	// TODO
		node._active = convFile->readSint16LE() != 0;
		node._unk3 = convFile->readSint16LE();	// TODO
		_nodes.push_back(node);
	}

	delete convFile;

	// **** Section 2: Dialogs ************************************************
	convFile = convFileUnpacked.getItemStream(2);
	assert(convFile->size() == _dialogCount * 8);

	_dialogs.resize(_dialogCount);
	for (uint idx = 0; idx < _dialogCount; ++idx) {
		_dialogs[idx]._textLineIndex = convFile->readSint16LE();
		_dialogs[idx]._speechIndex = convFile->readSint16LE();
		_dialogs[idx]._scriptOffset = convFile->readUint16LE();
		_dialogs[idx]._scriptSize = convFile->readUint16LE();
	}

	delete convFile;

	// **** Section 3: Messages ***********************************************
	convFile = convFileUnpacked.getItemStream(3);
	assert(convFile->size() == _messageCount * 4);

	_messages.resize(_messageCount);
	for (uint idx = 0; idx < _messageCount; ++idx) {
		_messages[idx]._stringIndex = convFile->readUint16LE();
		_messages[idx]._count = convFile->readUint16LE();
	}

	delete convFile;

	// **** Section 4: Text line offsets **************************************
	convFile = convFileUnpacked.getItemStream(4);
	assert(convFile->size() == _textLineCount * 2);

	uint16 *textLineOffsets = new uint16[_textLineCount];	// deleted below in section 5
	for (uint16 i = 0; i < _textLineCount; i++)
		textLineOffsets[i] = convFile->readUint16LE();

	delete convFile;

	// **** Section 5: Text lines *********************************************
	convFile = convFileUnpacked.getItemStream(5);
	assert(convFile->size() == _textSize);

	Common::String textLine;
	_textLines.resize(_textLineCount);
	char textLineBuffer[256];
	uint16 nextOffset;
	for (uint16 i = 0; i < _textLineCount; i++) {
		nextOffset = (i != _textLineCount - 1) ? textLineOffsets[i + 1] : convFile->size();
		convFile->read(textLineBuffer, nextOffset - textLineOffsets[i]);
		_textLines[i] = Common::String(textLineBuffer);
	}

	delete[] textLineOffsets;
	delete convFile;

	// **** Section 6: Scripts ************************************************
	convFile = convFileUnpacked.getItemStream(6);
	assert(convFile->size() == _commandsSize);

	for (uint idx = 0; idx < _dialogs.size(); ++idx) {
		// Move to the correct position for the dialog's script, and create
		// a memory stream to represent the data for just that script
		convFile->seek(_dialogs[idx]._scriptOffset);
		Common::SeekableReadStream *scriptStream = convFile->readStream(_dialogs[idx]._scriptSize);

		// Pass it to the dialog's script set class to parse into commands
		_dialogs[idx]._script.load(*scriptStream, _dialogs[idx]._scriptOffset);
		delete scriptStream;
	}

	delete convFile;
	inFile.close();
}