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; }
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"); }
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(); }