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(); }
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; }
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; }