void Model::loadEMI(Common::MemoryReadStream &ms) { char name[64]; int nameLength = ms.readUint32LE(); assert(nameLength < 64); ms.read(name, nameLength); // skip over some unkown floats ms.seek(48, SEEK_CUR); _numMaterials = ms.readUint32LE(); _materials = new Material*[_numMaterials]; _materialNames = new char[_numMaterials][32]; for (int i = 0; i < _numMaterials; i++) { nameLength = ms.readUint32LE(); assert(nameLength < 32); ms.read(_materialNames[i], nameLength); // I'm not sure what specialty mateials are, but they are handled differently. if (memcmp(_materialNames[i], "specialty", 9) == 0) { _materials[i] = 0; } else { loadMaterial(i, 0); } ms.seek(4, SEEK_CUR); } ms.seek(4, SEEK_CUR); }
void AnimationResource::load(byte *source, int size) { Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size); sourceS->readUint32LE(); sourceS->readUint32LE(); sourceS->readUint16LE(); _flags = sourceS->readUint16LE(); _width = sourceS->readUint16LE(); _height = sourceS->readUint16LE(); sourceS->readUint32LE(); uint16 frameCount = sourceS->readUint16LE(); sourceS->readUint16LE(); sourceS->readUint16LE(); for (uint16 i = 0; i < frameCount; i++) { sourceS->seek(26 + i * 4); uint32 frameOffs = sourceS->readUint32LE(); sourceS->seek(frameOffs); sourceS->readUint32LE(); sourceS->readUint32LE(); uint16 frameWidth = sourceS->readUint16LE(); uint16 frameHeight = sourceS->readUint16LE(); uint16 cmdOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 pixelOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 maskOffs = sourceS->readUint16LE(); sourceS->readUint16LE(); uint16 lineSize = sourceS->readUint16LE(); Graphics::Surface *frame = new Graphics::Surface(); frame->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8()); decompressImage(source + frameOffs, *frame, cmdOffs, pixelOffs, maskOffs, lineSize, 0, 0, 0, _flags & 1); _frames.push_back(frame); } delete sourceS; }
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 Costume::loadEMI(Common::MemoryReadStream &ms, Costume *prevCost) { Common::List<Component *>components; _numChores = ms.readUint32LE(); _chores = new Chore[_numChores]; for (int i = 0; i < _numChores; i++) { uint32 nameLength; Component *prevComponent = NULL; nameLength = ms.readUint32LE(); ms.read(_chores[i]._name, nameLength); float length; ms.read(&length, 4); _chores[i]._length = (int)length; _chores[i]._owner = this; _chores[i]._numTracks = ms.readUint32LE(); _chores[i]._tracks = new ChoreTrack[_chores[i]._numTracks]; for (int k = 0; k < _chores[i]._numTracks; k++) { int componentNameLength = ms.readUint32LE(); assert(componentNameLength < 64); char name[64]; ms.read(name, componentNameLength); ms.readUint32LE(); int parentID = ms.readUint32LE(); if (parentID == -1 && prevCost) { MainModelComponent *mmc; // However, only the first item can actually share the // node hierarchy with the previous costume, so flag // that component so it knows what to do if (i == 0) parentID = -2; prevComponent = prevCost->_components[0]; mmc = dynamic_cast<MainModelComponent *>(prevComponent); // Make sure that the component is valid if (!mmc) prevComponent = NULL; } // Actually load the appropriate component Component *component = loadComponentEMI(parentID < 0 ? NULL : _components[parentID], parentID, name, prevComponent); //Component *component = loadComponentEMI(name, parent); components.push_back(component); ChoreTrack &track = _chores[i]._tracks[k]; track.numKeys = ms.readUint32LE(); track.keys = new TrackKey[track.numKeys]; // this is probably wrong track.compID = 0; for (int j = 0; j < track.numKeys; j++) { float time, value; ms.read(&time, 4); ms.read(&value, 4); track.keys[j].time = (int)time; track.keys[j].value = (int)value; } } //_chores[i]._tracks->compID; } _numComponents = components.size(); _components = new Component *[_numComponents]; int i = 0; for (Common::List<Component *>::iterator it = components.begin(); it != components.end(); ++it, ++i) { _components[i] = *it; if (!_components[i]) continue; _components[i]->setCostume(this); _components[i]->init(); } }