Пример #1
0
void PrinceEngine::playVideo(Common::String videoFilename) {
        // Set the correct video mode
        initGraphics(640, 480, true, 0);
        if (_system->getScreenFormat().bytesPerPixel == 1) {
                warning("Couldn't switch to a RGB color video mode to play a video.");
                return;
        }

        debug(2, "Screen format: %s", _system->getScreenFormat().toString().c_str());

	Video::VideoDecoder *videoDecoder = new Video::AVIDecoder();
	if (!videoDecoder->loadFile(videoFilename)) {
		delete videoDecoder;
		warning("Unable to open video %s", videoFilename.c_str());
		initGraphics(640, 480, true);
		return;
	}

	videoDecoder->start();

	bool skipVideo = false;

	while (!shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
		if (videoDecoder->needsUpdate()) {
			const Graphics::Surface *frame = videoDecoder->decodeNextFrame();
			if (frame) {
				if (frame->format.bytesPerPixel > 1) {
					Graphics::Surface *frame1 = frame->convertTo(_system->getScreenFormat());
					_system->copyRectToScreen(frame1->getPixels(), frame1->pitch, 0, 0, frame1->w, frame1->h);
					frame1->free();
					delete frame1;
				} else {
					_system->copyRectToScreen(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
				}
				_system->updateScreen();
			}
		}

		Common::Event event;
		while (_system->getEventManager()->pollEvent(event)) {
			if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) ||
				event.type == Common::EVENT_LBUTTONUP)
				skipVideo = true;
		}

		_system->delayMillis(10);
	}

	delete videoDecoder;

	initGraphics(640, 480, true);
}
Пример #2
0
void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) {
	Common::Rect dst = destRect;
	// If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
	if (dst.isEmpty())
		dst = Common::Rect(vid.getWidth(), vid.getHeight());

	Graphics::Surface scaled;

	if (vid.getWidth() != dst.width() || vid.getHeight() != dst.height())
		scaled.create(dst.width(), dst.height(), vid.getPixelFormat());

	uint16 x = _workingWindow.left + dst.left;
	uint16 y = _workingWindow.top + dst.top;
	uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
	uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
	bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1);

	_clock.stop();
	vid.start();
	_videoIsPlaying = true;

	// Only continue while the video is still playing
	while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) {
		// Check for engine quit and video stop key presses
		while (_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) {
						vid.stop();
					}
					break;
				default:
					break;
				}
			default:
				break;
			}
		}

		if (vid.needsUpdate()) {
			const Graphics::Surface *frame = vid.decodeNextFrame();
			if (sub && showSubs)
				sub->process(vid.getCurFrame());

			if (frame) {
				if (scaled.getPixels()) {
					_renderManager->scaleBuffer(frame->getPixels(), scaled.getPixels(), frame->getWidth(), frame->getHeight(), frame->getFormat().bytesPerPixel, scaled.getWidth(), scaled.getHeight());
					frame = &scaled;
				}
				Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
				_renderManager->copyToScreen(*frame, rect, 0, 0);
				_renderManager->processSubs(0);
			}
		}

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

		_system->delayMillis(vid.getTimeToNextFrame() / 2);
	}

	_videoIsPlaying = false;
	_clock.start();
}
Пример #3
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;
	}
}