Пример #1
0
void ConversationConditionals::load(const Common::String &filename) {
	Common::File inFile;
	Common::SeekableReadStream *convFile;

	// Open up the file for access
	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);

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

	_currentNode = convFile->readUint16LE();
	int entryFlagsCount = convFile->readUint16LE();
	int varsCount = convFile->readUint16LE();
	int importsCount = convFile->readUint16LE();

	convFile->skip(4);

	_messageList1.resize(convFile->readUint16LE());
	_messageList2.resize(convFile->readUint16LE());
	_messageList3.resize(convFile->readUint16LE());
	_messageList4.resize(convFile->readUint16LE());
	convFile->skip(20);

	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList1.size())
			_messageList1[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList2.size())
			_messageList2[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList3.size())
			_messageList3[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList4.size())
			_messageList4[idx] = v;
	}

	delete convFile;

	// **** Section: Imports *************************************************
	int streamNum = 1;
	
	_importVariables.resize(importsCount);
	if (importsCount > 0) {
		convFile = convFileUnpacked.getItemStream(streamNum++);

		// Read in the variable indexes that each import value will be stored in
		for (int idx = 0; idx < importsCount; ++idx)
			_importVariables[idx] = convFile->readUint16LE();

		delete convFile;
	}

	// **** Section: Entry Flags *********************************************
	convFile = convFileUnpacked.getItemStream(streamNum++);
	assert(convFile->size() == (entryFlagsCount * 2));

	_entryFlags.resize(entryFlagsCount);
	for (int idx = 0; idx < entryFlagsCount; ++idx)
		_entryFlags[idx] = convFile->readUint16LE();

	delete convFile;

	// **** Section: Variables ***********************************************
	convFile = convFileUnpacked.getItemStream(streamNum);
	assert(convFile->size() == (varsCount * 6));

	_vars.resize(varsCount);
	for (int idx = 0; idx < varsCount; ++idx) {
		convFile->skip(2);	// Loaded values are never pointers, so don't need this
		_vars[idx]._isPtr = false;
		_vars[idx]._val = convFile->readSint16LE();
		convFile->skip(2);	// Unused segment selector for pointer values
	}

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

	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);
	Common::SeekableReadStream *convFile = convFileUnpacked.getItemStream(0);

	// **** Section 0: Header *************************************************
	_nodeCount = convFile->readUint16LE();
	_dialogCount = convFile->readUint16LE();
	_messageCount = convFile->readUint16LE();
	_textLineCount = convFile->readUint16LE();
	_unk2 = convFile->readUint16LE();
	_importCount = 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) {
		_speakerExists[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);

	_convNodes.clear();
	for (uint i = 0; i < _nodeCount; i++) {
		ConvNode node;
		node._index = convFile->readUint16LE();
		node._dialogCount = convFile->readUint16LE();
		node._unk1 = convFile->readSint16LE();	// TODO
		node._unk2 = convFile->readSint16LE();	// TODO
		node._unk3 = convFile->readSint16LE();	// TODO
		_convNodes.push_back(node);
		//debug("Node %d, index %d, entries %d - %d, %d, %d", i, node.index, node.dialogCount, node.unk1, node.unk2, node.unk3);
	}
	delete convFile;

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

	for (uint idx = 0; idx < _nodeCount; ++idx) {
		uint dialogCount = _convNodes[idx]._dialogCount;

		for (uint j = 0; j < dialogCount; ++j) {
			ConvDialog dialog;
			dialog._textLineIndex = convFile->readSint16LE();
			dialog._speechIndex = convFile->readSint16LE();
			dialog._nodeOffset = convFile->readUint16LE();
			dialog._nodeSize = convFile->readUint16LE();
			_convNodes[idx]._dialogs.push_back(dialog);
		}
	}
	delete convFile;

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

	_messages.resize(_messageCount);
	for (uint idx = 0; idx < _messageCount; ++idx)
		_messages[idx] = convFile->readUint32LE();

	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: Node entry commands ************************************
	convFile = convFileUnpacked.getItemStream(6);
	assert(convFile->size() == _commandsSize);

	for (uint16 i = 0; i < _nodeCount; i++) {
		uint16 dialogCount = _convNodes[i]._dialogCount;

		for (uint16 j = 0; j < dialogCount; j++) {
			//ConvDialog dialog = _convNodes[i].dialogs[j];
			byte command;
			uint16 chk;

			do {
				command = convFile->readByte();
				chk = convFile->readUint16BE();
				if (chk != 0xFF00 && chk != 0x0000) {
					warning("Error while reading conversation node entries - bailing out");
					break;
				}

				switch (command) {
				case cmdNodeEnd:
					//debug("Node end");
					break;
				case cmdDialogEnd:
					//debug("Dialog end");
					break;
				case cmdHide: {
					byte count = convFile->readByte();
					for (byte k = 0; k < count; k++) {
						/*uint16 nodeRef = */convFile->readUint16LE();
						//debug("Hide node %d", nodeRef);
					}

				}
							  break;
				case cmdUnhide: {
					byte count = convFile->readByte();
					for (byte k = 0; k < count; k++) {
						/*uint16 nodeRef = */convFile->readUint16LE();
						//debug("Unhide node %d", nodeRef);
					}

				}
								break;
				case cmdMessage:
					//debug("Message");
					convFile->skip(7);	// TODO
					break;
				case cmdGoto: {
					convFile->skip(3);	// unused?
					/*byte nodeRef = */convFile->readByte();
					//debug("Goto %d", nodeRef);
				}
							  break;
				case cmdAssign: {
					convFile->skip(3);	// unused?
					/*uint16 value = */convFile->readUint16LE();
					/*uint16 variable = */convFile->readUint16LE();
					//debug("Variable %d = %d", variable, value);
				}
								break;
				default:
					error("Unknown conversation command %d", command);
					break;
				}
			} while (command != cmdNodeEnd && command != cmdDialogEnd);
		}
	}

	delete convFile;
	inFile.close();

	// TODO: Still stuff to do
	warning("TODO GameConversations::get");
}
Пример #3
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();
}