예제 #1
0
void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey) {
	if (src.w == _dstRect.width() && src.h == _dstRect.height()) {
		blitSurfaceToBkg(src, _dstRect.left, _dstRect.top, colorkey);
	} else {
		Graphics::Surface *tmp = new Graphics::Surface;
		tmp->create(_dstRect.width(), _dstRect.height(), src.format);
		scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
		blitSurfaceToBkg(*tmp, _dstRect.left, _dstRect.top, colorkey);
		tmp->free();
		delete tmp;
	}
}
예제 #2
0
void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer) {
	SpriteInfo *spriteInfo;

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

	spriteInfo = &spriteList.infoList[spriteNumber];

	if (scale < 256) {
		xAlign = (spriteInfo->xAlign * scale) >> 8;
		yAlign = (spriteInfo->yAlign * scale) >> 8;
		height = (spriteInfo->height * scale + 0x7f) >> 8;
		width = (spriteInfo->width * scale + 0x7f) >> 8;
		scaleBuffer(spriteInfo->decodedBuffer, spriteInfo->width, spriteInfo->height, scale);
		buffer = _decodeBuf;
	} else {
예제 #3
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 {
예제 #4
0
void ZVision::playVideo(Video::VideoDecoder &videoDecoder, const Common::Rect &destRect, bool skippable) {
	byte bytesPerPixel = videoDecoder.getPixelFormat().bytesPerPixel;

	uint16 origWidth = videoDecoder.getWidth();
	uint16 origHeight = videoDecoder.getHeight();

	uint scale = 1;
	// If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
	if (destRect.isEmpty()) {
		// Most videos are very small. Therefore we do a simple 2x scale
		if (origWidth * 2 <= 640 && origHeight * 2 <= 480) {
			scale = 2;
		}
	} else {
		// Assume bilinear scaling. AKA calculate the scale from just the width.
		// Also assume that the scaling is in integral intervals. AKA no 1.5x scaling
		// TODO: Test ^these^ assumptions
		scale = destRect.width() / origWidth;

		// TODO: Test if we need to support downscale.
	}

	uint16 pitch = origWidth * bytesPerPixel;

	uint16 finalWidth = origWidth * scale;
	uint16 finalHeight = origHeight * scale;

	byte *scaledVideoFrameBuffer;
	if (scale != 1) {
		scaledVideoFrameBuffer = new byte[finalWidth * finalHeight * bytesPerPixel];
	}

	uint16 x = ((WINDOW_WIDTH - finalWidth) / 2) + destRect.left;
	uint16 y = ((WINDOW_HEIGHT - finalHeight) / 2) + destRect.top;

	_clock.stop();
	videoDecoder.start();

	// Only continue while the video is still playing
	while (!shouldQuit() && !videoDecoder.endOfVideo() && videoDecoder.isPlaying()) {
		// Check for engine quit and video stop key presses
		while (!videoDecoder.endOfVideo() && videoDecoder.isPlaying() && _eventMan->pollEvent(_event)) {
			switch (_event.type) {
			case Common::EVENT_KEYDOWN:
				switch (_event.kbd.keycode) {
				case Common::KEYCODE_q:
					if (_event.kbd.hasFlags(Common::KBD_CTRL))
						quitGame();
					break;
				case Common::KEYCODE_SPACE:
					if (skippable) {
						videoDecoder.stop();
					}
					break;
				default:
					break;
				}
			default:
				break;
			}
		}

		if (videoDecoder.needsUpdate()) {
			const Graphics::Surface *frame = videoDecoder.decodeNextFrame();

			if (frame) {
				if (scale != 1) {
					scaleBuffer((const byte *)frame->getPixels(), scaledVideoFrameBuffer, origWidth, origHeight, bytesPerPixel, scale);
					_system->copyRectToScreen(scaledVideoFrameBuffer, pitch * 2, x, y, finalWidth, finalHeight);
				} else {
					_system->copyRectToScreen((const byte *)frame->getPixels(), pitch, x, y, finalWidth, finalHeight);
				}
			}
		}

		// Always update the screen so the mouse continues to render
		_system->updateScreen();

		_system->delayMillis(videoDecoder.getTimeToNextFrame());
	}

	_clock.start();

	if (scale != 1) {
		delete[] scaledVideoFrameBuffer;
	}
}