aboutsummaryrefslogtreecommitdiff
path: root/graphics/video/coktelvideo/coktelvideo.cpp
diff options
context:
space:
mode:
authorSven Hesse2009-07-24 21:36:42 +0000
committerSven Hesse2009-07-24 21:36:42 +0000
commit3668895abce7445077350f88c55175ff1c66b05f (patch)
tree9cafedb01f5a4a81ba45c1bf4c559121f9889be8 /graphics/video/coktelvideo/coktelvideo.cpp
parent54b63ac239a8b555b191d40733e05090b3b08e3a (diff)
downloadscummvm-rg350-3668895abce7445077350f88c55175ff1c66b05f.tar.gz
scummvm-rg350-3668895abce7445077350f88c55175ff1c66b05f.tar.bz2
scummvm-rg350-3668895abce7445077350f88c55175ff1c66b05f.zip
CoktelVideo cleanup: Splitting up some IMD methods and removing the obsolete notifyPaused()
svn-id: r42715
Diffstat (limited to 'graphics/video/coktelvideo/coktelvideo.cpp')
-rw-r--r--graphics/video/coktelvideo/coktelvideo.cpp378
1 files changed, 217 insertions, 161 deletions
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;