aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/coktelvideo.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/coktelvideo.h')
-rw-r--r--engines/gob/coktelvideo.h313
1 files changed, 313 insertions, 0 deletions
diff --git a/engines/gob/coktelvideo.h b/engines/gob/coktelvideo.h
new file mode 100644
index 0000000000..a4e5452cce
--- /dev/null
+++ b/engines/gob/coktelvideo.h
@@ -0,0 +1,313 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GOB_COKTELVIDEO_H
+#define GOB_COKTELVIDEO_H
+
+#include "common/stream.h"
+#include "sound/mixer.h"
+#include "sound/audiostream.h"
+
+namespace Gob {
+
+/** Common interface for handling Coktel Vision videos and derivated formats. */
+class CoktelVideo {
+public:
+ enum Features {
+ kFeaturesNone = 0,
+ /** Has an own palette. */
+ kFeaturesPalette = 8,
+ /** Suggests a data size. */
+ kFeaturesDataSize = 0x20,
+ /** Has sound. */
+ kFeaturesSound = 0x40,
+ /** Has specific frame coordinates. */
+ kFeaturesFrameCoords = 0x80,
+ /** Has general standard coordinates. */
+ kFeaturesStdCoords = 0x100,
+ /** Has a frame positions table. */
+ kFeaturesFramesPos = 0x200,
+ /** Has video. */
+ kFeaturesVideo = 0x400
+ };
+
+ enum StateFlags {
+ kStateNone = 0,
+ /** Changed the palette. */
+ kStatePalette = 0x10,
+ /** Performed a jump to another frame. */
+ kStateJump = 0x200,
+ /** Updated according to the specific frame coordinates. */
+ kStateFrameCoords = 0x400,
+ /** Got no frame data. */
+ kStateNoVideoData = 0x800,
+ /** Updated according to the general standard coordinates. */
+ kStateStdCoords = 0x1000,
+ /** Had to explicitely seek to the frame. */
+ kStateSeeked = 0x2000,
+ /** Reached a break-point. */
+ kStateBreak = 0x8000
+ };
+
+ struct State {
+ /** Left-most value of the updated rectangle. */
+ int16 left;
+ /** Top-most value of the updated rectangle. */
+ int16 top;
+ /** Right-most value of the updated rectangle. */
+ int16 right;
+ /** Bottom-most value of the updated rectangle. */
+ int16 bottom;
+ /** Set accordingly to what was done. */
+ uint32 flags;
+
+ State() : left(0), top(0), right(0), bottom(0), flags(0) { }
+ };
+
+ virtual ~CoktelVideo() { }
+
+ /** Returns the features the loaded video possesses. */
+ virtual uint16 getFeatures() const = 0;
+ /** Returns the x coordinate of the video. */
+ virtual int16 getX() const = 0;
+ /** Returns the y coordinate of the video. */
+ virtual int16 getY() const = 0;
+ /** Returns the width of the video. */
+ virtual int16 getWidth() const = 0;
+ /** Returns the height of the video. */
+ virtual int16 getHeight() const = 0;
+ /** Returns the number of frames the loaded video has. */
+ virtual uint16 getFramesCount() const = 0;
+ /** Returns the current frame number.
+ *
+ * This is the current frame after the last nextFrame()-call,
+ * i.e. it's 0 after loading, 1 after the first nextFrame()-call, etc..
+ */
+ virtual uint16 getCurrentFrame() const = 0;
+ /** Returns the frame rate. */
+ virtual int16 getFrameRate() const = 0;
+ /** Returns the number of frames the video lags behind the audio. */
+ virtual uint32 getSyncLag() const = 0;
+ /** Returns the current frame's palette. */
+ virtual const byte *getPalette() const = 0;
+
+ /** Load a video out of a stream. */
+ virtual bool load(Common::SeekableReadStream &stream) = 0;
+ /** Unload the currently loaded video. */
+ virtual void unload() = 0;
+
+ /** Set the coordinations where to draw the video. */
+ virtual void setXY(int16 x, int16 y) = 0;
+ /** Use a specific memory block as video memory. */
+ virtual void setVideoMemory(byte *vidMem, uint16 width, uint16 height) = 0;
+ /** Use an own memory block as video memory. */
+ virtual void setVideoMemory() = 0;
+
+ /** Play sound (if the IMD has sound). */
+ virtual void enableSound(Audio::Mixer &mixer) = 0;
+ /** Don't play sound or stop currently playing sound. */
+ virtual void disableSound() = 0;
+
+ /** Seek to a specific frame.
+ *
+ * @param frame The frame to which to seek.
+ * @param whence The offset from whence the frame is given.
+ * @param restart Restart the video to reach an otherwise inaccessible frame?
+ */
+ virtual void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false) = 0;
+
+ /** Render the next frame. */
+ virtual State nextFrame() = 0;
+ /** Wait for the frame to end. */
+ virtual void waitEndFrame() = 0;
+
+ /** Copy the current frame.
+ *
+ * @param dest The memory to which to copy the current frame
+ * @param x The x position to where to copy.
+ * @param y The y position to where to copy.
+ * @param pitch The buffer's width.
+ * @param transp Which color should be seen as transparent?
+ */
+ virtual void copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp = -1) = 0;
+};
+
+/** Coktel Vision's IMD files.
+ */
+class Imd : public CoktelVideo {
+public:
+ Imd();
+ ~Imd();
+
+ uint16 getFeatures() const { return _features; }
+ int16 getX() const { return _x; }
+ int16 getY() const { return _y; }
+ int16 getWidth() const { return _width; }
+ int16 getHeight() const { return _height; }
+ uint16 getFramesCount() const { return _framesCount; }
+ uint16 getCurrentFrame() const { return _curFrame; }
+ int16 getFrameRate() const { if (_hasSound) return 1000 / _soundSliceLength; return 12; }
+ uint32 getSyncLag() const { return _skipFrames; }
+ const byte *getPalette() const { return _palette; }
+
+ bool load(Common::SeekableReadStream &stream);
+ void unload();
+
+ void setXY(int16 x, int16 y);
+ void setVideoMemory(byte *vidMem, uint16 width, uint16 height);
+ void setVideoMemory();
+
+ void enableSound(Audio::Mixer &mixer);
+ void disableSound();
+
+ void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
+
+ State nextFrame();
+ void waitEndFrame();
+
+ void copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp = -1);
+
+protected:
+ struct Coord {
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ } PACKED_STRUCT;
+
+ Common::SeekableReadStream *_stream;
+ uint16 _version;
+ uint16 _features;
+ uint16 _flags;
+ int16 _x, _y, _width, _height;
+ int16 _stdX, _stdY, _stdWidth, _stdHeight;
+ uint16 _framesCount, _curFrame;
+ uint32 *_framesPos;
+ uint32 _firstFramePos;
+ Coord *_frameCoords;
+
+ uint32 _frameDataSize, _vidBufferSize;
+ byte *_frameData, *_vidBuffer;
+
+ byte _palette[768];
+
+ bool _hasOwnVidMem;
+ byte *_vidMem;
+ uint16 _vidMemWidth, _vidMemHeight;
+
+ bool _hasSound;
+ bool _soundEnabled;
+ uint8 _soundStage; // (0: no sound, 1: loaded, 2: playing)
+ uint32 _soundStartTime;
+ uint32 _skipFrames;
+
+ uint16 _soundFlags;
+ int16 _soundFreq;
+ int16 _soundSliceSize;
+ int16 _soundSlicesCount;
+ uint16 _soundSliceLength;
+
+ Audio::AppendableAudioStream *_audioStream;
+ Audio::SoundHandle _audioHandle;
+
+ uint32 _frameLength;
+ uint32 _lastFrameTime;
+
+ Audio::Mixer *_mixer;
+
+ void unsignedToSigned(byte *buffer, int length) {
+ while (length-- > 0) *buffer++ ^= 0x80;
+ }
+
+ void deleteVidMem(bool del = true);
+ void clear(bool del = true);
+
+ State processFrame(uint16 frame);
+ uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
+ void deLZ77(byte *dest, byte *src);
+};
+
+class Vmd : public Imd {
+public:
+ Vmd();
+ ~Vmd();
+
+ bool load(Common::SeekableReadStream &stream);
+ void unload();
+
+ void setXY(int16 x, int16 y);
+
+ void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
+
+ State nextFrame();
+
+protected:
+ enum PartType {
+ kPartTypeAudio = 1,
+ kPartTypeVideo = 2
+ };
+ struct Part {
+ PartType type;
+ uint32 size;
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ byte flags;
+ } PACKED_STRUCT;
+ struct Frame {
+ uint32 offset;
+ Part *parts;
+
+ Frame() : parts(0) { }
+ ~Frame() { delete[] parts; }
+ } PACKED_STRUCT;
+
+ static const uint16 _tableDPCM[128];
+
+ bool _hasVideo;
+
+ uint16 _partsPerFrame;
+ Frame *_frames;
+
+ byte _soundBytesPerSample;
+ byte _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
+
+ void clear(bool del = true);
+
+ State processFrame(uint16 frame);
+ uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
+
+ void emptySoundSlice(uint32 size);
+ void soundSlice8bit(uint32 size);
+ void soundSlice16bit(uint32 size, int16 &init);
+ void filledSoundSlice(uint32 size);
+ void filledSoundSlices(uint32 size, uint32 mask);
+ void deDPCM(byte *soundBuf, byte *dataBuf, int16 &init, uint32 n);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_COKTELVIDEO_H