예제 #1
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();
}
예제 #2
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);
}
예제 #3
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();
}
예제 #4
0
uint32 VideoDecoder::FixedRateVideoTrack::getNextFrameStartTime() const {
	if (endOfTrack() || getCurFrame() < 0)
		return 0;

	Common::Rational time = (getCurFrame() + 1) * 1000;
	time /= getFrameRate();
	return time.toInt();
}
예제 #5
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());
}
예제 #6
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();
	}
}
예제 #7
0
uint32 FixedRateVideoDecoder::getFrameBeginTime(uint32 frame) const {
	Common::Rational beginTime = frame * 1000;
	beginTime /= getFrameRate();
	return beginTime.toInt();
}
예제 #8
0
uint32 SeekableBinkDecoder::getDuration() const
{
	Common::Rational duration = getFrameCount() * 1000 / getFrameRate();
	return duration.toInt();
}
예제 #9
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());
}