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(frame->getPixels(), frame->getPitch(), x, y, frame->getWidth(), frame->getHeight()); } if (_decoder->hasDirtyPalette()) { _vm->_system->getPaletteManager()->setPalette(_decoder->getPalette(), 0, 256); 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->getPitch()); _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(); }
void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 frame, int16 xx, int16 yy, int32 zz, Picture *mask, int32 scale) { debugC(5, kDebugAnim, "drawFrameWithMaskAndScale(surface, %d, %d, %d, %d, mask, %d)", frame, xx, yy, zz, scale); int16 dataFrame = frame; if (_frames[frame]._ref != -1) dataFrame = _frames[frame]._ref; int16 rectX = _frames[frame]._x2 - _frames[frame]._x1; int16 rectY = _frames[frame]._y2 - _frames[frame]._y1; int16 finalWidth = rectX * scale / 1024; int16 finalHeight = rectY * scale / 1024; // compute final x1, y1, x2, y2 int16 xx1 = xx + _x1 + _frames[frame]._x1 * scale / 1024; int16 yy1 = yy + _y1 + _frames[frame]._y1 * scale / 1024; int16 xx2 = xx1 + finalWidth; int16 yy2 = yy1 + finalHeight; int16 w = _frames[frame]._x2 - _frames[frame]._x1; _vm->addDirtyRect(xx1, yy1, xx2, yy2); int32 destPitch = surface.getPitch(); int32 destPitchMask = mask->getWidth(); uint8 *c = _frames[dataFrame]._data; uint8 *curRow = (uint8 *)surface.getPixels(); uint8 *curRowMask = mask->getDataPtr(); bool shadowFlag = false; if (strstr(_name, "SHADOW")) shadowFlag = true; for (int16 y = yy1; y < yy2; y++) { for (int16 x = xx1; x < xx2; x++) { if (x < 0 || x >= 1280 || y < 0 || y >= 400) continue; uint8 *cur = curRow + x + y * destPitch; uint8 *curMask = curRowMask + x + y * destPitchMask; // find the good c int16 xs = (x - xx1) * 1024 / scale; int16 ys = (y - yy1) * 1024 / scale; uint8 *cc = &c[ys * w + xs]; if (*cc && ((*curMask) >= zz)) { if (shadowFlag) *cur = _vm->getShadowLUT()[*cur]; else *cur = *cc; } } } }
void AGOSEngine::fillBackGroundFromFront() { Graphics::Surface *screen = _system->lockScreen(); byte *src = (byte *)screen->getPixels(); byte *dst = getBackGround(); for (int i = 0; i < _screenHeight; i++) { memcpy(dst, src, _screenWidth); src += screen->getPitch(); dst += _backGroundBuf->getPitch(); } _system->unlockScreen(); }
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { // The PSX videos have half resolution Graphics::Surface scaledFrame; scaledFrame.create(frame->getWidth(), frame->getHeight() * 2, frame->getFormat()); for (int y = 0; y < scaledFrame.getHeight(); y++) memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.getWidth() * scaledFrame.getFormat().bytesPerPixel); uint16 x = (g_system->getWidth() - scaledFrame.getWidth()) / 2; uint16 y = (g_system->getHeight() - scaledFrame.getHeight()) / 2; _vm->_system->copyRectToScreen(scaledFrame.getPixels(), scaledFrame.getPitch(), x, y, scaledFrame.getWidth(), scaledFrame.getHeight()); }
void VPXDecoder::decodeFrame(Graphics::Surface &surface, Common::SeekableReadStream &dataStream) { if (!_initialized) return; // Read all the data from the stream Common::ScopedArray<byte> data(new byte[dataStream.size()]); dataStream.read(data.get(), dataStream.size()); // Perform the actual decode vpx_codec_err_t result = vpx_codec_decode(&_context, data.get(), dataStream.size(), 0, 0); if (result != VPX_CODEC_OK) return; // Try to get the image vpx_codec_iter_t iter = 0; vpx_image_t *image = vpx_codec_get_frame(&_context, &iter); if (!image) return; // Figure out the color range Graphics::YUVToRGBManager::LuminanceScale scale; switch (image->range) { case VPX_CR_STUDIO_RANGE: scale = Graphics::YUVToRGBManager::kScaleITU; break; case VPX_CR_FULL_RANGE: scale = Graphics::YUVToRGBManager::kScaleFull; break; default: return; } // If we don't have it already, create our local surface if (!_surface) _surface.reset(new Graphics::Surface(image->w, image->h)); // Do the conversion based on the color space switch (image->fmt) { case VPX_IMG_FMT_I420: YUVToRGBMan.convert420(scale, _surface->getData(), _surface->getPitch(), image->planes[0], image->planes[1], image->planes[2], image->w, image->h, image->stride[0], image->stride[1]); break; default: return; } // Copy the subarea into the surface for (int y = 0; y < surface.getHeight(); y++) memcpy(surface.getData() + y * surface.getPitch(), _surface->getData() + (y * image->d_h) * image->d_w * 4, image->d_w * 4); }
void Animation::drawFontFrame(Graphics::Surface &surface, int32 frame, int16 xx, int16 yy, byte *colorMap) { debugC(4, kDebugAnim, "drawFontFrame(surface, %d, %d, %d, colorMap)", frame, xx, yy); if (frame < 0) frame = 0; if (frame >= _numFrames) frame = _numFrames - 1; if (_numFrames == 0) return; int16 dataFrame = frame; if (_frames[frame]._ref != -1) dataFrame = _frames[frame]._ref; int16 rectX = _frames[frame]._x2 - _frames[frame]._x1; int16 rectY = _frames[frame]._y2 - _frames[frame]._y1; if ((xx + _x1 + _frames[frame]._x1 < 0) || (yy + _y1 + _frames[frame]._y1 < 0)) return; if (rectX + xx + _x1 + _frames[frame]._x1 >= surface.getWidth()) rectX = surface.getWidth() - xx - _x1 - _frames[frame]._x1; if (rectX < 0) return; if (rectY + yy + _y1 + _frames[frame]._y1 >= surface.getHeight()) rectY = surface.getHeight() - yy - _y1 - _frames[frame]._y1; if (rectY < 0) return; int32 destPitch = surface.getPitch(); uint8 *c = _frames[dataFrame]._data; uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1, yy + _frames[frame]._y1 + _y1); for (int16 y = 0; y < rectY; y++) { unsigned char *cur = curRow; for (int16 x = 0; x < rectX; x++) { if (*c && *c < 4) *cur = colorMap[*c]; c++; cur++; } curRow += destPitch; } }
void Animation::drawFrame(Graphics::Surface &surface, int32 frame, int16 xx, int16 yy) { debugC(3, kDebugAnim, "drawFrame(surface, %d, %d, %d)", frame, xx, yy); if (frame < 0) frame = 0; if (frame >= _numFrames) frame = _numFrames - 1; if (_numFrames == 0) return; int16 dataFrame = frame; if (_frames[frame]._ref != -1) dataFrame = _frames[frame]._ref; if (!_frames[dataFrame]._data) return; int16 rectX = _frames[frame]._x2 - _frames[frame]._x1; int16 rectY = _frames[frame]._y2 - _frames[frame]._y1; int16 offsX = 0; int16 offsY = 0; _vm->addDirtyRect(xx + _x1 + _frames[frame]._x1, yy + _y1 + _frames[frame]._y1, xx + rectX + _x1 + _frames[frame]._x1 , yy + rectY + _y1 + _frames[frame]._y1); if (xx + _x1 + _frames[frame]._x1 < 0) { offsX = -(xx + _x1 + _frames[frame]._x1); } if (offsX >= rectX) return; else rectX -= offsX; if (yy + _y1 + _frames[frame]._y1 < 0) { offsY = -(yy + _y1 + _frames[frame]._y1); } if (offsY >= rectY) return; else rectY -= offsY; if (rectX + xx + _x1 + _frames[frame]._x1 >= surface.getWidth()) rectX = surface.getWidth() - xx - _x1 - _frames[frame]._x1; if (rectX < 0) return; if (rectY + yy + _y1 + _frames[frame]._y1 >= surface.getHeight()) rectY = surface.getHeight() - yy - _y1 - _frames[frame]._y1; if (rectY < 0) return; int32 destPitch = surface.getPitch(); uint8 *srcRow = _frames[dataFrame]._data + offsX + (_frames[frame]._x2 - _frames[frame]._x1) * offsY; uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1 + offsX, yy + _frames[frame]._y1 + _y1 + offsY); for (int16 y = 0; y < rectY; y++) { uint8 *cur = curRow; uint8 *c = srcRow + y * (_frames[frame]._x2 - _frames[frame]._x1); for (int16 x = 0; x < rectX; x++) { if (*c) *cur = *c; c++; cur++; } curRow += destPitch; } }
bool MoviePlayerSMK::processFrame() { Graphics::Surface *screen = _vm->_system->lockScreen(); copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->getPitch()); _vm->_system->unlockScreen(); uint32 waitTime = getTimeToNextFrame(); if (!waitTime && !endOfVideoTracks()) { warning("dropped frame %i", getCurFrame()); return false; } _vm->_system->updateScreen(); // Wait before showing the next frame _vm->_system->delayMillis(waitTime); return true; }
bool MoviePlayerDXA::processFrame() { Graphics::Surface *screen = _vm->_system->lockScreen(); copyFrameToBuffer((byte *)screen->getPixels(), (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->getPitch()); _vm->_system->unlockScreen(); uint32 soundTime = _mixer->getSoundElapsedTime(_bgSound); uint32 nextFrameStartTime = ((Video::VideoDecoder::VideoTrack *)getTrack(0))->getNextFrameStartTime().msecs(); if ((_bgSoundStream == NULL) || soundTime < nextFrameStartTime) { if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) { while (_mixer->isSoundHandleActive(_bgSound) && soundTime < nextFrameStartTime) { _vm->_system->delayMillis(10); soundTime = _mixer->getSoundElapsedTime(_bgSound); } // In case the background sound ends prematurely, update // _ticks so that we can still fall back on the no-sound // sync case for the subsequent frames. _ticks = _vm->_system->getMillis(); } else { _ticks += getTimeToNextFrame(); while (_vm->_system->getMillis() < _ticks) _vm->_system->delayMillis(10); } return true; } warning("dropped frame %i", getCurFrame()); return false; }
void AGOSEngine::displayScreen() { if (_fastFadeInFlag == 0 && _paletteFlag == 1) { _paletteFlag = 0; if (memcmp(_displayPalette, _currentPalette, sizeof(_currentPalette)) != 0) { memcpy(_currentPalette, _displayPalette, sizeof(_displayPalette)); _system->getPaletteManager()->setPalette(_displayPalette, 0, 256); } } Graphics::Surface *screen = _system->lockScreen(); if (getGameType() == GType_PP || getGameType() == GType_FF) { byte *src = getBackBuf(); byte *dst = (byte *)screen->getPixels(); for (int i = 0; i < _screenHeight; i++) { memcpy(dst, src, _screenWidth); src += _backBuf->getPitch(); dst += screen->getPitch(); } if (getGameId() != GID_DIMP) fillBackFromBackGround(_screenHeight, _screenWidth); } else { if (_window4Flag == 2) { _window4Flag = 0; uint16 srcWidth, width, height; byte *dst = (byte *)screen->getPixels(); const byte *src = (const byte *)_window4BackScn->getPixels(); if (_window3Flag == 1) { src = getBackGround(); } dst += (_moveYMin + _videoWindows[17]) * screen->getPitch(); dst += (_videoWindows[16] * 16) + _moveXMin; src += (_videoWindows[18] * 16 * _moveYMin); src += _moveXMin; srcWidth = _videoWindows[18] * 16; width = _moveXMax - _moveXMin; height = _moveYMax - _moveYMin; for (; height > 0; height--) { memcpy(dst, src, width); dst += screen->getPitch(); src += srcWidth; } _moveXMin = 0xFFFF; _moveYMin = 0xFFFF; _moveXMax = 0; _moveYMax = 0; } if (_window6Flag == 2) { _window6Flag = 0; byte *src = (byte *)_window6BackScn->getPixels(); byte *dst = (byte *)screen->getBasePtr(0, 51); for (int i = 0; i < 80; i++) { memcpy(dst, src, _window6BackScn->getWidth()); dst += screen->getPitch(); src += _window6BackScn->getPitch(); } } } _system->unlockScreen(); if (getGameType() == GType_FF && _scrollFlag) { scrollScreen(); } if (_fastFadeInFlag) { fastFadeIn(); } }
void AGOSEngine::displayBoxStars() { HitArea *ha, *dha; uint count; uint y_, x_; byte *dst; uint color; o_haltAnimation(); if (getGameType() == GType_SIMON2) color = 236; else color = 225; uint curHeight = (getGameType() == GType_SIMON2) ? _boxStarHeight : 134; for (int i = 0; i < 5; i++) { ha = _hitAreas; count = ARRAYSIZE(_hitAreas); Graphics::Surface *screen = _system->lockScreen(); do { if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) { dha = _hitAreas; if (ha->flags & kBFTextBox) { while (dha != ha && dha->flags != ha->flags) ++dha; if (dha != ha && dha->flags == ha->flags) continue; } else { dha = _hitAreas; while (dha != ha && dha->itemPtr != ha->itemPtr) ++dha; if (dha != ha && dha->itemPtr == ha->itemPtr) continue; } if (ha->y >= curHeight) continue; y_ = (ha->height / 2) - 4 + ha->y; x_ = (ha->width / 2) - 4 + ha->x - (_scrollX * 8); if (x_ >= 311) continue; dst = (byte *)screen->getPixels(); dst += (((screen->getPitch() / 4) * y_) * 4) + x_; dst[4] = color; dst += screen->getPitch(); dst[1] = color; dst[4] = color; dst[7] = color; dst += screen->getPitch(); dst[2] = color; dst[4] = color; dst[6] = color; dst += screen->getPitch(); dst[3] = color; dst[5] = color; dst += screen->getPitch(); dst[0] = color; dst[1] = color; dst[2] = color; dst[6] = color; dst[7] = color; dst[8] = color; dst += screen->getPitch(); dst[3] = color; dst[5] = color; dst += screen->getPitch(); dst[2] = color; dst[4] = color; dst[6] = color; dst += screen->getPitch(); dst[1] = color; dst[4] = color; dst[7] = color; dst += screen->getPitch(); dst[4] = color; } } while (ha++, --count); _system->unlockScreen(); delay(100); setMoveRect(0, 0, 320, curHeight); _window4Flag = 2; displayScreen(); delay(100); } o_restartAnimation(); }