예제 #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(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();
}
예제 #2
0
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;
			}
		}
	}
}
예제 #3
0
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();
}
예제 #4
0
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());
}
예제 #5
0
파일: vpx.cpp 프로젝트: Supermanu/xoreos
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);
}
예제 #6
0
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;
	}
}
예제 #7
0
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;
	}
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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();
	}
}
예제 #11
0
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();
}