mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
- Reverted commit #40730, as it introduced rounding errors
- Properly fixed the FLIC player - The sound chunk tag of DXA files is now read by the DXADecoder's loadFile() method svn-id: r40736
This commit is contained in:
parent
caf9bf0941
commit
6ec870303f
@ -273,10 +273,9 @@ void MoviePlayerDXA::stopVideo() {
|
||||
|
||||
void MoviePlayerDXA::startSound() {
|
||||
byte *buffer;
|
||||
uint32 offset, size, tag;
|
||||
uint32 offset, size;
|
||||
|
||||
tag = _fileStream->readUint32BE();
|
||||
if (tag == MKID_BE('WAVE')) {
|
||||
if (getSoundTag() == MKID_BE('WAVE')) {
|
||||
size = _fileStream->readUint32BE();
|
||||
|
||||
if (_sequenceNum) {
|
||||
@ -322,7 +321,7 @@ void MoviePlayerDXA::nextFrame() {
|
||||
}
|
||||
|
||||
if (_vm->_interactiveVideo == TYPE_LOOPING && getCurFrame() == getFrameCount()) {
|
||||
_fileStream->seek(_videoInfo.frameOffs);
|
||||
_fileStream->seek(_videoInfo.firstframeOffset);
|
||||
_videoInfo.currentFrame = 0;
|
||||
startSound();
|
||||
}
|
||||
@ -445,7 +444,7 @@ void MoviePlayerSMK::handleNextFrame() {
|
||||
|
||||
void MoviePlayerSMK::nextFrame() {
|
||||
if (_vm->_interactiveVideo == TYPE_LOOPING && getCurFrame() == getFrameCount()) {
|
||||
_fileStream->seek(_videoInfo.frameOffs);
|
||||
_fileStream->seek(_videoInfo.firstframeOffset);
|
||||
_videoInfo.currentFrame = 0;
|
||||
}
|
||||
|
||||
|
@ -144,15 +144,7 @@ bool MoviePlayer::load(uint32 id) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (_decoder->loadFile(filename)) {
|
||||
// The DXA animations in the Broken Sword games always use external audio tracks.
|
||||
if (_decoderType == kVideoDecoderDXA && _decoder->readSoundHeader() != MKID_BE('NULL'))
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return _decoder->loadFile(filename);
|
||||
}
|
||||
|
||||
void MoviePlayer::play(void) {
|
||||
@ -244,7 +236,7 @@ int32 DXADecoderWithSound::getAudioLag() {
|
||||
int32 videoTime = _videoInfo.currentFrame * frameDelay;
|
||||
int32 audioTime;
|
||||
|
||||
audioTime = (int32) _mixer->getSoundElapsedTime(*_bgSoundHandle);
|
||||
audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100);
|
||||
|
||||
return videoTime - audioTime;
|
||||
}
|
||||
|
@ -80,16 +80,7 @@ bool MoviePlayer::load(const char *name) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (_decoder->loadFile(filename)) {
|
||||
// The DXA animations in the Broken Sword games always use external audio tracks,
|
||||
// if they have any sound at all.
|
||||
if (_decoderType == kVideoDecoderDXA && _decoder->readSoundHeader() != MKID_BE('NULL'))
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return _decoder->loadFile(filename);
|
||||
}
|
||||
|
||||
void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadIn, uint32 leadOut) {
|
||||
@ -280,7 +271,7 @@ int32 DXADecoderWithSound::getAudioLag() {
|
||||
int32 videoTime = _videoInfo.currentFrame * frameDelay;
|
||||
int32 audioTime;
|
||||
|
||||
audioTime = (int32) _mixer->getSoundElapsedTime(*_bgSoundHandle);
|
||||
audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100);
|
||||
|
||||
return videoTime - audioTime;
|
||||
}
|
||||
|
@ -86,13 +86,13 @@ bool DXADecoder::loadFile(const char *fileName) {
|
||||
|
||||
if (frameRate > 0) {
|
||||
_videoInfo.frameRate = 1000 / frameRate;
|
||||
_videoInfo.frameDelay = frameRate;
|
||||
_videoInfo.frameDelay = frameRate * 100;
|
||||
} else if (frameRate < 0) {
|
||||
_videoInfo.frameRate = 100000 / (-frameRate);
|
||||
_videoInfo.frameDelay = -frameRate / 100;
|
||||
_videoInfo.frameDelay = -frameRate;
|
||||
} else {
|
||||
_videoInfo.frameRate = 10;
|
||||
_videoInfo.frameDelay = 100;
|
||||
_videoInfo.frameDelay = 10000;
|
||||
}
|
||||
|
||||
_videoInfo.width = _fileStream->readUint16BE();
|
||||
@ -155,9 +155,13 @@ bool DXADecoder::loadFile(const char *fileName) {
|
||||
} while (tag != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read the sound header
|
||||
_soundTag = _fileStream->readUint32BE();
|
||||
|
||||
_videoInfo.currentFrame = 0;
|
||||
|
||||
_videoInfo.frameOffs = _fileStream->pos();
|
||||
_videoInfo.firstframeOffset = _fileStream->pos();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -55,6 +55,11 @@ public:
|
||||
|
||||
bool decodeNextFrame();
|
||||
|
||||
/**
|
||||
* Get the sound chunk tag of the loaded DXA file
|
||||
*/
|
||||
uint32 getSoundTag() { return _soundTag; }
|
||||
|
||||
private:
|
||||
void decodeZlib(byte *data, int size, int totalSize);
|
||||
void decode12(int size);
|
||||
@ -76,6 +81,7 @@ private:
|
||||
uint16 _curHeight;
|
||||
uint32 _frameSize;
|
||||
ScaleMode _scaleMode;
|
||||
uint32 _soundTag;
|
||||
};
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
@ -72,8 +72,9 @@ bool FlicDecoder::loadFile(const char *fileName) {
|
||||
}
|
||||
_fileStream->readUint16LE(); // flags
|
||||
// Note: The normal delay is a 32-bit integer (dword), whereas the overriden delay is a 16-bit integer (word)
|
||||
_videoInfo.frameDelay = _fileStream->readUint32LE(); // frameDelay is the FLIC "speed", in milliseconds
|
||||
_videoInfo.frameRate = 1000 / _videoInfo.frameDelay;
|
||||
// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
|
||||
_videoInfo.frameDelay = 100 * _fileStream->readUint32LE();
|
||||
_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
|
||||
|
||||
_fileStream->seek(80);
|
||||
_offsetFrame1 = _fileStream->readUint32LE();
|
||||
@ -206,10 +207,11 @@ bool FlicDecoder::decodeNextFrame() {
|
||||
case FRAME_TYPE: {
|
||||
chunkCount = _fileStream->readUint16LE();
|
||||
// Note: The overriden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword)
|
||||
// frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here
|
||||
uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds
|
||||
if (newFrameDelay > 0) {
|
||||
_videoInfo.frameDelay = newFrameDelay;
|
||||
_videoInfo.frameRate = 1000 / _videoInfo.frameDelay;
|
||||
_videoInfo.frameDelay = 100 * newFrameDelay;
|
||||
_videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay;
|
||||
}
|
||||
_fileStream->readUint16LE(); // reserved, always 0
|
||||
uint16 newWidth = _fileStream->readUint16LE();
|
||||
|
@ -344,9 +344,9 @@ int32 SmackerDecoder::getAudioLag() {
|
||||
and how much time *should* have passed.
|
||||
*/
|
||||
|
||||
audioTime = g_system->getMillis() - _videoInfo.startTime;
|
||||
audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
|
||||
} else
|
||||
audioTime = (int32) _mixer->getSoundElapsedTime(_audioHandle);
|
||||
audioTime = (((int32) _mixer->getSoundElapsedTime(_audioHandle)) * 100);
|
||||
|
||||
return videoTime - audioTime;
|
||||
}
|
||||
@ -380,13 +380,13 @@ bool SmackerDecoder::loadFile(const char *fileName) {
|
||||
|
||||
if (frameRate > 0) {
|
||||
_videoInfo.frameRate = 1000 / frameRate;
|
||||
_videoInfo.frameDelay = frameRate;
|
||||
_videoInfo.frameDelay = frameRate * 100;
|
||||
} else if (frameRate < 0) {
|
||||
_videoInfo.frameRate = 100000 / (-frameRate);
|
||||
_videoInfo.frameDelay = -frameRate / 100;
|
||||
_videoInfo.frameDelay = -frameRate;
|
||||
} else {
|
||||
_videoInfo.frameRate = 10;
|
||||
_videoInfo.frameDelay = 100;
|
||||
_videoInfo.frameDelay = 10000;
|
||||
}
|
||||
|
||||
// Flags are determined by which bit is set, which can be one of the following:
|
||||
@ -473,7 +473,7 @@ bool SmackerDecoder::loadFile(const char *fileName) {
|
||||
_palette = (byte *)malloc(3 * 256);
|
||||
memset(_palette, 0, 3 * 256);
|
||||
|
||||
_videoInfo.frameOffs = _fileStream->pos();
|
||||
_videoInfo.firstframeOffset = _fileStream->pos();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -88,14 +88,14 @@ int32 VideoDecoder::getAudioLag() {
|
||||
Calculate the lag by how much time has gone by since the first frame
|
||||
and how much time *should* have passed.
|
||||
*/
|
||||
int32 audioTime = g_system->getMillis() - _videoInfo.startTime;
|
||||
int32 audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
|
||||
int32 videoTime = _videoInfo.currentFrame * getFrameDelay();
|
||||
|
||||
return videoTime - audioTime;
|
||||
}
|
||||
|
||||
uint32 VideoDecoder::getFrameWaitTime() {
|
||||
int32 waitTime = getFrameDelay() + getAudioLag();
|
||||
int32 waitTime = (getFrameDelay() + getAudioLag()) / 100;
|
||||
|
||||
if (waitTime < 0)
|
||||
return 0;
|
||||
|
@ -75,16 +75,16 @@ public:
|
||||
virtual int32 getFrameRate();
|
||||
|
||||
/**
|
||||
* Returns the time to wait for each frame in ms
|
||||
* @return the time to wait for each frame in ms
|
||||
* Returns the time to wait for each frame in 1/100 ms (to avoid rounding errors)
|
||||
* @return the time to wait for each frame in 1/100 ms (to avoid rounding errors)
|
||||
*/
|
||||
virtual int32 getFrameDelay();
|
||||
|
||||
/**
|
||||
* Returns the current A/V lag in ms
|
||||
* Returns the current A/V lag in 1/100 ms (to avoid rounding errors)
|
||||
* If > 0, audio lags behind
|
||||
* If < 0, video lags behind
|
||||
* @return the current A/V lag in ms
|
||||
* @return the current A/V lag in 1/100 ms (to avoid rounding errors)
|
||||
*/
|
||||
virtual int32 getAudioLag();
|
||||
|
||||
@ -158,20 +158,14 @@ public:
|
||||
*/
|
||||
virtual bool decodeNextFrame() = 0;
|
||||
|
||||
/**
|
||||
* Used to read the sound header from DXA files. It's not pretty,
|
||||
* but it's slightly better than exposing _fileStream
|
||||
*/
|
||||
uint32 readSoundHeader() { return _fileStream->readUint32BE(); }
|
||||
|
||||
protected:
|
||||
struct {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 frameCount;
|
||||
int32 frameRate;
|
||||
int32 frameDelay; // ms
|
||||
uint32 frameOffs;
|
||||
int32 frameDelay; // 1/100 ms (to avoid rounding errors)
|
||||
uint32 firstframeOffset;
|
||||
uint32 currentFrame;
|
||||
uint32 startTime;
|
||||
} _videoInfo;
|
||||
|
Loading…
Reference in New Issue
Block a user