Speech bubbles can point down right.
[scummvm-innocent.git] / graphics / video / coktelvideo / coktelvideo.h
blobdb80b4c43d90a6dadaab9b4947928a8dc4d5c93f
1 /* ScummVM - Graphic Adventure Engine
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $URL$
22 * $Id$
26 #ifndef GRAPHICS_VIDEO_COKTELVIDEO_H
27 #define GRAPHICS_VIDEO_COKTELVIDEO_H
29 #include "common/stream.h"
30 #include "common/array.h"
31 #include "graphics/dither.h"
32 #include "sound/mixer.h"
33 #include "sound/audiostream.h"
35 namespace Graphics {
37 class Indeo3;
39 /** Common interface for handling Coktel Vision videos and derivated formats. */
40 class CoktelVideo {
41 public:
42 enum Features {
43 kFeaturesNone = 0,
44 /** Has an own palette. */
45 kFeaturesPalette = 8,
46 /** Suggests a data size. */
47 kFeaturesDataSize = 0x20,
48 /** Has sound. */
49 kFeaturesSound = 0x40,
50 /** Has specific frame coordinates. */
51 kFeaturesFrameCoords = 0x80,
52 /** Has general standard coordinates. */
53 kFeaturesStdCoords = 0x100,
54 /** Has a frame positions table. */
55 kFeaturesFramesPos = 0x200,
56 /** Has video. */
57 kFeaturesVideo = 0x400,
58 /** Is a full color (non-paletted) video. */
59 kFeaturesFullColor = 0x4000,
60 /** Supports automatic doubling. */
61 kFeaturesSupportsDouble = 0x40000000
64 enum StateFlags {
65 kStateNone = 0,
66 /** Changed the palette. */
67 kStatePalette = 0x10,
68 /** Performed a jump to another frame. */
69 kStateJump = 0x200,
70 /** Updated according to the specific frame coordinates. */
71 kStateFrameCoords = 0x400,
72 /** Got no frame data. */
73 kStateNoVideoData = 0x800,
74 /** Updated according to the general standard coordinates. */
75 kStateStdCoords = 0x1000,
76 /** Had to explicitely seek to the frame. */
77 kStateSeeked = 0x2000,
78 /** Reached a break-point. */
79 kStateBreak = 0x8000,
80 /** Frame marks the beginning of speech. */
81 kStateSpeech = 0x4000000
84 struct State {
85 /** Left-most value of the updated rectangle. */
86 int16 left;
87 /** Top-most value of the updated rectangle. */
88 int16 top;
89 /** Right-most value of the updated rectangle. */
90 int16 right;
91 /** Bottom-most value of the updated rectangle. */
92 int16 bottom;
93 /** Set accordingly to what was done. */
94 uint32 flags;
95 /** The id of the spoken words. */
96 uint16 speechId;
98 State() : left(0), top(0), right(0), bottom(0), flags(0), speechId(0) { }
101 virtual ~CoktelVideo() { }
103 /** Returns the features the loaded video possesses. */
104 virtual uint32 getFeatures() const = 0;
105 /** Returns the flags the loaded video possesses. */
106 virtual uint16 getFlags() const = 0;
107 /** Returns the x coordinate of the video. */
108 virtual int16 getX() const = 0;
109 /** Returns the y coordinate of the video. */
110 virtual int16 getY() const = 0;
111 /** Returns the width of the video. */
112 virtual int16 getWidth() const = 0;
113 /** Returns the height of the video. */
114 virtual int16 getHeight() const = 0;
115 /** Returns the number of frames the loaded video has. */
116 virtual uint16 getFramesCount() const = 0;
117 /** Returns the current frame number.
119 * This is the current frame after the last nextFrame()-call,
120 * i.e. it's 0 after loading, 1 after the first nextFrame()-call, etc..
122 virtual uint16 getCurrentFrame() const = 0;
123 /** Returns the frame rate. */
124 virtual int16 getFrameRate() const = 0;
125 /** Returns the number of frames the video lags behind the audio. */
126 virtual uint32 getSyncLag() const = 0;
127 /** Returns the current frame's palette. */
128 virtual const byte *getPalette() const = 0;
130 /** Returns the frame's coordinates */
131 virtual bool getFrameCoords(int16 frame,
132 int16 &x, int16 &y, int16 &width, int16 &height) = 0;
134 /** Returns whether that extra data file exists */
135 virtual bool hasExtraData(const char *fileName) const = 0;
136 /** Returns an extra data file */
137 virtual Common::MemoryReadStream *getExtraData(const char *fileName) = 0;
139 /** Load a video out of a stream. */
140 virtual bool load(Common::SeekableReadStream &stream) = 0;
141 /** Unload the currently loaded video. */
142 virtual void unload() = 0;
144 /** Set the frame rate. */
145 virtual void setFrameRate(int16 frameRate) = 0;
147 /** Set the coordinations where to draw the video. */
148 virtual void setXY(int16 x, int16 y) = 0;
149 /** Use a specific memory block as video memory. */
150 virtual void setVideoMemory(byte *vidMem, uint16 width, uint16 height) = 0;
151 /** Use an own memory block as video memory. */
152 virtual void setVideoMemory() = 0;
154 /** Double the video's resolution. */
155 virtual void setDoubleMode(bool doubleMode) = 0;
157 /** Play sound (if the video has sound). */
158 virtual void enableSound(Audio::Mixer &mixer) = 0;
159 /** Don't play sound or stop currently playing sound. */
160 virtual void disableSound() = 0;
162 /** Is sound currently playing? */
163 virtual bool isSoundPlaying() const = 0;
165 /** Seek to a specific frame.
167 * @param frame The frame to which to seek.
168 * @param whence The offset from whence the frame is given.
169 * @param restart Restart the video to reach an otherwise inaccessible frame?
171 virtual void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false) = 0;
173 /** Render the next frame. */
174 virtual State nextFrame() = 0;
175 /** Wait for the frame to end. */
176 virtual void waitEndFrame() = 0;
178 /** Copy the current frame.
180 * @param dest The memory to which to copy the current frame.
181 * @param left The x position within the frame.
182 * @param top The y position within the frame.
183 * @param width The width of the area to copy.
184 * @param height The height of the area to copy.
185 * @param x The x position to where to copy.
186 * @param y The y position to where to copy.
187 * @param pitch The buffer's width.
188 * @param transp Which color should be seen as transparent?
190 virtual void copyCurrentFrame(byte *dest,
191 uint16 left, uint16 top, uint16 width, uint16 height,
192 uint16 x, uint16 y, uint16 pitch, int16 transp = -1) = 0;
195 /** Coktel Vision's IMD files.
197 class Imd : public CoktelVideo {
198 public:
199 Imd();
200 ~Imd();
202 uint32 getFeatures() const;
203 uint16 getFlags() const;
205 int16 getX() const;
206 int16 getY() const;
207 int16 getWidth() const;
208 int16 getHeight() const;
210 uint16 getFramesCount() const;
211 uint16 getCurrentFrame() const;
212 int16 getFrameRate() const;
213 uint32 getSyncLag() const;
215 const byte *getPalette() const;
217 bool getFrameCoords(int16 frame,
218 int16 &x, int16 &y, int16 &width, int16 &height);
220 bool hasExtraData(const char *fileName) const;
221 Common::MemoryReadStream *getExtraData(const char *fileName);
223 void setFrameRate(int16 frameRate);
225 bool load(Common::SeekableReadStream &stream);
226 void unload();
228 void setXY(int16 x, int16 y);
229 void setVideoMemory(byte *vidMem, uint16 width, uint16 height);
230 void setVideoMemory();
232 void setDoubleMode(bool doubleMode);
234 void enableSound(Audio::Mixer &mixer);
235 void disableSound();
237 bool isSoundPlaying() const;
239 void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
241 State nextFrame();
242 void waitEndFrame();
244 void copyCurrentFrame(byte *dest,
245 uint16 left, uint16 top, uint16 width, uint16 height,
246 uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
248 protected:
249 enum Command {
250 kCommandNextSound = 0xFF00,
251 kCommandStartSound = 0xFF01,
253 kCommandBreak = 0xFFF0,
254 kCommandBreakSkip0 = 0xFFF1,
255 kCommandBreakSkip16 = 0xFFF2,
256 kCommandBreakSkip32 = 0xFFF3,
257 kCommandBreakMask = 0xFFF8,
259 kCommandPalette = 0xFFF4,
260 kCommandVideoData = 0xFFFC,
262 kCommandJump = 0xFFFD
265 struct Coord {
266 int16 left;
267 int16 top;
268 int16 right;
269 int16 bottom;
270 } PACKED_STRUCT;
272 Common::SeekableReadStream *_stream;
274 // Properties
275 uint16 _version;
276 uint32 _features;
277 uint16 _flags;
279 // Current coordinates
280 int16 _x;
281 int16 _y;
282 int16 _width;
283 int16 _height;
285 // Standard coordinates gives by the header
286 int16 _stdX;
287 int16 _stdY;
288 int16 _stdWidth;
289 int16 _stdHeight;
291 uint16 _framesCount;
292 uint16 _curFrame;
294 uint32 *_framesPos;
295 uint32 _firstFramePos;
296 Coord *_frameCoords;
298 // Buffer for raw frame data
299 byte *_frameData;
300 uint32 _frameDataSize;
301 uint32 _frameDataLen;
303 // Buffer for uncompressed raw frame data
304 byte *_vidBuffer;
305 uint32 _vidBufferSize;
307 byte _palette[768];
309 // Video memory
310 bool _hasOwnVidMem;
311 byte *_vidMem;
312 uint16 _vidMemWidth;
313 uint16 _vidMemHeight;
315 // Sound properties
316 uint16 _soundFlags;
317 int16 _soundFreq;
318 int16 _soundSliceSize;
319 int16 _soundSlicesCount;
320 uint32 _soundSliceLength;
322 // Current sound state
323 bool _hasSound;
324 bool _soundEnabled;
325 uint8 _soundStage; // (0: no sound, 1: loaded, 2: playing)
326 uint32 _skipFrames;
328 Audio::AppendableAudioStream *_audioStream;
329 Audio::SoundHandle _audioHandle;
331 // Current video state
332 int16 _frameRate;
333 uint32 _frameLength;
334 uint32 _lastFrameTime;
336 Audio::Mixer *_mixer;
338 void unsignedToSigned(byte *buffer, int length);
340 void deleteVidMem(bool del = true);
341 void clear(bool del = true);
343 bool loadCoordinates();
344 bool loadFrameTableOffsets(uint32 &framesPosPos, uint32 &framesCoordsPos);
345 bool assessVideoProperties();
346 bool assessAudioProperties();
347 bool loadFrameTables(uint32 framesPosPos, uint32 framesCoordsPos);
349 State processFrame(uint16 frame);
350 uint32 renderFrame(int16 left, int16 top, int16 right, int16 bottom);
351 void deLZ77(byte *dest, byte *src);
353 void renderBlockWhole (byte *dest, const byte *src, int16 width, int16 height,
354 int16 destWidth, int16 destHeight);
355 void renderBlockWhole4X (byte *dest, const byte *src, int16 width, int16 height,
356 int16 destWidth, int16 destHeight);
357 void renderBlockWhole2Y (byte *dest, const byte *src, int16 width, int16 height,
358 int16 destWidth, int16 destHeight);
359 void renderBlockSparse (byte *dest, const byte *src, int16 width, int16 height,
360 int16 destWidth, int16 destHeight);
361 void renderBlockSparse2Y(byte *dest, const byte *src, int16 width, int16 height,
362 int16 destWidth, int16 destHeight);
364 void calcFrameCoords(uint16 frame, State &state);
366 void nextSoundSlice(bool hasNextCmd);
367 bool initialSoundSlice(bool hasNextCmd);
368 void emptySoundSlice(bool hasNextCmd);
370 void videoData(uint32 size, State &state);
373 class Vmd : public Imd {
374 public:
375 Vmd(Graphics::PaletteLUT *palLUT = 0);
376 ~Vmd();
378 bool getFrameCoords(int16 frame,
379 int16 &x, int16 &y, int16 &width, int16 &height);
381 bool hasExtraData(const char *fileName) const;
382 Common::MemoryReadStream *getExtraData(const char *fileName);
384 bool load(Common::SeekableReadStream &stream);
385 void unload();
387 int16 getWidth() const;
389 void setXY(int16 x, int16 y);
391 void setDoubleMode(bool doubleMode);
393 void seekFrame(int32 frame, int16 whence = SEEK_SET, bool restart = false);
395 State nextFrame();
397 protected:
398 enum PartType {
399 kPartTypeSeparator = 0,
400 kPartTypeAudio = 1,
401 kPartTypeVideo = 2,
402 kPartTypeExtraData = 3,
403 kPartType4 = 4,
404 kPartTypeSpeech = 5
407 enum AudioFormat {
408 kAudioFormat8bitDirect = 0,
409 kAudioFormat16bitDPCM = 1,
410 kAudioFormat16bitADPCM = 2
413 struct ExtraData {
414 char name[16];
415 uint32 offset;
416 uint32 size;
417 uint32 realSize;
419 ExtraData();
420 } PACKED_STRUCT;
422 struct Part {
423 PartType type;
424 byte field_1;
425 byte field_E;
426 uint32 size;
427 int16 left;
428 int16 top;
429 int16 right;
430 int16 bottom;
431 uint16 id;
432 byte flags;
434 Part();
435 } PACKED_STRUCT;
437 struct Frame {
438 uint32 offset;
439 Part *parts;
441 Frame();
442 ~Frame();
443 } PACKED_STRUCT;
445 // Tables for the audio decompressors
446 static const uint16 _tableDPCM[128];
447 static const int32 _tableADPCM[];
448 static const int32 _tableADPCMStep[];
450 bool _hasVideo;
451 uint32 _videoCodec;
453 uint32 _frameInfoOffset;
454 uint16 _partsPerFrame;
455 Frame *_frames;
457 Common::Array<ExtraData> _extraData;
459 // Sound properties
460 byte _soundBytesPerSample;
461 byte _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
462 uint32 _soundHeaderSize;
463 uint32 _soundDataSize;
464 AudioFormat _audioFormat;
466 // Video properties
467 bool _externalCodec;
468 byte _blitMode;
469 byte _bytesPerPixel;
470 byte _preScaleX;
471 byte _postScaleX;
472 byte _scaleExternalX;
473 byte *_vidMemBuffer;
475 bool _doubleMode;
477 Graphics::PaletteLUT *_palLUT;
478 Indeo3 *_codecIndeo3;
480 void clear(bool del = true);
482 bool getPartCoords(int16 frame, PartType type,
483 int16 &x, int16 &y, int16 &width, int16 &height);
485 bool assessVideoProperties();
486 bool assessAudioProperties();
487 void readFrameTable(int &numExtraData);
488 void readExtraData();
490 State processFrame(uint16 frame);
491 uint32 renderFrame(int16 &left, int16 &top, int16 &right, int16 &bottom);
493 void renderBlockRLE(byte *dest, const byte *src, int16 width, int16 height,
494 int16 destWidth, int16 destHeight);
496 void deRLE(byte *&destPtr, const byte *&srcPtr, int16 len);
498 inline int32 preScaleX(int32 x) const;
499 inline int32 postScaleX(int32 x) const;
501 void blit(byte *dest, byte *src, int16 width, int16 height);
502 void blit16(byte *dest, byte *src, int16 srcPitch, int16 width, int16 height);
503 void blit24(byte *dest, byte *src, int16 srcPitch, int16 width, int16 height);
505 byte *deDPCM(const byte *data, uint32 &size, int32 init[2]);
506 byte *deADPCM(const byte *data, uint32 &size, int32 init, int32 v28);
508 byte *soundEmpty(uint32 &size);
509 byte *sound8bitDirect(uint32 &size);
510 byte *sound16bitDPCM(uint32 &size);
511 byte *sound16bitADPCM(uint32 &size);
513 uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
514 void emptySoundSlice(uint32 size);
515 void filledSoundSlice(uint32 size);
516 void filledSoundSlices(uint32 size, uint32 mask);
519 } // End of namespace Graphics
521 #endif // GRAPHICS_VIDEO_COKTELVIDEO_H