예제 #1
0
void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, uint spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer) {
	SpriteInfo *spriteInfo;

	if (spriteList.size() <= spriteNumber) {
		// this can occur in IHNM while loading a saved game from chapter 1-5 when being in the end chapter
		warning("spriteList.size() <= spriteNumber");
		return;
	}

	spriteInfo = &spriteList[spriteNumber];

	if (scale < 256) {
		xAlign = (spriteInfo->xAlign * scale) >> 8; //TODO: do we need to take in account sprite x&y aligns ?
		yAlign = (spriteInfo->yAlign * scale) >> 8; // ????
		height = (spriteInfo->height * scale + 0x7f) >> 8;
		width = (spriteInfo->width * scale + 0x7f) >> 8;
		size_t outLength = width * height;
		if (outLength > 0) {
			scaleBuffer(&spriteInfo->decodedBuffer.front(), spriteInfo->width, spriteInfo->height, scale, outLength);
			buffer = &_decodeBuf.front();
		} else {
			buffer = NULL;
		}
	} else {
예제 #2
0
void Sprite::loadList(int resourceId, SpriteList &spriteList) {
	SpriteInfo *spriteInfo;
	ByteArray spriteListData;
	uint16 oldSpriteCount;
	uint16 newSpriteCount;
	uint16 spriteCount;
	uint i;
	int outputLength, inputLength;
	uint32 offset;
	const byte *spritePointer;
	const byte *spriteDataPointer;

	_vm->_resource->loadResource(_spriteContext, resourceId, spriteListData);

	if (spriteListData.empty()) {
		return;
	}

	ByteArrayReadStreamEndian readS(spriteListData, _spriteContext->isBigEndian());

	spriteCount = readS.readUint16();

	debug(9, "Sprites: %d", spriteCount);

	oldSpriteCount = spriteList.size();
	newSpriteCount = oldSpriteCount + spriteCount;

	spriteList.resize(newSpriteCount);

	bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources();

	for (i = oldSpriteCount; i < spriteList.size(); i++) {
		spriteInfo = &spriteList[i];
		if (bigHeader)
			offset = readS.readUint32();
		else
			offset = readS.readUint16();

		if (offset >= spriteListData.size()) {
			// ITE Mac demos throw this warning
			warning("Sprite::loadList offset exceeded");
			spriteList.resize(i);
			return;
		}

		spritePointer = spriteListData.getBuffer();
		spritePointer += offset;

		if (bigHeader) {
			Common::MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian());

			spriteInfo->xAlign = readS2.readSint16();
			spriteInfo->yAlign = readS2.readSint16();

			spriteInfo->width = readS2.readUint16();
			spriteInfo->height = readS2.readUint16();

			spriteDataPointer = spritePointer + readS2.pos();
		} else {
			Common::MemoryReadStreamEndian readS2(spritePointer, 4, false);

			spriteInfo->xAlign = readS2.readSByte();
			spriteInfo->yAlign = readS2.readSByte();

			spriteInfo->width = readS2.readByte();
			spriteInfo->height = readS2.readByte();
			spriteDataPointer = spritePointer + readS2.pos();
		}

		outputLength = spriteInfo->width * spriteInfo->height;
		inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer());
		spriteInfo->decodedBuffer.resize(outputLength);
		if (outputLength > 0) {
			decodeRLEBuffer(spriteDataPointer, inputLength, outputLength);
			byte *dst = &spriteInfo->decodedBuffer.front();
#ifdef ENABLE_IHNM
			// IHNM sprites are upside-down, for reasons which i can only
			// assume are perverse. To simplify things, flip them now. Not
			// at drawing time.

			if (_vm->getGameId() == GID_IHNM) {
				byte *src = &_decodeBuf[spriteInfo->width * (spriteInfo->height - 1)];

				for (int j = 0; j < spriteInfo->height; j++) {
					memcpy(dst, src, spriteInfo->width);
					src -= spriteInfo->width;
					dst += spriteInfo->width;
				}
			} else
#endif
				memcpy(dst, &_decodeBuf.front(), outputLength);
		}
	}
}