From 3668895abce7445077350f88c55175ff1c66b05f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 24 Jul 2009 21:36:42 +0000 Subject: CoktelVideo cleanup: Splitting up some IMD methods and removing the obsolete notifyPaused() svn-id: r42715 --- graphics/video/coktelvideo/coktelvideo.cpp | 378 +++++++++++++++++------------ 1 file changed, 217 insertions(+), 161 deletions(-) (limited to 'graphics/video/coktelvideo/coktelvideo.cpp') diff --git a/graphics/video/coktelvideo/coktelvideo.cpp b/graphics/video/coktelvideo/coktelvideo.cpp index 02893bb73e..2b0ae79186 100644 --- a/graphics/video/coktelvideo/coktelvideo.cpp +++ b/graphics/video/coktelvideo/coktelvideo.cpp @@ -101,47 +101,12 @@ Common::MemoryReadStream *Imd::getExtraData(const char *fileName) { return 0; } -bool Imd::load(Common::SeekableReadStream &stream) { - unload(); - - _stream = &stream; - - uint16 handle; - - handle = _stream->readUint16LE(); - _version = _stream->readByte(); - - // Version checking - if ((handle != 0) || (_version < 2)) { - warning("Imd::load(): Version incorrect (%d,%X)", handle, _version); - unload(); - return false; - } - - // Rest header - _features = _stream->readByte(); - _framesCount = _stream->readUint16LE(); - _x = _stream->readSint16LE(); - _y = _stream->readSint16LE(); - _width = _stream->readSint16LE(); - _height = _stream->readSint16LE(); - _flags = _stream->readUint16LE(); - _firstFramePos = _stream->readUint16LE(); - - // IMDs always have video - _features |= kFeaturesVideo; - // IMDs always have palettes - _features |= kFeaturesPalette; - - // Palette - _stream->read((byte *) _palette, 768); - +bool Imd::loadCoordinates() { // Standard coordinates if (_version >= 3) { _stdX = _stream->readUint16LE(); if (_stdX > 1) { warning("IMD: More than one standard coordinate quad found (%d)", _stdX); - unload(); return false; } if (_stdX != 0) { @@ -155,8 +120,14 @@ bool Imd::load(Common::SeekableReadStream &stream) { } else _stdX = -1; - // Offset to frame positions table - uint32 framesPosPos = 0; + return true; +} + +bool Imd::loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos) { + framesPosPos = 0; + framesCoordsPos = 0; + + // Frame positions if (_version >= 4) { framesPosPos = _stream->readUint32LE(); if (framesPosPos != 0) { @@ -166,12 +137,40 @@ bool Imd::load(Common::SeekableReadStream &stream) { } } - // Offset to frame coordinates - uint32 framesCoordsPos = 0; + // Frame coordinates if (_features & kFeaturesFrameCoords) framesCoordsPos = _stream->readUint32LE(); - // Sound + return true; +} + +bool Imd::assessVideoProperties() { + // Sizes of the frame data and extra video buffer + if (_features & kFeaturesDataSize) { + _frameDataSize = _stream->readUint16LE(); + if (_frameDataSize == 0) { + _frameDataSize = _stream->readUint32LE(); + _vidBufferSize = _stream->readUint32LE(); + } else + _vidBufferSize = _stream->readUint16LE(); + } else { + _frameDataSize = _width * _height + 500; + if (!(_flags & 0x100) || (_flags & 0x1000)) + _vidBufferSize = _frameDataSize; + } + + // Allocating working memory + _frameData = new byte[_frameDataSize + 500]; + assert(_frameData); + memset(_frameData, 0, _frameDataSize + 500); + _vidBuffer = new byte[_vidBufferSize + 500]; + assert(_vidBuffer); + memset(_vidBuffer, 0, _vidBufferSize + 500); + + return true; +} + +bool Imd::assessAudioProperties() { if (_features & kFeaturesSound) { _soundFreq = _stream->readSint16LE(); _soundSliceSize = _stream->readSint16LE(); @@ -185,7 +184,6 @@ bool Imd::load(Common::SeekableReadStream &stream) { if (_soundSlicesCount > 40) { warning("Imd::load(): More than 40 sound slices found (%d)", _soundSlicesCount); - unload(); return false; } @@ -200,28 +198,18 @@ bool Imd::load(Common::SeekableReadStream &stream) { } else _frameLength = 1000 / _frameRate; - // Sizes of the frame data and extra video buffer - if (_features & kFeaturesDataSize) { - _frameDataSize = _stream->readUint16LE(); - if (_frameDataSize == 0) { - _frameDataSize = _stream->readUint32LE(); - _vidBufferSize = _stream->readUint32LE(); - } else - _vidBufferSize = _stream->readUint16LE(); - } else { - _frameDataSize = _width * _height + 500; - if (!(_flags & 0x100) || (_flags & 0x1000)) - _vidBufferSize = _frameDataSize; - } + return true; +} - // Frame positions table +bool Imd::loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos) { + // Positions table if (_framesPos) { _stream->seek(framesPosPos, SEEK_SET); for (int i = 0; i < _framesCount; i++) _framesPos[i] = _stream->readUint32LE(); } - // Frame coordinates table + // Coordinates table if (_features & kFeaturesFrameCoords) { _stream->seek(framesCoordsPos, SEEK_SET); _frameCoords = new Coord[_framesCount]; @@ -234,17 +222,73 @@ bool Imd::load(Common::SeekableReadStream &stream) { } } + return true; +} + +bool Imd::load(Common::SeekableReadStream &stream) { + unload(); + + _stream = &stream; + + uint16 handle; + + handle = _stream->readUint16LE(); + _version = _stream->readByte(); + + // Version checking + if ((handle != 0) || (_version < 2)) { + warning("Imd::load(): Version incorrect (%d,%X)", handle, _version); + unload(); + return false; + } + + // Rest header + _features = _stream->readByte(); + _framesCount = _stream->readUint16LE(); + _x = _stream->readSint16LE(); + _y = _stream->readSint16LE(); + _width = _stream->readSint16LE(); + _height = _stream->readSint16LE(); + _flags = _stream->readUint16LE(); + _firstFramePos = _stream->readUint16LE(); + + // IMDs always have video + _features |= kFeaturesVideo; + // IMDs always have palettes + _features |= kFeaturesPalette; + + // Palette + _stream->read((byte *) _palette, 768); + + if (!loadCoordinates()) { + unload(); + return false; + } + + uint32 framesPosPos, frameCoordsPos; + if (!loadFrameTableOffsets(framesPosPos, frameCoordsPos)) { + unload(); + return false; + } + + if (!assessAudioProperties()) { + unload(); + return false; + } + + if (!assessVideoProperties()) { + unload(); + return false; + } + + if (!loadFrameTables(framesPosPos, frameCoordsPos)) { + unload(); + return false; + } + // Seek to the first frame _stream->seek(_firstFramePos, SEEK_SET); - // Allocating working memory - _frameData = new byte[_frameDataSize + 500]; - assert(_frameData); - memset(_frameData, 0, _frameDataSize + 500); - _vidBuffer = new byte[_vidBufferSize + 500]; - assert(_vidBuffer); - memset(_vidBuffer, 0, _vidBufferSize + 500); - return true; } @@ -252,9 +296,6 @@ void Imd::unload() { clear(); } -void Imd::notifyPaused(uint32 duration) { -} - void Imd::setFrameRate(int16 frameRate) { if (frameRate == 0) frameRate = 1; @@ -526,6 +567,88 @@ void Imd::clear(bool del) { _lastFrameTime = 0; } +void Imd::nextSoundSlice(bool hasNextCmd) { + if (hasNextCmd || !_soundEnabled) { + _stream->seek(_soundSliceSize, SEEK_CUR); + return; + } + + byte *soundBuf = new byte[_soundSliceSize]; + + _stream->read(soundBuf, _soundSliceSize); + unsignedToSigned(soundBuf, _soundSliceSize); + + _audioStream->queueBuffer(soundBuf, _soundSliceSize); +} + +bool Imd::initialSoundSlice(bool hasNextCmd) { + int dataLength = _soundSliceSize * _soundSlicesCount; + + if (hasNextCmd || !_soundEnabled) { + _stream->seek(dataLength, SEEK_CUR); + return false; + } + + byte *soundBuf = new byte[dataLength]; + + _stream->read(soundBuf, dataLength); + unsignedToSigned(soundBuf, dataLength); + + _audioStream->queueBuffer(soundBuf, dataLength); + + return _soundStage == 1; +} + +void Imd::emptySoundSlice(bool hasNextCmd) { + if (hasNextCmd || !_soundEnabled) + return; + + byte *soundBuf = new byte[_soundSliceSize]; + + memset(soundBuf, 0, _soundSliceSize); + + _audioStream->queueBuffer(soundBuf, _soundSliceSize); +} + +void Imd::videoData(uint32 size, State &state) { + _stream->read(_frameData, size); + _frameDataLen = size; + + if (_vidMemWidth <= state.right) { + state.left = 0; + state.right -= state.left; + } + if (_vidMemWidth <= state.right) + state.right = _vidMemWidth - 1; + if (_vidMemHeight <= state.bottom) { + state.top = 0; + state.bottom -= state.top; + } + if (_vidMemHeight <= state.bottom) + state.bottom = _vidMemHeight -1; + + state.flags |= renderFrame(state.left, state.top, state.right, state.bottom); + state.flags |= _frameData[0]; +} + +void Imd::calcFrameCoords(uint16 frame, State &state) { + if (_stdX != -1) { + state.left = _stdX; + state.top = _stdY; + state.right = _stdWidth + state.left - 1; + state.bottom = _stdHeight + state.top - 1; + state.flags |= kStateStdCoords; + } + if (_frameCoords && + (_frameCoords[frame].left != -1)) { + state.left = _frameCoords[frame].left; + state.top = _frameCoords[frame].top; + state.right = _frameCoords[frame].right; + state.bottom = _frameCoords[frame].bottom; + state.flags |= kStateFrameCoords; + } +} + CoktelVideo::State Imd::processFrame(uint16 frame) { State state; uint32 cmd = 0; @@ -551,41 +674,29 @@ CoktelVideo::State Imd::processFrame(uint16 frame) { state.bottom = _height + state.top - 1; do { - if (frame != 0) { - if (_stdX != -1) { - state.left = _stdX; - state.top = _stdY; - state.right = _stdWidth + state.left - 1; - state.bottom = _stdHeight + state.top - 1; - state.flags |= kStateStdCoords; - } - if (_frameCoords && - (_frameCoords[frame].left != -1)) { - state.left = _frameCoords[frame].left; - state.top = _frameCoords[frame].top; - state.right = _frameCoords[frame].right; - state.bottom = _frameCoords[frame].bottom; - state.flags |= kStateFrameCoords; - } - } + if (frame != 0) + calcFrameCoords(frame, state); cmd = _stream->readUint16LE(); - if ((cmd & 0xFFF8) == 0xFFF0) { - if (cmd == 0xFFF0) { + if ((cmd & kCommandBreakMask) == kCommandBreak) { + // Flow control + + if (cmd == kCommandBreak) { _stream->seek(2, SEEK_CUR); cmd = _stream->readUint16LE(); } - if (cmd == 0xFFF1) { + // Break + if (cmd == kCommandBreakSkip0) { state.flags = kStateBreak; continue; - } else if (cmd == 0xFFF2) { // Skip (16 bit) + } else if (cmd == kCommandBreakSkip16) { cmd = _stream->readUint16LE(); _stream->seek(cmd, SEEK_CUR); state.flags = kStateBreak; continue; - } else if (cmd == 0xFFF3) { // Skip (32 bit) + } else if (cmd == kCommandBreakSkip32) { cmd = _stream->readUint32LE(); _stream->seek(cmd, SEEK_CUR); state.flags = kStateBreak; @@ -593,59 +704,24 @@ CoktelVideo::State Imd::processFrame(uint16 frame) { } } + // Audio if (_soundStage != 0) { - byte *soundBuf; - - if (cmd == 0xFF00) { - // Next sound slice data - - if (!hasNextCmd && _soundEnabled) { - soundBuf = new byte[_soundSliceSize]; - assert(soundBuf); - - _stream->read(soundBuf, _soundSliceSize); - unsignedToSigned(soundBuf, _soundSliceSize); - _audioStream->queueBuffer(soundBuf, _soundSliceSize); - } else - _stream->seek(_soundSliceSize, SEEK_CUR); + if (cmd == kCommandNextSound) { + nextSoundSlice(hasNextCmd); cmd = _stream->readUint16LE(); - } else if (cmd == 0xFF01) { - // Initial sound data (all slices) - - int dataLength = _soundSliceSize * _soundSlicesCount; - - if (!hasNextCmd && _soundEnabled) { - soundBuf = new byte[dataLength]; - assert(soundBuf); - - _stream->read(soundBuf, dataLength); - unsignedToSigned(soundBuf, dataLength); - - if (_soundStage == 1) - startSound = true; - - _audioStream->queueBuffer(soundBuf, dataLength); - } else - _stream->seek(dataLength, SEEK_CUR); + } else if (cmd == kCommandStartSound) { + startSound = initialSoundSlice(hasNextCmd); cmd = _stream->readUint16LE(); - } else if (!hasNextCmd && (_soundEnabled)) { - // Empty sound slice - - soundBuf = new byte[_soundSliceSize]; - assert(soundBuf); - - memset(soundBuf, 0, _soundSliceSize); - - _audioStream->queueBuffer(soundBuf, _soundSliceSize); - } + } else + emptySoundSlice(hasNextCmd); } // Set palette - if (cmd == 0xFFF4) { + if (cmd == kCommandPalette) { _stream->seek(2, SEEK_CUR); state.flags |= kStatePalette; @@ -655,8 +731,8 @@ CoktelVideo::State Imd::processFrame(uint16 frame) { hasNextCmd = false; - // Jump to frame - if (cmd == 0xFFFD) { + if (cmd == kCommandJump) { + // Jump to frame frame = _stream->readSint16LE(); if (_framesPos) { @@ -667,37 +743,17 @@ CoktelVideo::State Imd::processFrame(uint16 frame) { state.flags |= kStateJump; } - } else if (cmd == 0xFFFC) { + } else if (cmd == kCommandVideoData) { + uint32 size = _stream->readUint32LE() + 2; - state.flags |= 1; - cmd = _stream->readUint32LE(); - _stream->read(_frameData, cmd + 2); - _frameDataLen = cmd + 2; - - if (_vidMemWidth <= state.right) { - state.left = 0; - state.right -= state.left; - } - if (_vidMemWidth <= state.right) - state.right = _vidMemWidth - 1; - if (_vidMemHeight <= state.bottom) { - state.top = 0; - state.bottom -= state.top; - } - if (_vidMemHeight <= state.bottom) - state.bottom = _vidMemHeight -1; + videoData(size, state); - state.flags |= renderFrame(state.left, state.top, state.right, state.bottom); - state.flags |= _frameData[0]; + state.flags |= 1; - // Frame video data } else if (cmd != 0) { + uint32 size = cmd + 2; - _stream->read(_frameData, cmd + 2); - _frameDataLen = cmd + 2; - - state.flags |= renderFrame(state.left, state.top, state.right, state.bottom); - state.flags |= _frameData[0]; + videoData(size, state); } else state.flags |= kStateNoVideoData; -- cgit v1.2.3