bool DrasculaEngine::animate(const char *animationFile, int FPS) { int NFrames; int cnt = 2; Common::SeekableReadStream *stream = _archives.open(animationFile); if (!stream) { error("Animation file %s not found", animationFile); } NFrames = stream->readSint32LE(); showFrame(stream, true); _system->delayMillis(1000 / FPS); while (cnt < NFrames) { showFrame(stream); _system->delayMillis(1000 / FPS); cnt++; byte key = getScan(); if (key == Common::KEYCODE_ESCAPE) term_int = 1; if (key != 0) break; } delete stream; return ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()); }
int64 GFF4Struct::getSint(Common::SeekableReadStream &data, IFieldType type) const { switch (type) { case kIFieldTypeUint8: return (int64) ((uint64) data.readByte()); case kIFieldTypeSint8: return (int64) data.readSByte(); case kIFieldTypeUint16: return (int64) ((uint64) data.readUint16LE()); case kIFieldTypeSint16: return (int64) data.readSint16LE(); case kIFieldTypeUint32: return (int64) ((uint64) data.readUint32LE()); case kIFieldTypeSint32: return (int64) data.readSint32LE(); case kIFieldTypeUint64: return (int64) ((uint64) data.readUint64LE()); case kIFieldTypeSint64: return (int64) data.readSint64LE(); default: break; } throw Common::Exception("GFF4: Field is not an int type"); }
void ERFFile::readV3ResList(Common::SeekableReadStream &erf, const ERFHeader &header) { if (!erf.seek(header.offResList)) throw Common::Exception(Common::kSeekError); uint32 index = 0; ResourceList::iterator res = _resources.begin(); IResourceList::iterator iRes = _iResources.begin(); for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) { int32 nameOffset = erf.readSint32LE(); if (nameOffset >= 0) { if ((uint32)nameOffset >= header.stringTableSize) throw Common::Exception("Invalid ERF string table offset"); Common::UString name = header.stringTable + nameOffset; res->name = TypeMan.setFileType(name, kFileTypeNone); res->type = TypeMan.getFileType(name); } res->index = index; res->hash = erf.readUint64LE(); uint32 typeHash = erf.readUint32LE(); // Look up the file type by its hash FileType type = TypeMan.getFileType(Common::kHashFNV32, typeHash); if (type != kFileTypeNone) res->type = type; iRes->offset = erf.readUint32LE(); iRes->packedSize = erf.readUint32LE(); iRes->unpackedSize = erf.readUint32LE(); } }
void SoundTowns_Darkmoon::loadSoundFile(Common::String name) { Common::SeekableReadStream *s = _vm->resource()->createReadStream(Common::String::format("%s.SDT", name.c_str())); if (!s) error("Failed to load sound file '%s.SDT'", name.c_str()); for (int i = 0; i < 120; i++) { _soundTable[i].type = s->readSByte(); _soundTable[i].para1 = s->readSint32LE(); _soundTable[i].para2 = s->readSint16LE(); } delete s; uint32 bytesLeft; uint8 *pmb = _vm->resource()->fileData(Common::String::format("%s.PMB", name.c_str()).c_str(), &bytesLeft); _vm->delay(300); if (pmb) { uint8 *src = pmb + 8; for (int i = 0; i < 32; i++) _intf->callback(5, 0x40, i, &src[i << 7]); _intf->callback(35, -1); src += 0x1000; bytesLeft -= 0x1008; while (bytesLeft) { _intf->callback(34, src); uint32 len = READ_LE_UINT16(&src[12]) + 32; src = src + len; bytesLeft -= len; } delete[] pmb; } else { warning("Sound file '%s.PMB' not found.", name.c_str()); // TODO } }
bool PatchedFile::readNextInst() { if (instrLeft == 0) { diffCopy = 0; extraCopy = 0; jump = 0; return false; } diffCopy = _ctrl->readUint32LE(); extraCopy = _ctrl->readUint32LE(); jump = _ctrl->readSint32LE(); //Sanity checks if (_ctrl->err() || (int32(diffCopy) > _file->size() - _file->pos()) || (int32(diffCopy) > _diff->size() - _diff->pos()) || (int32(extraCopy) > _extra->size() - _extra->pos()) || (jump > _file->size() - _file->pos())) error("%s: Corrupted patchfile. istrleft = %d", _patchName.c_str(), instrLeft); --instrLeft; return true; }
void DirectorySubEntry::readFromStream(Common::SeekableReadStream &inStream) { _offset = inStream.readUint32LE(); _size = inStream.readUint32LE(); _metadataSize = inStream.readUint16LE(); _face = inStream.readByte(); _type = static_cast<ResourceType>(inStream.readByte()); if (_metadataSize == 2 && (_type == kSpotItem || _type == kLocalizedSpotItem)) { _spotItemData.u = inStream.readUint32LE(); _spotItemData.v = inStream.readUint32LE(); } else if (_metadataSize == 10 && (_type == kMovie || _type == kMultitrackMovie)) { _videoData.v1.setValue(0, inStream.readSint32LE() * 0.000001f); _videoData.v1.setValue(1, inStream.readSint32LE() * 0.000001f); _videoData.v1.setValue(2, inStream.readSint32LE() * 0.000001f); _videoData.v2.setValue(0, inStream.readSint32LE() * 0.000001f); _videoData.v2.setValue(1, inStream.readSint32LE() * 0.000001f); _videoData.v2.setValue(2, inStream.readSint32LE() * 0.000001f); _videoData.u = inStream.readSint32LE(); _videoData.v = inStream.readSint32LE(); _videoData.width = inStream.readSint32LE(); _videoData.height = inStream.readSint32LE(); } else if (_type == kNumMetadata || _type == kTextMetadata) { if (_metadataSize > 20) { warning("Too much metadata, skipping"); inStream.skip(_metadataSize * sizeof(uint32)); return; } _miscData[0] = _offset; _miscData[1] = _size; for (uint i = 0; i < _metadataSize; i++) _miscData[i + 2] = inStream.readUint32LE(); } else if (_metadataSize != 0) { warning("Metadata not read for type %d, size %d", _type, _metadataSize); inStream.skip(_metadataSize * sizeof(uint32)); } }
void Resources::decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize) { int inputSize = (_vm->getGameID() == GType_RoseTattoo) ? source.readSint32LE() : -1; decompressLZ(source, buffer, outSize, inputSize); }
bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) { destroy(); if (stream.readByte() != 'B') return false; if (stream.readByte() != 'M') return false; /* uint32 fileSize = */ stream.readUint32LE(); /* uint16 res1 = */ stream.readUint16LE(); /* uint16 res2 = */ stream.readUint16LE(); uint32 imageOffset = stream.readUint32LE(); uint32 infoSize = stream.readUint32LE(); if (infoSize != 40) { warning("Only Windows v3 bitmaps are supported"); return false; } uint32 width = stream.readUint32LE(); int32 height = stream.readSint32LE(); if (width == 0 || height == 0) return false; if (height < 0) { warning("Right-side up bitmaps not supported"); return false; } /* uint16 planes = */ stream.readUint16LE(); uint16 bitsPerPixel = stream.readUint16LE(); if (bitsPerPixel != 8 && bitsPerPixel != 24 && bitsPerPixel != 32) { warning("%dbpp bitmaps not supported", bitsPerPixel); return false; } uint32 compression = stream.readUint32LE(); if (compression != 0) { warning("Compressed bitmaps not supported"); return false; } /* uint32 imageSize = */ stream.readUint32LE(); /* uint32 pixelsPerMeterX = */ stream.readUint32LE(); /* uint32 pixelsPerMeterY = */ stream.readUint32LE(); _paletteColorCount = stream.readUint32LE(); /* uint32 colorsImportant = */ stream.readUint32LE(); if (bitsPerPixel == 8) { if (_paletteColorCount == 0) _paletteColorCount = 256; // Read the palette _palette = new byte[_paletteColorCount * 3]; for (uint16 i = 0; i < _paletteColorCount; i++) { _palette[i * 3 + 2] = stream.readByte(); _palette[i * 3 + 1] = stream.readByte(); _palette[i * 3 + 0] = stream.readByte(); stream.readByte(); } } // Start us at the beginning of the image stream.seek(imageOffset); Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); // BGRA for 24bpp and 32 bpp if (bitsPerPixel == 24 || bitsPerPixel == 32) format = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0); _surface = new Graphics::Surface(); _surface->create(width, height, format); int srcPitch = width * (bitsPerPixel >> 3); const int extraDataLength = (srcPitch % 4) ? 4 - (srcPitch % 4) : 0; if (bitsPerPixel == 8) { byte *dst = (byte *)_surface->pixels; for (int32 i = 0; i < height; i++) { stream.read(dst + (height - i - 1) * width, width); stream.skip(extraDataLength); } } else if (bitsPerPixel == 24) { byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch; for (int32 i = 0; i < height; i++) { for (uint32 j = 0; j < width; j++) { byte b = stream.readByte(); byte g = stream.readByte(); byte r = stream.readByte(); uint32 color = format.RGBToColor(r, g, b); *((uint32 *)dst) = color; dst += format.bytesPerPixel; } stream.skip(extraDataLength); dst -= _surface->pitch * 2; } } else { // 32 bpp byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch; for (int32 i = 0; i < height; i++) { for (uint32 j = 0; j < width; j++) { byte b = stream.readByte(); byte g = stream.readByte(); byte r = stream.readByte(); // Ignore the last byte, as in v3 it is unused // and should thus NOT be used as alpha. // ref: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx stream.readByte(); uint32 color = format.RGBToColor(r, g, b); *((uint32 *)dst) = color; dst += format.bytesPerPixel; } stream.skip(extraDataLength); dst -= _surface->pitch * 2; } } return true; }
void Resources::decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize) { int inputSize = IS_ROSE_TATTOO ? source.readSint32LE() : -1; decompressLZ(source, buffer, outSize, inputSize); }