Beispiel #1
0
bool MoviePlayer::playVideo() {
	uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
	uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;

	while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
		if (_decoder->needsUpdate()) {
			const Graphics::Surface *frame = _decoder->decodeNextFrame();
			if (frame) {
				if (_decoderType == kVideoDecoderPSX)
					drawFramePSX(frame);
				else
					_vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
			}

			if (_decoder->hasDirtyPalette()) {
				_decoder->setSystemPalette();

				uint32 maxWeight = 0;
				uint32 minWeight = 0xFFFFFFFF;
				uint32 weight;
				byte r, g, b;

				const byte *palette = _decoder->getPalette();

				for (int i = 0; i < 256; i++) {
					r = *palette++;
					g = *palette++;
					b = *palette++;

					weight = 3 * r * r + 6 * g * g + 2 * b * b;

					if (weight >= maxWeight) {
						maxWeight = weight;
						_white = i;
					}

					if (weight <= minWeight) {
						minWeight = weight;
						_black = i;
					}
				}
			}

			Graphics::Surface *screen = _vm->_system->lockScreen();
			performPostProcessing(screen, screen->pitch);
			_vm->_system->unlockScreen();
			_vm->_system->updateScreen();
		}

		Common::Event event;
		while (_vm->_system->getEventManager()->pollEvent(event))
			if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
				return false;

		_vm->_system->delayMillis(10);
	}

	return !_vm->shouldQuit();
}
Beispiel #2
0
bool VideoPlayer::playVideo(Common::List<Common::Event> &stopEvents) {
	_skipVideo = false;
	debug(0, "Playing video");

	g_system->fillScreen(0);

	int frameX = (g_system->getWidth() - _decoder->getWidth()) / 2;
	int frameY = (g_system->getHeight() - _decoder->getHeight()) / 2;

	while (_decoder->getCurFrame() < _decoder->getFrameCount() && !_skipVideo) {
		processVideoEvents(stopEvents);

		uint32 startTime = 0;
		_decoder->decodeNextFrame();

		Graphics::Surface *screen = g_system->lockScreen();
		_decoder->copyFrameToBuffer((byte *)screen->pixels, frameX, frameY, g_system->getWidth());
		performPostProcessing((byte *)screen->pixels);
		g_system->unlockScreen();

		uint32 waitTime = _decoder->getFrameWaitTime();

		if (!waitTime) {
			warning("dropped frame %i", _decoder->getCurFrame());
			continue;
		}

		// Update the screen
		g_system->updateScreen();

		startTime = g_system->getMillis();

		// Wait before showing the next frame
		while (g_system->getMillis() < startTime + waitTime && !_skipVideo) {
			processVideoEvents(stopEvents);
			g_system->delayMillis(10);
		}
	}

	return !_skipVideo;
}
Beispiel #3
0
bool MoviePlayer::playVideo() {
	bool skipped = false;
	uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
	uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;

	while (!_vm->shouldQuit() && !_decoder->endOfVideo() && !skipped) {
		if (_decoder->needsUpdate()) {
			const Graphics::Surface *frame = _decoder->decodeNextFrame();
			if (frame) {
				if (_decoderType == kVideoDecoderPSX)
					drawFramePSX(frame);
				else
					_vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
			}

			if (_decoder->hasDirtyPalette()) {
				_decoder->setSystemPalette();

				if (!_movieTexts.empty()) {
					// Look for the best color indexes to use to display the subtitles
					uint32 minWeight = 0xFFFFFFFF;
					uint32 weight;
					float c1Weight = 1e+30f;
					float c2Weight = 1e+30f;
					float c3Weight = 1e+30f;
					float c4Weight = 1e+30f;
					byte r, g, b;
					float h, s, v, hd, hsvWeight;

					const byte *palette = _decoder->getPalette();

					// Color comparaison for the subtitles colors is done in HSL
					// C1 color is used for George and is almost white (R = 248, G = 252, B = 248)
					const float h1 = 0.333333f, s1 = 0.02f, v1 = 0.99f;

					// C2 color is used for George as a narrator and is grey (R = 184, G = 188, B = 184)
					const float h2 = 0.333333f, s2 = 0.02f, v2 = 0.74f;

					// C3 color is used for Nicole and is rose (R = 200, G = 120, B = 184)
					const float h3 = 0.866667f, s3 = 0.4f, v3 = 0.78f;

					// C4 color is used for Maguire and is blue (R = 80, G = 152, B = 184)
					const float h4 = 0.55f, s4 = 0.57f, v4 = 0.72f;

					for (int i = 0; i < 256; i++) {
						r = *palette++;
						g = *palette++;
						b = *palette++;

						weight = 3 * r * r + 6 * g * g + 2 * b * b;

						if (weight <= minWeight) {
							minWeight = weight;
							_black = i;
						}

						convertColor(r, g, b, h, s, v);

						// C1 color
						// It is almost achromatic (very low saturation) so the hue as litle impact on the color.
						// Therefore use a low weight on hue and high weight on saturation.
						hd = h - h1;
						hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
						hsvWeight = 1.0f * hd * hd + 4.0f * (s - s1) * (s - s1) + 3.0f * (v - v1) * (v - v1);
						if (hsvWeight <= c1Weight) {
							c1Weight = hsvWeight;
							_c1Color = i;
						}

						// C2 color
						// Also an almost achromatic color so use the same weights as for C1 color.
						hd = h - h2;
						hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
						hsvWeight = 1.0f * hd * hd + 4.0f * (s - s2) * (s - s2) + 3.0f * (v - v2) * (v - v2);
						if (hsvWeight <= c2Weight) {
							c2Weight = hsvWeight;
							_c2Color = i;
						}

						// C3 color
						// A light rose. Use a high weight on the hue to get a rose.
						// The color is a bit gray and the saturation has not much impact so use a low weight.
						hd = h - h3;
						hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
						hsvWeight = 4.0f * hd * hd + 1.0f * (s - s3) * (s - s3) + 2.0f * (v - v3) * (v - v3);
						if (hsvWeight <= c3Weight) {
							c3Weight = hsvWeight;
							_c3Color = i;
						}

						// C4 color
						// Blue. Use a hight weight on the hue to get a blue.
						// The color is darker and more saturated than C3 and the saturation has more impact.
						hd = h - h4;
						hd += hd < -0.5f ? 1.0f : hd > 0.5f ? -1.0f : 0.0f;
						hsvWeight = 5.0f * hd * hd + 3.0f * (s - s4) * (s - s4) + 2.0f * (v - v4) * (v - v4);
						if (hsvWeight <= c4Weight) {
							c4Weight = hsvWeight;
							_c4Color = i;
						}
					}
				}
			}

			Graphics::Surface *screen = _vm->_system->lockScreen();
			performPostProcessing((byte *)screen->pixels);
			_vm->_system->unlockScreen();
			_vm->_system->updateScreen();
		}

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

		_vm->_system->delayMillis(10);
	}

	if (_decoderType == kVideoDecoderPSX) {
		// Need to jump back to paletted color
		initGraphics(g_system->getWidth(), g_system->getHeight(), true);
	}

	return !_vm->shouldQuit() && !skipped;
}