void TwoDAFile::readRows2b(Common::SeekableReadStream &twoda) { /* And now read the cells. In binary 2DA files, each cell only * stores a single 16-bit number, the offset into the data segment * where the data for this cell can be found. Moreover, a single * data offset can be used by several cells, deduplicating the * cell data. */ size_t columnCount = _headers.size(); size_t rowCount = _rows.size(); size_t cellCount = columnCount * rowCount; uint32 *offsets = new uint32[cellCount]; Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); tokenize.addSeparator('\0'); for (size_t i = 0; i < cellCount; i++) offsets[i] = twoda.readUint16LE(); twoda.skip(2); // Size of the data segment in bytes size_t dataOffset = twoda.pos(); for (size_t i = 0; i < rowCount; i++) { _rows[i] = new TwoDARow(*this); _rows[i]->_data.resize(columnCount); for (size_t j = 0; j < columnCount; j++) { size_t offset = dataOffset + offsets[i * columnCount + j]; try { twoda.seek(offset); } catch (...) { delete[] offsets; throw; } _rows[i]->_data[j] = tokenize.getToken(twoda); if (_rows[i]->_data[j].empty()) _rows[i]->_data[j] = "****"; } } delete[] offsets; }
bool Mob::loadFromStream(Common::SeekableReadStream &stream) { int32 pos = stream.pos(); uint16 visible = stream.readUint16LE(); if (visible == 0xFFFF) return false; _visible = visible; _type = stream.readUint16LE(); _rect.left = stream.readUint16LE(); _rect.top = stream.readUint16LE(); _rect.right = stream.readUint16LE(); _rect.bottom = stream.readUint16LE(); _mask = stream.readUint16LE(); _examPosition.x = stream.readUint16LE(); _examPosition.y = stream.readUint16LE(); _examDirection = (Direction)stream.readUint16LE(); _usePosition.x = stream.readByte(); _usePosition.y = stream.readByte(); _useDirection = (Direction)stream.readUint16LE(); uint32 nameOffset = stream.readUint32LE(); uint32 examTextOffset = stream.readUint32LE(); byte c; stream.seek(nameOffset); _name.clear(); while ((c = stream.readByte())) _name += c; stream.seek(examTextOffset); _examText.clear(); c = stream.readByte(); if (c) { _examText += c; do { c = stream.readByte(); _examText += c; } while (c != 255); } stream.seek(pos + 32); return true; }
bool SaveContainer::isSave(Common::SeekableReadStream &stream) { // Remember the stream's position to seek back to uint32 startPos = stream.pos(); SaveHeader header; header.setType(kID); header.setVersion(kVersion); bool result = header.verifyReadSize(stream); // Seek back stream.seek(startPos); return result; }
void TopMenu::loadBmpArr(Common::SeekableReadStream &in) { _arraySize = in.readUint16BE(); delete _arrayBmp; _arrayBmp = new Graphics::Surface *[_arraySize * 2]; for (int i = 0; i < _arraySize; i++) { uint16 bmpSize = in.readUint16BE(); uint32 filPos = in.pos(); Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize); Graphics::BitmapDecoder bitmapDecoder; if (!bitmapDecoder.loadStream(stream)) error("TopMenu::loadBmpArr(): Could not load bitmap"); const Graphics::Surface *bitmapSrc = bitmapDecoder.getSurface(); if (bitmapSrc->format.bytesPerPixel == 1) error("TopMenu::loadBmpArr(): Unhandled paletted image"); _arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat()); _arrayBmp[i * 2 + 1] = new Graphics::Surface(); _arrayBmp[i * 2 + 1]->create(_arrayBmp[i * 2]->w * 2, _arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat()); byte *src = (byte *)_arrayBmp[i * 2]->getPixels(); byte *dst = (byte *)_arrayBmp[i * 2 + 1]->getPixels(); for (int j = 0; j < _arrayBmp[i * 2]->h; j++) { src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j); dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); for (int k = _arrayBmp[i * 2]->w; k > 0; k--) { for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } src -= _arrayBmp[i * 2]->format.bytesPerPixel; for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } } src = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1); for (int k = _arrayBmp[i * 2 + 1]->pitch; k > 0; k--) { *dst++ = *src++; } } in.seek(filPos + bmpSize); } }
uint16 MohawkEngine_Riven::matchRMAPToCard(uint32 rmapCode) { uint16 index = 0; Common::SeekableReadStream *rmapStream = getResource(ID_RMAP, 1); for (uint16 i = 1; rmapStream->pos() < rmapStream->size(); i++) { uint32 code = rmapStream->readUint32BE(); if (code == rmapCode) index = i; } delete rmapStream; if (!index) error ("Could not match RMAP code %08x", rmapCode); return index - 1; }
Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, Common::Encoding encoding) const { /* When the string is encoded in UTF-8, then length field specifies the length in bytes. * Otherwise, it's the length in characters. */ const size_t lengthMult = encoding == Common::kEncodingUTF8 ? 1 : Common::getBytesPerCodepoint(encoding); const size_t offset = data.pos(); const uint32 length = data.readUint32LE(); const size_t size = length * lengthMult; try { return readStringFixed(data, encoding, size); } catch (...) { } return Common::UString::format("GFF4: Invalid string encoding (0x%08X)", (uint) offset); }
Common::SeekableReadStream *GFF4Struct::getData(uint32 field) const { const Field *f; Common::SeekableReadStream *data = getField(field, f); if (!data) return 0; const uint32 count = getListCount(*data, *f); const uint32 size = getFieldSize(f->type); if ((size == 0) || (count == 0)) return 0; const uint32 dataBegin = data->pos(); const uint32 dataEnd = data->pos() + (count * size); return new Common::SeekableSubReadStream(data, dataBegin, dataEnd); }
void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) { loadPalette(stream); int streamSize = stream.size(); while (stream.pos() < streamSize) { ImageFrame frame; frame._width = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1; frame._paletteBase = stream.readByte(); if (animImages) { // Animation cutscene image files use a 16-bit x offset frame._offset.x = stream.readUint16LE(); frame._rleEncoded = (frame._offset.x & 0xff) == 1; frame._offset.y = stream.readByte(); } else { // Standard image files have a separate byte for the RLE flag, and an 8-bit X offset frame._rleEncoded = stream.readByte() == 1; frame._offset.x = stream.readByte(); frame._offset.y = stream.readByte(); } frame._rleEncoded = !skipPalette && frame._rleEncoded; if (frame._paletteBase) { // Nibble packed frame data frame._size = (frame._width * frame._height) / 2; } else if (frame._rleEncoded) { // This size includes the header size, which we subtract frame._size = stream.readUint16LE() - 11; frame._rleMarker = stream.readByte(); } else { // Uncompressed data frame._size = frame._width * frame._height; } // Load data for frame and decompress it byte *data = new byte[frame._size + 4]; stream.read(data, frame._size); Common::fill(data + frame._size, data + frame._size + 4, 0); frame.decompressFrame(data, IS_ROSE_TATTOO); delete[] data; push_back(frame); } }
void PLTFile::load(Common::SeekableReadStream &plt) { // --- PLT header --- AuroraBase::readHeader(plt); if (_id != kPLTID) throw Common::Exception("Not a PLT file (%s)", Common::debugTag(_id).c_str()); if (_version != kVersion1) throw Common::Exception("Unsupported PLT file version %s", Common::debugTag(_version).c_str()); const uint32 layers = plt.readUint32LE(); if (layers > kLayerMAX) throw Common::Exception("Too many layers (%d)", layers); plt.skip(4); // Unknown const uint32 width = plt.readUint32LE(); const uint32 height = plt.readUint32LE(); if ((plt.size() - plt.pos()) < (int32) (2 * width * height)) throw Common::Exception("Not enough data"); // --- PLT layer data --- uint32 size = width * height; _dataImage = new uint8[size]; _dataLayers = new uint8[size]; uint8 *image = _dataImage; uint8 *layer = _dataLayers; while (size-- > 0) { *image++ = plt.readByte(); *layer++ = MIN<uint8>(plt.readByte(), kLayerMAX - 1); } // --- Create the actual texture surface --- // Initialize it to pink, for high debug visibility _surface = new Surface(width, height); _surface->fill(0xFF, 0x00, 0xFF, 0xFF); set(_name, _surface, ::Aurora::kFileTypePLT, 0); addToQueues(); }
void TThandleQuoteEntries::load(const char *name) { Common::SeekableReadStream *r = g_vm->_filesManager->getResource(name); _tag1 = r->readUint32LE(); _tag2 = r->readUint32LE(); _rangeStart = r->readUint32LE(); _rangeEnd = r->readUint32LE(); while (r->pos() < r->size()) { TThandleQuoteEntry qe; qe._index = r->readUint32LE(); qe._tagId = r->readUint32LE(); qe._dialogueId = r->readUint32LE(); push_back(qe); } delete r; }
bool dumpStream(Common::SeekableReadStream &stream, const Common::UString &fileName) { Common::DumpFile file; if (!file.open(fileName)) return false; uint32 pos = stream.pos(); stream.seek(0); file.writeStream(stream); file.flush(); bool error = file.err(); stream.seek(pos); file.close(); return !error; }
bool CUP_Player::parseNextBlockTag(Common::SeekableReadStream &dataStream) { uint32 tag = dataStream.readUint32BE(); uint32 size = dataStream.readUint32BE() - 8; uint32 next = dataStream.pos() + size; debug(1, "New block tag %s %d dataSize %d", tag2str(tag), size, _dataSize); switch (tag) { case MKTAG('F','R','A','M'): handleFRAM(dataStream, size); break; case MKTAG('L','Z','S','S'): if (handleLZSS(dataStream, size) && _outLzssBufSize != 0) { Common::MemoryReadStream memoryStream(_outLzssBufData, _outLzssBufSize); parseNextBlockTag(memoryStream); } break; case MKTAG('R','A','T','E'): handleRATE(dataStream, size); break; case MKTAG('R','G','B','S'): handleRGBS(dataStream, size); break; case MKTAG('S','N','D','E'): handleSNDE(dataStream, size); break; case MKTAG('T','O','I','L'): handleTOIL(dataStream, size); break; case MKTAG('S','R','L','E'): handleSRLE(dataStream, size); break; case MKTAG('B','L','O','K'): _dataSize -= size + 8; return false; case MKTAG('W','R','L','E'): // this is never triggered default: warning("Unhandled tag %s", tag2str(tag)); break; } dataStream.seek(next); return true; }
void TRXFile::load(Common::SeekableReadStream &trx) { uint32 magic = trx.readUint32BE(); if (magic != MKTAG('N', 'W', 'N', '2')) throw Common::Exception("Invalid magic %s", Common::debugTag(magic).c_str()); uint16 versionMajor = trx.readUint16LE(); uint16 versionMinor = trx.readUint16LE(); if ((versionMajor != 2) || (versionMinor != 3)) throw Common::Exception("Invalid version %d.%d", versionMajor, versionMinor); uint32 packetCount = trx.readUint32LE(); if ((uint)(trx.size() - trx.pos()) < (packetCount * 8)) throw Common::Exception("TRX won't fit the packet packets"); std::vector<Packet> packets; packets.resize(packetCount); loadDirectory(trx, packets); loadPackets(trx, packets); }
bool PScr::loadFromStream(Common::SeekableReadStream &stream) { int32 pos = stream.pos(); uint16 file = stream.readUint16LE(); if (file == 0xFFFF) { return false; } _x = stream.readUint16LE(); _y = stream.readUint16LE(); _step = stream.readUint16LE(); const Common::String pscrStreamName = Common::String::format("PS%02d", file); Common::SeekableReadStream *pscrStream = SearchMan.createReadStreamForMember(pscrStreamName); if (pscrStream != nullptr) { loadSurface(*pscrStream); } delete pscrStream; stream.seek(pos + 12); // size of PScrList struct return true; }
void PLTFile::readHeader(Common::SeekableReadStream &plt) { AuroraBase::readHeader(plt); if (_id != kPLTID) throw Common::Exception("Not a PLT file"); if (_version != kVersion1) throw Common::Exception("Unsupported PLT file version %08X", _version); uint32 layers = plt.readUint32LE(); if (layers > kLayerMAX) throw Common::Exception("Too many layers (%d)", layers); plt.skip(4); // Unknown _width = plt.readUint32LE(); _height = plt.readUint32LE(); if ((plt.size() - plt.pos()) < (int32) (2 * _width * _height)) throw Common::Exception("Not enough data"); }
static GFFVersion identifyGFF(Common::SeekableReadStream &input, bool allowNWNPremium) { uint32 id = 0xFFFFFFFF, version = 0xFFFFFFFF; try { size_t pos = input.pos(); id = input.readUint32BE(); version = input.readUint32BE(); input.seek(pos); } catch (...) { throw; } GFFVersion gffVersion; if ((version == kVersion32) || (version == kVersion33)) { gffVersion = kGFFVersion3; allowNWNPremium = false; } else if ((version == kVersion40) || (version == kVersion41)) { gffVersion = kGFFVersion4; allowNWNPremium = false; } else if (allowNWNPremium && (FROM_BE_32(id) >= 0x30) && (FROM_BE_32(id) <= 0x12F)) { gffVersion = kGFFVersion3; } else throw Common::Exception("Invalid GFF %s, %s", Common::debugTag(id).c_str(), Common::debugTag(version).c_str()); size_t foundType = 0xFFFFFFFF; for (size_t i = 0; i < ARRAYSIZE(kGFFTypes); i++) { if (kGFFTypes[i] == id) { foundType = i; break; } } if ((foundType == 0xFFFFFFFF) && !allowNWNPremium) warning("Unknown GFF type %s", Common::debugTag(id).c_str()); return gffVersion; }
void TwoDAFile::readRows2b(Common::SeekableReadStream &twoda) { uint32 columnCount = _headers.size(); uint32 rowCount = _rows.size(); uint32 cellCount = columnCount * rowCount; uint32 *offsets = new uint32[cellCount]; Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); tokenize.addSeparator('\0'); for (uint32 i = 0; i < cellCount; i++) offsets[i] = twoda.readUint16LE(); twoda.skip(2); // Reserved uint32 dataOffset = twoda.pos(); for (uint32 i = 0; i < rowCount; i++) { _rows[i] = new TwoDARow(*this); _rows[i]->_data.resize(columnCount); for (uint32 j = 0; j < columnCount; j++) { uint32 offset = dataOffset + offsets[i * columnCount + j]; try { twoda.seek(offset); } catch (...) { delete[] offsets; throw; } _rows[i]->_data[j] = tokenize.getToken(twoda); if (_rows[i]->_data[j].empty()) _rows[i]->_data[j] = "****"; } } delete[] offsets; }
static void decodeTRLE(uint8 *dst, int dstPitch, Common::Rect &dstRect, Common::SeekableReadStream &dataStream) { dst += dstRect.top * dstPitch + dstRect.left; int h = dstRect.bottom - dstRect.top + 1; int w = dstRect.right - dstRect.left + 1; while (h--) { int lineSize = dataStream.readUint16LE(); int nextLineOffset = dataStream.pos() + lineSize; uint8 *dstNextLine = dst + dstPitch; if (lineSize != 0) { uint8 *dstEnd = dst + w; while (dst < dstEnd) { int code = dataStream.readByte(); if (code & 1) { // skip code >>= 1; dst += code; } else if (code & 2) { // set code = (code >> 2) + 1; const int sz = MIN<int>(code, dstEnd - dst); memset(dst, dataStream.readByte(), sz); dst += sz; } else { // copy
static int seek_stream_wrap(void *dataSource, ogg_int64_t offset, int whence) { Common::SeekableReadStream::Origin seekOrigin = Common::SeekableReadStream::kOriginMAX; switch (whence) { case SEEK_SET: seekOrigin = Common::SeekableReadStream::kOriginBegin; break; case SEEK_CUR: seekOrigin = Common::SeekableReadStream::kOriginCurrent; break; case SEEK_END: seekOrigin = Common::SeekableReadStream::kOriginEnd; break; default: assert(false); break; } Common::SeekableReadStream *stream = static_cast<Common::SeekableReadStream *>(dataSource); stream->seek((ptrdiff_t)offset, seekOrigin); return stream->pos(); }
bool parseInstruction(Common::SeekableReadStream &ncs, Instruction &instr) { instr.address = ncs.pos(); try { instr.opcode = (Opcode) ncs.readByte(); instr.type = (InstructionType) ncs.readByte(); } catch (...) { if (ncs.eos()) return false; throw; } if (((size_t)instr.opcode >= ARRAYSIZE(kParseFunc)) || !kParseFunc[(size_t)instr.opcode]) throw Common::Exception("Invalid opcode 0x%02X", (uint8)instr.opcode); const ParseFunc func = kParseFunc[(size_t)instr.opcode]; (*func)(instr, ncs); return true; }
CMusicSong::CMusicSong(int index) { // Read in the list of song strings Common::SeekableReadStream *res = g_vm->_filesManager->getResource("MUSIC/PARSER"); Common::StringArray parserStrings; while (res->pos() < res->size()) parserStrings.push_back(readStringFromStream(res)); delete res; // Set up a new song parser with the desired string CSongParser parser(parserStrings[index].c_str()); // Count how many encoded values there are CValuePair r; int count = 0; while (parser.parse(r)) ++count; assert(count > 0); // Read in the values to the array _data.resize(count); parser.reset(); for (int idx = 0; idx < count; ++idx) parser.parse(_data[idx]); // Figure out the range of values in the array _minVal = 0x7FFFFFFF; int maxVal = -0x7FFFFFFF; for (int idx = 0; idx < count; ++idx) { CValuePair &vp = _data[idx]; if (vp._data != 0x7FFFFFFF) { if (vp._data < _minVal) _minVal = vp._data; if (vp._data > maxVal) maxVal = vp._data; } } _range = maxVal - _minVal; }
bool dumpStream(Common::SeekableReadStream &stream, const Common::UString &fileName) { Common::WriteFile file; if (!file.open(fileName)) return false; size_t pos = stream.pos(); try { stream.seek(0); file.writeStream(stream); stream.seek(pos); file.flush(); } catch (...) { stream.seek(pos); return false; } file.close(); return true; }
void NDSFile::readNames(Common::SeekableReadStream &nds, uint32 offset, uint32 length) { if (!nds.seek(offset + 8)) throw Common::Exception(Common::kSeekError); uint32 index = 0; while (((uint32) nds.pos()) < (offset + length)) { Resource res; byte nameLength = nds.readByte(); Common::UString name; name.readFixedASCII(nds, nameLength); name.tolower(); res.name = TypeMan.setFileType(name, kFileTypeNone); res.type = TypeMan.getFileType(name); res.index = index++; _resources.push_back(res); } }
void ScalpelInventory::loadInv() { // Exit if the inventory names are already loaded if (_names.size() > 0) return; // Load the inventory names Common::SeekableReadStream *stream = _vm->_res->load("invent.txt"); int streamSize = stream->size(); while (stream->pos() < streamSize) { Common::String name; char c; while ((c = stream->readByte()) != 0) name += c; _names.push_back(name); } delete stream; loadGraphics(); }
ImageType Surface::identifyImage(Common::SeekableReadStream &stream) { uint32 startPos = stream.pos(); if ((stream.size() - startPos) < 17) return kImageTypeNone; char buffer[10]; if (!stream.read(buffer, 10)) return kImageTypeNone; stream.seek(startPos); if (!strncmp(buffer , "FORM", 4)) return kImageTypeIFF; if (!strncmp(buffer + 6, "JFIF", 4)) return kImageTypeJPEG; if (!strncmp(buffer , "BRC" , 3)) return kImageTypeBRC; if (!strncmp(buffer , "BM" , 2)) return kImageTypeBMP; // Try to determine if it's maybe a TGA stream.skip(12); uint16 width = stream.readUint16LE(); uint16 height = stream.readUint16LE(); uint8 bpp = stream.readByte(); // Check width, height and bpp for sane values if ((width == 0) || (height == 0) || (bpp == 0)) return kImageTypeNone; if ((width > 800) || (height > 600)) return kImageTypeNone; if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) return kImageTypeNone; // This might be a TGA return kImageTypeTGA; }
void Lua_V1::TextFileGetLineCount() { char textBuf[1000]; lua_Object nameObj = lua_getparam(1); if (lua_isnil(nameObj)) { lua_pushnil(); return; } const char *filename = luaL_check_string(1); Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::SeekableReadStream *file = saveFileMan->openForLoading(filename); if (!file) { lua_pushnil(); return; } lua_Object result = lua_createtable(); int line = 0; for (;;) { if (file->eos()) break; lua_pushobject(result); lua_pushnumber(line); int pos = file->pos(); lua_pushnumber(pos); lua_settable(); file->readLine(textBuf, 1000); line++; } delete file; lua_pushobject(result); lua_pushstring("count"); lua_pushnumber(line); lua_settable(); lua_pushobject(result); }
void TopMenu::loadBmpArr(Common::SeekableReadStream &in) { arraySize = in.readUint16BE(); delete arrayBmp; arrayBmp = new Graphics::Surface *[arraySize * 2]; for (int i = 0; i < arraySize; i++) { uint16 bmpSize = in.readUint16BE(); uint32 filPos = in.pos(); Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize); arrayBmp[i * 2] = Graphics::ImageDecoder::loadFile(stream, g_system->getOverlayFormat()); arrayBmp[i * 2 + 1] = new Graphics::Surface(); arrayBmp[i * 2 + 1]->create(arrayBmp[i * 2]->w * 2, arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat()); byte *src = (byte *)arrayBmp[i * 2]->pixels; byte *dst = (byte *)arrayBmp[i * 2 + 1]->pixels; for (int j = 0; j < arrayBmp[i * 2]->h; j++) { src = (byte *)arrayBmp[i * 2]->getBasePtr(0, j); dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); for (int k = arrayBmp[i * 2]->w; k > 0; k--) { for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } src -= arrayBmp[i * 2]->format.bytesPerPixel; for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } } src = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1); for (int k = arrayBmp[i * 2 + 1]->pitch; k > 0; k--) { *dst++ = *src++; } } in.skip(bmpSize); } }
void AdlEngine_v3::loadItemDescriptions(Common::SeekableReadStream &stream, byte count) { int32 startPos = stream.pos(); uint16 baseAddr = stream.readUint16LE(); // This code assumes that the first pointer points to a string that // directly follows the pointer table assert(baseAddr != 0); baseAddr -= count * 2; for (uint i = 0; i < count; ++i) { stream.seek(startPos + i * 2); uint16 offset = stream.readUint16LE(); if (offset > 0) { stream.seek(startPos + offset - baseAddr); _itemDesc.push_back(readString(stream, 0xff)); } else _itemDesc.push_back(Common::String()); } if (stream.eos() || stream.err()) error("Error loading item descriptions"); }
void SurfaceList::load(Common::SeekableReadStream &stream, Type type, int sub_hack) { free(); byte fn = stream.readByte(); if (stream.eos()) return; surfaces_n = fn - sub_hack; debug(0, "loading %u surfaces from list (skip %d)", surfaces_n, sub_hack); if (surfaces_n == 0) return; surfaces = new Surface[surfaces_n]; for (byte i = 0; i < surfaces_n; ++i) { uint offset = stream.readUint16LE(); uint pos = stream.pos(); stream.seek(offset); surfaces[i].load(stream, Surface::kTypeOns); stream.seek(pos); } }
bool Resource::loadFileList(const Common::String &filedata) { Common::SeekableReadStream *f = createReadStream(filedata); if (!f) return false; uint32 filenameOffset = 0; while ((filenameOffset = f->readUint32LE()) != 0) { uint32 offset = f->pos(); f->seek(filenameOffset, SEEK_SET); uint8 buffer[13]; f->read(buffer, sizeof(buffer)-1); buffer[12] = 0; f->seek(offset + 16, SEEK_SET); Common::String filename = Common::String((char *)buffer); filename.toUppercase(); if (filename.hasSuffix(".PAK")) { if (!exists(filename.c_str()) && _vm->gameFlags().isDemo) { // the demo version supplied with Kyra3 does not // contain all pak files listed in filedata.fdt // so we don't do anything here if they are non // existant. } else if (!loadPakFile(filename)) { delete f; error("couldn't load file '%s'", filename.c_str()); return false; // for compilers that don't support NORETURN } } } delete f; return true; }