bool Node::dumpFaceMask(uint16 index, int face, DirectorySubEntry::ResourceType type) { static const int32 kMaskSize = 640 * 640; byte *mask = new byte[kMaskSize]; memset(mask, 0, kMaskSize); uint32 headerOffset = 0; uint32 dataOffset = 0; const DirectorySubEntry *maskDesc = _vm->getFileDescription(0, index, face, type); if (!maskDesc) { delete[] mask; return false; } Common::MemoryReadStream *maskStream = maskDesc->getData(); while (headerOffset < 400) { int blockX = (headerOffset / sizeof(dataOffset)) % 10; int blockY = (headerOffset / sizeof(dataOffset)) / 10; maskStream->seek(headerOffset, SEEK_SET); dataOffset = maskStream->readUint32LE(); headerOffset = maskStream->pos(); if (dataOffset != 0) { maskStream->seek(dataOffset, SEEK_SET); for(int i = 63; i >= 0; i--) { int x = 0; byte numValues = maskStream->readByte(); for (int j = 0; j < numValues; j++) { byte repeat = maskStream->readByte(); byte value = maskStream->readByte(); for (int k = 0; k < repeat; k++) { mask[((blockY * 64) + i) * 640 + blockX * 64 + x] = value; x++; } } } } } delete maskStream; Common::DumpFile outFile; outFile.open(Common::String::format("dump/%d-%d.masku_%d", index, face, type)); outFile.write(mask, kMaskSize); outFile.close(); delete[] mask; return true; }
void ObjectMan::loadObjectNames() { DisplayMan &dispMan = *_vm->_displayMan; _objectIconForMousePointer = new byte[16 * 16]; char *objectNames = new char[dispMan.getCompressedDataSize(k556_ObjectNamesGraphicIndice) + k199_ObjectNameCount]; Common::MemoryReadStream stream = dispMan.getCompressedData(k556_ObjectNamesGraphicIndice); for (uint16 objNameIndex = 0; objNameIndex < k199_ObjectNameCount; ++objNameIndex) { _objectNames[objNameIndex] = objectNames; byte tmpByte; for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte()) // last char of object name has 7th bit on *objectNames++ = tmpByte; // write while not last char *objectNames++ = tmpByte & 0x7F; // write without the 7th bit *objectNames++ = '\0'; // terminate string } }
void PictureResource::loadRaw(byte *source, int size) { // Loads a "raw" picture as used in RtZ, LGoP2, Manhole:N&E and Rodney's Funscreen Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size); _hasPalette = (sourceS->readByte() != 0); byte cmdFlags = sourceS->readByte(); byte pixelFlags = sourceS->readByte(); byte maskFlags = sourceS->readByte(); uint16 cmdOffs = sourceS->readUint16LE(); uint16 pixelOffs = sourceS->readUint16LE(); uint16 maskOffs = sourceS->readUint16LE(); uint16 lineSize = sourceS->readUint16LE(); /*uint16 u = */sourceS->readUint16LE(); uint16 width = sourceS->readUint16LE(); uint16 height = sourceS->readUint16LE(); if (cmdFlags || pixelFlags || maskFlags) { warning("PictureResource::loadRaw() Graphic has flags set (%d, %d, %d)", cmdFlags, pixelFlags, maskFlags); } _paletteColorCount = (cmdOffs - 18) / 3; // 18 = sizeof header debug(2, "width = %d; height = %d\n", width, height); if (_hasPalette) { _picturePalette = new byte[_paletteColorCount * 3]; sourceS->read(_picturePalette, _paletteColorCount * 3); } _picture = new Graphics::Surface(); _picture->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); decompressImage(source, *_picture, cmdOffs, pixelOffs, maskOffs, lineSize, cmdFlags, pixelFlags, maskFlags); delete sourceS; }
GTEST_TEST(MemoryReadStream, readStream) { static const byte data[3] = { 0x12, 0x34, 0x56 }; Common::MemoryReadStream stream(data); Common::MemoryReadStream *streamRead = stream.readStream(ARRAYSIZE(data)); EXPECT_EQ(streamRead->size(), ARRAYSIZE(data)); for (size_t i = 0; i < ARRAYSIZE(data); i++) EXPECT_EQ(streamRead->readByte(), data[i]) << "At index " << i; delete streamRead; stream.seek(0); EXPECT_THROW(stream.readStream(ARRAYSIZE(data) + 1), Common::Exception); }
void PictureResource::loadChunked(byte *source, int size) { // Loads a "chunked" picture as used in Manhole EGA Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size); byte cmdFlags = 0, pixelFlags = 0, maskFlags = 0; uint16 cmdOffs = 0, pixelOffs = 0, maskOffs = 0; uint16 lineSize = 0, width = 0, height = 0; sourceS->skip(36); // skip the "Flex" header _hasPalette = false; while (!sourceS->eos()) { uint32 chunkType = sourceS->readUint32BE(); uint32 chunkSize = sourceS->readUint32BE(); if (sourceS->eos()) break; debug(0, "chunkType = %08X; chunkSize = %d", chunkType, chunkSize); if (chunkType == MKTAG('R','e','c','t')) { debug(0, "Rect"); sourceS->skip(4); height = sourceS->readUint16BE(); width = sourceS->readUint16BE(); debug(0, "width = %d; height = %d", width, height); } else if (chunkType == MKTAG('f','M','a','p')) { debug(0, "fMap"); lineSize = sourceS->readUint16BE(); sourceS->skip(11); cmdFlags = sourceS->readByte(); cmdOffs = sourceS->pos(); sourceS->skip(chunkSize - 14); debug(0, "lineSize = %d; cmdFlags = %d; cmdOffs = %04X", lineSize, cmdFlags, cmdOffs); } else if (chunkType == MKTAG('f','L','C','o')) { debug(0, "fLCo"); sourceS->skip(9); pixelFlags = sourceS->readByte(); pixelOffs = sourceS->pos(); sourceS->skip(chunkSize - 10); debug(0, "pixelFlags = %d; pixelOffs = %04X", pixelFlags, pixelOffs); } else if (chunkType == MKTAG('f','P','i','x')) { debug(0, "fPix"); sourceS->skip(9); maskFlags = sourceS->readByte(); maskOffs = sourceS->pos(); sourceS->skip(chunkSize - 10); debug(0, "maskFlags = %d; maskOffs = %04X", maskFlags, maskOffs); } else if (chunkType == MKTAG('f','G','C','o')) { debug(0, "fGCo"); _hasPalette = true; _paletteColorCount = chunkSize / 3; _picturePalette = new byte[_paletteColorCount * 3]; sourceS->read(_picturePalette, _paletteColorCount * 3); } else { error("PictureResource::loadChunked() Invalid chunk %08X at %08X", chunkType, sourceS->pos()); } } if (!cmdOffs || !pixelOffs /*|| !maskOffs*/ || !lineSize || !width || !height) { error("PictureResource::loadChunked() Error parsing the picture data, one or more chunks/parameters are missing"); } _picture = new Graphics::Surface(); _picture->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); decompressImage(source, *_picture, cmdOffs, pixelOffs, maskOffs, lineSize, cmdFlags, pixelFlags, maskFlags); delete sourceS; }