示例#1
0
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {
	// Since Audio::Timestamp doesn't support a fractional frame rate, we're currently
	// just converting to milliseconds.
	Common::Rational time = getFrameCount() * 1000;
	time /= getFrameRate();
	return time.toInt();
}
示例#2
0
void SeekableBinkDecoder::seekToFrame(uint32 frame) {
	assert(frame < _frames.size());

	// Fast path
	if ((int32)frame == _curFrame + 1)
		return;

	// Stop all audio (for now)
	stopAudio();

	// Track down the keyframe
	_curFrame = findKeyFrame(frame) - 1;
	while (_curFrame < (int32)frame - 1)
		skipNextFrame();

	// Map out the starting point
	Common::Rational startTime = frame * 1000 / getFrameRate();
	_startTime = g_system->getMillis() - startTime.toInt();
	resetPauseStartTime();

	// Adjust the audio starting point
	if (_audioTrack < _audioTracks.size()) {
		Common::Rational audioStartTime = (frame + 1) * 1000 / getFrameRate();
		_audioStartOffset = audioStartTime.toInt();
	}

	// Restart the audio
	startAudio();
}
示例#3
0
uint32 VideoDecoder::FixedRateVideoTrack::getNextFrameStartTime() const {
	if (endOfTrack() || getCurFrame() < 0)
		return 0;

	Common::Rational time = (getCurFrame() + 1) * 1000;
	time /= getFrameRate();
	return time.toInt();
}
示例#4
0
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) const {
	// Try to get as accurate as possible, considering we have a fractional frame rate
	// (which Audio::Timestamp doesn't support).
	Common::Rational frameRate = getFrameRate();

	if (frameRate == frameRate.toInt()) // The nice case (a whole number)
		return Audio::Timestamp(0, frame, frameRate.toInt());

	// Just convert to milliseconds.
	Common::Rational time = frame * 1000;
	time /= frameRate;
	return Audio::Timestamp(time.toInt(), 1000);
}
示例#5
0
void Movie::setTime(const TimeValue time, const TimeScale scale) {
	if (_video) {
		// Don't go past the ends of the movie
		Common::Rational timeFrac = Common::Rational(time, ((scale == 0) ? getScale() : scale));

		if (timeFrac < Common::Rational(_startTime, _startScale))
			timeFrac = Common::Rational(_startTime, _startScale);
		else if (timeFrac >= Common::Rational(_stopTime, _stopScale))
			return;

		_video->seek(Audio::Timestamp(0, timeFrac.getNumerator(), timeFrac.getDenominator()));
		_time = timeFrac;
		_lastMillis = 0;
	}
}
示例#6
0
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) const {
	// Try to get as accurate as possible, considering we have a fractional frame rate
	// (which Audio::Timestamp doesn't support).
	Common::Rational frameRate = getFrameRate();

	// Try to keep it in terms of the frame rate, if the frame rate is a whole
	// number.
	if (frameRate.getDenominator() == 1)
		return Audio::Timestamp(0, frame, frameRate.toInt());

	// Convert as best as possible
	Common::Rational time = frameRate.getInverse() * frame;
	return Audio::Timestamp(0, time.getNumerator(), time.getDenominator());
}
示例#7
0
void ZVision::onMouseMove(const Common::Point &pos) {
	Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));

	bool cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);

	// Graph of the function governing rotation velocity:
	//
	//                                    |---------------- working window ------------------|
	//               ^                    |---------|
	//               |                          |
	// +Max velocity |                        rotation screen edge offset
	//               |                                                                      /|
	//               |                                                                     / |
	//               |                                                                    /  |
	//               |                                                                   /   |
	//               |                                                                  /    |
	//               |                                                                 /     |
	//               |                                                                /      |
	//               |                                                               /       |
	//               |                                                              /        |
	// Zero velocity |______________________________ ______________________________/_________|__________________________>
	//               | Position ->        |         /
	//               |                    |        /
	//               |                    |       /
	//               |                    |      /
	//               |                    |     /
	//               |                    |    /
	//               |                    |   /
	//               |                    |  /
	//               |                    | /
	// -Max velocity |                    |/
	//               |
	//               |
	//               ^

	if (_workingWindow.contains(pos)) {
		RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState();
		if (renderState == RenderTable::PANORAMA) {
			if (pos.x >= _workingWindow.left && pos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) {
				// Linear function of distance to the left edge (y = -mx + b)
				// We use fixed point math to get better accuracy
				Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.left)) - MAX_ROTATION_SPEED;
				_renderManager->setBackgroundVelocity(velocity.toInt());
				_cursorManager->setLeftCursor();
				cursorWasChanged = true;
			} else if (pos.x <= _workingWindow.right && pos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) {
				// Linear function of distance to the right edge (y = mx)
				// We use fixed point math to get better accuracy
				Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET);
				_renderManager->setBackgroundVelocity(velocity.toInt());
				_cursorManager->setRightCursor();
				cursorWasChanged = true;
			} else {
				_renderManager->setBackgroundVelocity(0);
			}
		} else if (renderState == RenderTable::TILT) {
			if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) {
				// Linear function of distance to top edge
				// We use fixed point math to get better accuracy
				Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - MAX_ROTATION_SPEED;
				_renderManager->setBackgroundVelocity(velocity.toInt());
				_cursorManager->setUpCursor();
				cursorWasChanged = true;
			} else if (pos.y <= _workingWindow.bottom && pos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) {
				// Linear function of distance to the bottom edge (y = mx)
				// We use fixed point math to get better accuracy
				Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET);
				_renderManager->setBackgroundVelocity(velocity.toInt());
				_cursorManager->setDownCursor();
				cursorWasChanged = true;
			} else {
				_renderManager->setBackgroundVelocity(0);
			}
		}
	} else {
		_renderManager->setBackgroundVelocity(0);
	}

	if (!cursorWasChanged) {
		_cursorManager->revertToIdle();
	}
}
示例#8
0
void Surface::blitScaled(const Surface &from, int16 left, int16 top, int16 right, int16 bottom,
		int16 x, int16 y, Common::Rational scale, int32 transp) {

	if (scale == 1) {
		// Yeah, "scaled"

		blit(from, left, top, right, bottom, x, y, transp);
		return;
	}

	// Color depths have to fit
	assert(_bpp == from._bpp);

	uint16 dWidth  = (uint16) floor((_width  / scale).toDouble());
	uint16 dHeight = (uint16) floor((_height / scale).toDouble());
	 int16 clipX   = ( int16) floor((x       / scale).toDouble());
	 int16 clipY   = ( int16) floor((y       / scale).toDouble());

	// Clip
	if (!clipBlitRect(left, top, right, bottom, clipX, clipY, dWidth, dHeight, from._width, from._height))
		return;

	// Area to actually copy
	uint16 width  = right  - left + 1;
	uint16 height = bottom - top  + 1;

	if ((width == 0) || (height == 0))
		// Nothing to do
		return;

	width  = MIN<int32>((int32) floor((width  * scale).toDouble()), _width);
	height = MIN<int32>((int32) floor((height * scale).toDouble()), _height);

	// Pointers to the blit destination and source start points
	      byte *dst =      getData(x   , y);
	const byte *src = from.getData(left, top);

	frac_t step = scale.getInverse().toFrac();

	frac_t posW = 0, posH = 0;
	while (height-- > 0) {
		      byte *dstRow = dst;
		const byte *srcRow = src;

		posW = 0;

		for (uint16 i = 0; i < width; i++, dstRow += _bpp) {
			memmove(dstRow, srcRow, _bpp);

			posW += step;
			while (posW >= ((frac_t) FRAC_ONE)) {
				srcRow += from._bpp;
				posW   -= FRAC_ONE;
			}
		}

		posH += step;
		while (posH >= ((frac_t) FRAC_ONE)) {
			src  += from._width * from._bpp;
			posH -= FRAC_ONE;
		}

		dst += _width * _bpp;
	}

}
示例#9
0
uint32 FixedRateVideoDecoder::getFrameBeginTime(uint32 frame) const {
	Common::Rational beginTime = frame * 1000;
	beginTime /= getFrameRate();
	return beginTime.toInt();
}
示例#10
0
uint32 SeekableBinkDecoder::getDuration() const
{
	Common::Rational duration = getFrameCount() * 1000 / getFrameRate();
	return duration.toInt();
}
示例#11
0
void SeekableBinkDecoder::seekToTime(Audio::Timestamp time) {
	// Try to find the last frame that should have been decoded
	Common::Rational frame = time.msecs() * getFrameRate() / 1000;
	seekToFrame(frame.toInt());
}