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.
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"
39 /** Common interface for handling Coktel Vision videos and derivated formats. */
44 /** Has an own palette. */
46 /** Suggests a data size. */
47 kFeaturesDataSize
= 0x20,
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,
57 kFeaturesVideo
= 0x400,
58 /** Is a full color (non-paletted) video. */
59 kFeaturesFullColor
= 0x4000,
60 /** Supports automatic doubling. */
61 kFeaturesSupportsDouble
= 0x40000000
66 /** Changed the palette. */
68 /** Performed a jump to another frame. */
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. */
80 /** Frame marks the beginning of speech. */
81 kStateSpeech
= 0x4000000
85 /** Left-most value of the updated rectangle. */
87 /** Top-most value of the updated rectangle. */
89 /** Right-most value of the updated rectangle. */
91 /** Bottom-most value of the updated rectangle. */
93 /** Set accordingly to what was done. */
95 /** The id of the spoken words. */
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
{
202 uint32
getFeatures() const;
203 uint16
getFlags() 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
);
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
);
237 bool isSoundPlaying() const;
239 void seekFrame(int32 frame
, int16 whence
= SEEK_SET
, bool restart
= false);
244 void copyCurrentFrame(byte
*dest
,
245 uint16 left
, uint16 top
, uint16 width
, uint16 height
,
246 uint16 x
, uint16 y
, uint16 pitch
, int16 transp
= -1);
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
272 Common::SeekableReadStream
*_stream
;
279 // Current coordinates
285 // Standard coordinates gives by the header
295 uint32 _firstFramePos
;
298 // Buffer for raw frame data
300 uint32 _frameDataSize
;
301 uint32 _frameDataLen
;
303 // Buffer for uncompressed raw frame data
305 uint32 _vidBufferSize
;
313 uint16 _vidMemHeight
;
318 int16 _soundSliceSize
;
319 int16 _soundSlicesCount
;
320 uint32 _soundSliceLength
;
322 // Current sound state
325 uint8 _soundStage
; // (0: no sound, 1: loaded, 2: playing)
328 Audio::AppendableAudioStream
*_audioStream
;
329 Audio::SoundHandle _audioHandle
;
331 // Current video state
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
{
375 Vmd(Graphics::PaletteLUT
*palLUT
= 0);
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
);
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);
399 kPartTypeSeparator
= 0,
402 kPartTypeExtraData
= 3,
408 kAudioFormat8bitDirect
= 0,
409 kAudioFormat16bitDPCM
= 1,
410 kAudioFormat16bitADPCM
= 2
445 // Tables for the audio decompressors
446 static const uint16 _tableDPCM
[128];
447 static const int32 _tableADPCM
[];
448 static const int32 _tableADPCMStep
[];
453 uint32 _frameInfoOffset
;
454 uint16 _partsPerFrame
;
457 Common::Array
<ExtraData
> _extraData
;
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
;
472 byte _scaleExternalX
;
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