aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gob/gob.cpp1
-rw-r--r--engines/gob/videoplayer.cpp9
-rw-r--r--engines/gob/videoplayer.h2
-rw-r--r--graphics/video/coktelvideo/coktelvideo.cpp378
-rw-r--r--graphics/video/coktelvideo/coktelvideo.h35
5 files changed, 247 insertions, 178 deletions
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 13f306fff1..6c8aceff33 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -306,7 +306,6 @@ void GobEngine::pauseEngineIntern(bool pause) {
} else {
uint32 duration = _system->getMillis() - _pauseStart;
- _vidPlayer->notifyPaused(duration);
_util->notifyPaused(duration);
_game->_startTimeKey += duration;
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 43395db829..a3a9dde892 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -797,13 +797,4 @@ void VideoPlayer::evalBgShading(Graphics::CoktelVideo &video) {
_vm->_sound->bgUnshade();
}
-void VideoPlayer::notifyPaused(uint32 duration) {
- if (_primaryVideo->isOpen())
- _primaryVideo->getVideo()->notifyPaused(duration);
-
- for (uint i = 0; i < _videoSlots.size(); i++)
- if (_videoSlots[i] && _videoSlots[i]->isOpen())
- _videoSlots[i]->getVideo()->notifyPaused(duration);
-}
-
} // End of namespace Gob
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index 532d216d7e..28e72ab43a 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -103,8 +103,6 @@ public:
void writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
int16 varFrames, int16 varWidth, int16 varHeight);
- void notifyPaused(uint32 duration);
-
private:
class Video {
public:
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;
diff --git a/graphics/video/coktelvideo/coktelvideo.h b/graphics/video/coktelvideo/coktelvideo.h
index ecb9a1505f..6a043233c9 100644
--- a/graphics/video/coktelvideo/coktelvideo.h
+++ b/graphics/video/coktelvideo/coktelvideo.h
@@ -175,9 +175,6 @@ public:
/** Wait for the frame to end. */
virtual void waitEndFrame() = 0;
- /** Notifies the video that it was paused for duration ms. */
- virtual void notifyPaused(uint32 duration) = 0;
-
/** Copy the current frame.
*
* @param dest The memory to which to copy the current frame.
@@ -223,8 +220,6 @@ public:
bool hasExtraData(const char *fileName) const;
Common::MemoryReadStream *getExtraData(const char *fileName);
- void notifyPaused(uint32 duration);
-
void setFrameRate(int16 frameRate);
bool load(Common::SeekableReadStream &stream);
@@ -251,6 +246,22 @@ public:
uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
protected:
+ enum Command {
+ kCommandNextSound = 0xFF00,
+ kCommandStartSound = 0xFF01,
+
+ kCommandBreak = 0xFFF0,
+ kCommandBreakSkip0 = 0xFFF1,
+ kCommandBreakSkip16 = 0xFFF2,
+ kCommandBreakSkip32 = 0xFFF3,
+ kCommandBreakMask = 0xFFF8,
+
+ kCommandPalette = 0xFFF4,
+ kCommandVideoData = 0xFFFC,
+
+ kCommandJump = 0xFFFD
+ };
+
struct Coord {
int16 left;
int16 top;
@@ -329,9 +340,23 @@ protected:
void deleteVidMem(bool del = true);
void clear(bool del = true);
+ bool loadCoordinates();
+ bool loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos);
+ bool assessVideoProperties();
+ bool assessAudioProperties();
+ bool loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos);
+
State processFrame(uint16 frame);
uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
void deLZ77(byte *dest, byte *src);
+
+ void calcFrameCoords(uint16 frame, State &state);
+
+ void nextSoundSlice(bool hasNextCmd);
+ bool initialSoundSlice(bool hasNextCmd);
+ void emptySoundSlice(bool hasNextCmd);
+
+ void videoData(uint32 size, State &state);
};
class Vmd : public Imd {