Пример #1
0
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());
}
Пример #2
0
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");
}
Пример #3
0
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();
	}

}
Пример #4
0
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
	}
}
Пример #5
0
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;
}
Пример #6
0
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));
    }
}
Пример #7
0
void Resources::decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize) {
	int inputSize = (_vm->getGameID() == GType_RoseTattoo) ? source.readSint32LE() : -1;

	decompressLZ(source, buffer, outSize, inputSize);
}
Пример #8
0
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;
}
Пример #9
0
void Resources::decompress(Common::SeekableReadStream &source, byte *buffer, uint32 outSize) {
	int inputSize = IS_ROSE_TATTOO ? source.readSint32LE() : -1;

	decompressLZ(source, buffer, outSize, inputSize);
}