[Scummvm-cvs-logs] SF.net SVN: scummvm:[51902] scummvm/trunk/graphics/video
drmccoy at users.sourceforge.net
drmccoy at users.sourceforge.net
Sun Aug 8 02:58:59 CEST 2010
Revision: 51902
http://scummvm.svn.sourceforge.net/scummvm/?rev=51902&view=rev
Author: drmccoy
Date: 2010-08-08 00:58:59 +0000 (Sun, 08 Aug 2010)
Log Message:
-----------
VIDEO: Implement VMD frame decoding
Modified Paths:
--------------
scummvm/trunk/graphics/video/coktel_decoder.cpp
scummvm/trunk/graphics/video/coktel_decoder.h
Modified: scummvm/trunk/graphics/video/coktel_decoder.cpp
===================================================================
--- scummvm/trunk/graphics/video/coktel_decoder.cpp 2010-08-08 00:58:29 UTC (rev 51901)
+++ scummvm/trunk/graphics/video/coktel_decoder.cpp 2010-08-08 00:58:59 UTC (rev 51902)
@@ -1681,7 +1681,7 @@
_frames[i].parts[j].field_E = _stream->readByte();
_frames[i].parts[j].flags = _stream->readByte();
- } else if (_frames[i].parts[j].type == kPartTypeSpeech) {
+ } else if (_frames[i].parts[j].type == kPartTypeSubtitle) {
_frames[i].parts[j].id = _stream->readUint16LE();
// Speech text file name
_stream->skip(8);
@@ -1806,7 +1806,6 @@
createSurface();
processFrame();
- renderFrame();
if (_curFrame == 0)
_startTime = g_system->getMillis();
@@ -1816,12 +1815,156 @@
void VMDDecoder::processFrame() {
_curFrame++;
+
+ _dirtyRects.clear();
+
+ _paletteDirty = false;
+
+ bool startSound = false;
+
+ for (uint16 i = 0; i < _partsPerFrame; i++) {
+ uint32 pos = _stream->pos();
+
+ Part &part = _frames[_curFrame].parts[i];
+
+ if (part.type == kPartTypeAudio) {
+
+ if (part.flags == 1) {
+ // Next sound slice data
+
+ if (_soundEnabled) {
+ filledSoundSlice(part.size);
+
+ if (_soundStage == kSoundLoaded)
+ startSound = true;
+
+ } else
+ _stream->skip(part.size);
+
+ } else if (part.flags == 2) {
+ // Initial sound data (all slices)
+
+ if (_soundEnabled) {
+ uint32 mask = _stream->readUint32LE();
+ filledSoundSlices(part.size - 4, mask);
+
+ if (_soundStage == kSoundLoaded)
+ startSound = true;
+
+ } else
+ _stream->skip(part.size);
+
+ } else if (part.flags == 3) {
+ // Empty sound slice
+
+ if (_soundEnabled) {
+ emptySoundSlice(_soundDataSize * _soundBytesPerSample);
+
+ if (_soundStage == kSoundLoaded)
+ startSound = true;
+ }
+
+ _stream->skip(part.size);
+ } else if (part.flags == 4) {
+ warning("Vmd::processFrame(): TODO: Addy 5 sound type 4 (%d)", part.size);
+ disableSound();
+ _stream->skip(part.size);
+ } else {
+ warning("Vmd::processFrame(): Unknown sound type %d", part.flags);
+ _stream->skip(part.size);
+ }
+
+ _stream->seek(pos + part.size);
+
+ } else if ((part.type == kPartTypeVideo) && !_hasVideo) {
+
+ warning("Vmd::processFrame(): Header claims there's no video, but video found (%d)", part.size);
+ _stream->skip(part.size);
+
+ } else if ((part.type == kPartTypeVideo) && _hasVideo) {
+
+ uint32 size = part.size;
+
+ // New palette
+ if (part.flags & 2) {
+ uint8 index = _stream->readByte();
+ uint8 count = _stream->readByte();
+
+ _stream->read(_palette + index * 3, (count + 1) * 3);
+ _stream->skip((255 - count) * 3);
+
+ _paletteDirty = true;
+
+ size -= (768 + 2);
+ }
+
+ _stream->read(_frameData, size);
+ _frameDataLen = size;
+
+ int16 l = part.left, t = part.top, r = part.right, b = part.bottom;
+ if (renderFrame(l, t, r, b))
+ _dirtyRects.push_back(Common::Rect(l, t, r + 1, b + 1));
+
+ } else if (part.type == kPartTypeSeparator) {
+
+ // Ignore
+
+ } else if (part.type == kPartTypeFile) {
+
+ // Ignore
+ _stream->skip(part.size);
+
+ } else if (part.type == kPartType4) {
+
+ // Unknown, ignore
+ _stream->skip(part.size);
+
+ } else if (part.type == kPartTypeSubtitle) {
+
+ // TODO:
+ // state.speechId = part.id;
+ // Always triggers when speech starts
+ _stream->skip(part.size);
+
+ } else {
+
+ warning("Vmd::processFrame(): Unknown frame part type %d, size %d (%d of %d)",
+ part.type, part.size, i + 1, _partsPerFrame);
+
+ }
+ }
+
+ if (startSound && _soundEnabled) {
+ if (_hasSound && _audioStream) {
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_audioHandle, _audioStream);
+ _soundStage = kSoundPlaying;
+ } else
+ _soundStage = kSoundNone;
+ }
+
+ if (((uint32)_curFrame == (_frameCount - 1)) && (_soundStage == 2)) {
+ _audioStream->finish();
+ _mixer->stopHandle(_audioHandle);
+ _audioStream = 0;
+ _soundStage = kSoundNone;
+ }
}
-// Just a simple blit
-void VMDDecoder::renderFrame() {
+bool VMDDecoder::renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom) {
+ // TODO
+
+ return false;
}
+void VMDDecoder::emptySoundSlice(uint32 size) {
+}
+
+void VMDDecoder::filledSoundSlice(uint32 size) {
+}
+
+void VMDDecoder::filledSoundSlices(uint32 size, uint32 mask) {
+}
+
PixelFormat VMDDecoder::getPixelFormat() const {
return PixelFormat::createFormatCLUT8();
}
Modified: scummvm/trunk/graphics/video/coktel_decoder.h
===================================================================
--- scummvm/trunk/graphics/video/coktel_decoder.h 2010-08-08 00:58:29 UTC (rev 51901)
+++ scummvm/trunk/graphics/video/coktel_decoder.h 2010-08-08 00:58:59 UTC (rev 51902)
@@ -362,7 +362,7 @@
kPartTypeVideo = 2,
kPartTypeFile = 3,
kPartType4 = 4,
- kPartTypeSpeech = 5
+ kPartTypeSubtitle = 5
};
enum AudioFormat {
@@ -459,7 +459,15 @@
// Frame decoding
void processFrame();
- void renderFrame();
+
+ // Video
+ bool renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom);
+
+ // Sound
+ void emptySoundSlice(uint32 size);
+ void filledSoundSlice(uint32 size);
+ void filledSoundSlices(uint32 size, uint32 mask);
+
};
} // End of namespace Graphics
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list