ScummVM API documentation
coktel_decoder.h
1/* ScummVM - Graphic Adventure Engine
2 *
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.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *
21 * This file is dual-licensed.
22 * In addition to the GPLv3 license mentioned above, this code is also
23 * licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
24 * full text of the license.
25 *
26 */
27
28// Currently, only GOB and SCI32 games play IMDs and VMDs, so skip compiling if GOB and SCI32 is disabled.
29#if !(defined(ENABLE_GOB) || defined(ENABLE_SCI32) || defined(DYNAMIC_MODULES))
30
31// Do not compile the CoktelDecoder code
32
33#else
34
35#ifndef VIDEO_COKTELDECODER_H
36#define VIDEO_COKTELDECODER_H
37
38#include "common/list.h"
39#include "common/array.h"
40#include "common/rational.h"
41#include "common/str.h"
42
43#include "graphics/palette.h"
44#include "graphics/surface.h"
45
46#include "video/video_decoder.h"
47
48#include "audio/mixer.h"
49
50namespace Common {
51struct Rect;
52class MemoryReadWriteStream;
53class SeekableReadStream;
54}
55namespace Audio {
56class QueuingAudioStream;
57}
58
59namespace Graphics {
60struct PixelFormat;
61}
62
63namespace Image {
64class Codec;
65}
66
67namespace Video {
68
76class CoktelDecoder {
77public:
78 struct State {
80 uint32 flags;
82 uint16 speechId;
83
84 State();
85 };
86
87 CoktelDecoder(Audio::Mixer *mixer,
89 virtual ~CoktelDecoder();
90
92 virtual bool reloadStream(Common::SeekableReadStream *stream) = 0;
93
94 virtual bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) = 0;
95
97 void setSurfaceMemory(void *mem, uint16 width, uint16 height, uint8 bpp);
99 void setSurfaceMemory();
100
101 const Graphics::Surface *getSurface() const;
102
104 virtual void setXY(uint16 x, uint16 y);
106 void setXY();
107
109 void setFrameRate(Common::Rational frameRate);
111 Common::Rational getFrameRate() const;
112
114 uint16 getDefaultX() const;
116 uint16 getDefaultY() const;
117
119 const Common::List<Common::Rect> &getDirtyRects() const;
120
121 bool hasPalette() const;
122 virtual bool hasVideo() const;
123 virtual bool hasVideoData() const;
124
125 bool hasSound() const;
126 bool isSoundEnabled() const;
127 bool isSoundPlaying() const;
128
129 void enableSound();
130 void disableSound();
131 void finishSound();
132
133 virtual void colorModeChanged();
134
136 virtual bool getFrameCoords(int16 frame, int16 &x, int16 &y, int16 &width, int16 &height);
137
139 virtual bool hasEmbeddedFiles() const;
140
142 virtual bool hasEmbeddedFile(const Common::String &fileName) const;
143
145 virtual Common::SeekableReadStream *getEmbeddedFile(const Common::String &fileName) const;
146
148 virtual int32 getSubtitleIndex() const;
149
151 virtual bool isPaletted() const;
152
153 virtual uint32 getVideoBufferSize() const = 0;
154
159 int getCurFrame() const;
160 int getNbFramesPastEnd() const;
161
166 virtual const Graphics::Surface *decodeNextFrame() = 0;
167
172 virtual bool loadStream(Common::SeekableReadStream *stream) = 0;
173
175 virtual bool isVideoLoaded() const = 0;
176
178 bool endOfVideo() const;
179
181 void close();
182
184 Audio::Mixer::SoundType getSoundType() const;
186 Audio::AudioStream *getAudioStream() const;
187
188 uint16 getWidth() const;
189 uint16 getHeight() const;
190 virtual uint32 getFlags() const = 0;
191 virtual uint16 getSoundFlags() const = 0;
192 virtual Graphics::PixelFormat getPixelFormat() const = 0;
193
194 uint32 getFrameCount() const;
195
196 const byte *getPalette();
197 bool hasDirtyPalette() const;
198
199 uint32 getTimeToNextFrame() const;
200 uint32 getStaticTimeToNextFrame() const;
201 int32 getExpectedFrameFromCurrentTime() const;
202
203 void pauseVideo(bool pause);
204
205protected:
206 enum SoundStage {
207 kSoundNone = 0,
208 kSoundLoaded = 1,
209 kSoundPlaying = 2,
210 kSoundFinished = 3
211 };
212
213 enum Features {
214 kFeaturesNone = 0x0000,
215 kFeaturesPalette = 0x0008,
216 kFeaturesDataSize = 0x0020,
217 kFeaturesSound = 0x0040,
218 kFeaturesFrameCoords = 0x0080,
219 kFeaturesStdCoords = 0x0100,
220 kFeaturesFramePos = 0x0200,
221 kFeaturesVideo = 0x0400
222 };
223
224 Audio::Mixer *_mixer;
225 Audio::Mixer::SoundType _soundType;
226
227 uint16 _width;
228 uint16 _height;
229
230 uint16 _x;
231 uint16 _y;
232
233 uint16 _defaultX;
234 uint16 _defaultY;
235
236 uint32 _features;
237
238 int32 _curFrame;
239 int32 _nbFramesPastEnd;
240 uint32 _frameCount;
241
242 uint32 _startTime;
243
244 Graphics::Palette _palette;
245 bool _paletteDirty;
246
247 bool _ownSurface;
248 Graphics::Surface _surface;
249
250 Common::List<Common::Rect> _dirtyRects;
251
252 Common::Rational _frameRate;
253
254 // Current sound state
255 bool _hasSound;
256 bool _soundEnabled;
257 SoundStage _soundStage;
258
259 Audio::QueuingAudioStream *_audioStream;
260 Audio::SoundHandle _audioHandle;
261
262 bool evaluateSeekFrame(int32 &frame, int whence) const;
263
264 // Surface management
265 bool hasSurface();
266 void createSurface();
267 void freeSurface();
268
269 // Decompression
270 uint32 deLZ77(byte *dest, const byte *src, uint32 srcSize, uint32 destSize);
271 void deRLE(byte *&destPtr, const byte *&srcPtr, int16 destLen, int16 srcLen);
272
273 // Block rendering
274 void renderBlockWhole (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
275 void renderBlockWhole4X (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
276 void renderBlockWhole2Y (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
277 void renderBlockSparse (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
278 void renderBlockSparse2Y (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
279 void renderBlockRLE (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
280
281 // Sound helper functions
282 inline void unsignedToSigned(byte *buffer, int length);
283
284private:
285 uint32 _pauseStartTime;
286 bool _isPaused;
287};
288
289class PreIMDDecoder : public CoktelDecoder {
290public:
291 PreIMDDecoder(uint16 width, uint16 height, Audio::Mixer *mixer,
293 ~PreIMDDecoder();
294
295 bool reloadStream(Common::SeekableReadStream *stream) override;
296
297 bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) override;
298
299 bool loadStream(Common::SeekableReadStream *stream) override;
300 void close();
301
302 bool isVideoLoaded() const override;
303
304 const Graphics::Surface *decodeNextFrame() override;
305
306 uint32 getFlags() const override;
307 uint16 getSoundFlags() const override;
308 uint32 getVideoBufferSize() const override;
309
310 Graphics::PixelFormat getPixelFormat() const override;
311
312private:
314
315 // Buffer for processed frame data
316 byte *_videoBuffer;
317 uint32 _videoBufferSize;
318
319 // Frame decoding
320 void processFrame();
321 void renderFrame();
322};
323
324class IMDDecoder : public CoktelDecoder {
325public:
327 ~IMDDecoder();
328
329 bool reloadStream(Common::SeekableReadStream *stream) override;
330
331 bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) override;
332
333 void setXY(uint16 x, uint16 y) override;
334
335 bool loadStream(Common::SeekableReadStream *stream) override;
336 void close();
337
338 bool isVideoLoaded() const override;
339
340 const Graphics::Surface *decodeNextFrame() override;
341
342 uint32 getFlags() const override;
343 uint16 getSoundFlags() const override;
344 uint32 getVideoBufferSize() const override;
345
346 Graphics::PixelFormat getPixelFormat() const override;
347
348private:
349 enum Command {
350 kCommandNextSound = 0xFF00,
351 kCommandStartSound = 0xFF01,
352
353 kCommandBreak = 0xFFF0,
354 kCommandBreakSkip0 = 0xFFF1,
355 kCommandBreakSkip16 = 0xFFF2,
356 kCommandBreakSkip32 = 0xFFF3,
357 kCommandBreakMask = 0xFFF8,
358
359 kCommandPalette = 0xFFF4,
360 kCommandVideoData = 0xFFFC,
361
362 kCommandJump = 0xFFFD
363 };
364
365 struct Coord {
366 int16 left;
367 int16 top;
368 int16 right;
369 int16 bottom;
370 };
371
373
374 byte _version;
375
376 // Standard coordinates gives by the header
377 int16 _stdX;
378 int16 _stdY;
379 int16 _stdWidth;
380 int16 _stdHeight;
381
382 uint32 _flags;
383
384 uint32 _firstFramePos;
385 uint32 *_framePos;
386 Coord *_frameCoords;
387
388 uint32 _videoBufferSize;
389 byte *_videoBuffer[2];
390 uint32 _videoBufferLen[2];
391
392 // Sound properties
393 uint16 _soundFlags;
394 int16 _soundFreq;
395 int16 _soundSliceSize;
396 int16 _soundSlicesCount;
397
398 // Loading helper functions
399 bool loadCoordinates();
400 bool loadFrameTableOffsets(uint32 &framePosPos, uint32 &frameCoordsPos);
401 bool assessVideoProperties();
402 bool assessAudioProperties();
403 bool loadFrameTables(uint32 framePosPos, uint32 frameCoordsPos);
404
405 // Frame decoding
406 void processFrame();
407 Common::Rect calcFrameCoords(uint32 frame);
408
409 // Video
410 bool renderFrame(Common::Rect &rect);
411
412 // Sound
413 void nextSoundSlice(bool hasNextCmd);
414 bool initialSoundSlice(bool hasNextCmd);
415 void emptySoundSlice(bool hasNextCmd);
416};
417
418class VMDDecoder : public CoktelDecoder {
419friend class AdvancedVMDDecoder;
420
421public:
423 ~VMDDecoder();
424
425 bool reloadStream(Common::SeekableReadStream *stream) override;
426
427 bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) override;
428
429 void setXY(uint16 x, uint16 y) override;
430
431 void colorModeChanged() override;
432
433 bool getFrameCoords(int16 frame, int16 &x, int16 &y, int16 &width, int16 &height) override;
434
435 bool hasEmbeddedFiles() const override;
436 bool hasEmbeddedFile(const Common::String &fileName) const override;
437 Common::SeekableReadStream *getEmbeddedFile(const Common::String &fileName) const override;
438
439 int32 getSubtitleIndex() const override;
440
441 bool hasVideo() const override;
442 bool hasVideoData() const override;
443 bool isPaletted() const override;
444
445 bool loadStream(Common::SeekableReadStream *stream) override;
446 void close();
447
448 bool isVideoLoaded() const override;
449
450 const Graphics::Surface *decodeNextFrame() override;
451
452 uint32 getFlags() const override;
453 uint16 getSoundFlags() const override;
454 uint32 getVideoBufferSize() const override;
455
456 Graphics::PixelFormat getPixelFormat() const override;
457
458protected:
459 void setAutoStartSound(bool autoStartSound);
460
461private:
462 enum PartType {
463 kPartTypeSeparator = 0,
464 kPartTypeAudio = 1,
465 kPartTypeVideo = 2,
466 kPartTypeFile = 3,
467 kPartType4 = 4,
468 kPartTypeSubtitle = 5
469 };
470
471 enum AudioFormat {
472 kAudioFormat8bitRaw = 0,
473 kAudioFormat16bitDPCM = 1,
474 kAudioFormat16bitADPCM = 2
475 };
476
477 struct File {
478 Common::String name;
479
480 uint32 offset;
481 uint32 size;
482 uint32 realSize;
483
484 File();
485 };
486
487 struct Part {
488 PartType type;
489 byte field_1;
490 byte field_E;
491 uint32 size;
492 int16 left;
493 int16 top;
494 int16 right;
495 int16 bottom;
496 uint16 id;
497 byte flags;
498
499 Part();
500 };
501
502 struct Frame {
503 uint32 offset;
504 Part *parts;
505
506 Frame();
507 ~Frame();
508 };
509
511
512 byte _version;
513 uint32 _flags;
514
515 uint32 _frameInfoOffset;
516 uint16 _partsPerFrame;
517 Frame *_frames;
518
519 Common::Array<File> _files;
520
521 // Sound properties
522 uint16 _soundFlags;
523 uint16 _soundFreq;
524 int16 _soundSliceSize;
525 int16 _soundSlicesCount;
526 byte _soundBytesPerSample;
527 byte _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
528 uint32 _soundHeaderSize;
529 uint32 _soundDataSize;
530 uint32 _soundLastFilledFrame;
531 AudioFormat _audioFormat;
532 bool _autoStartSound;
533
543 Common::MemoryReadWriteStream *_oldStereoBuffer;
544
545 // Video properties
546 bool _hasVideo;
547 bool _hasVideoData;
548 uint32 _videoCodec;
549 byte _blitMode;
550 byte _bytesPerPixel;
551
552 uint32 _firstFramePos;
553
554 uint32 _videoBufferSize;
555 byte *_videoBuffer[3];
556 uint32 _videoBufferLen[3];
557
558 Graphics::Surface _8bppSurface[3];
559
560 bool _externalCodec;
561 Image::Codec *_codec;
562
563 int32 _subtitle;
564
565 bool _isPaletted;
566
567 // Loading helper functions
568 bool assessVideoProperties();
569 bool assessAudioProperties();
570 bool openExternalCodec();
571 bool readFrameTable(int &numFiles);
572 bool readFiles();
573
574 // Frame decoding
575 void processFrame();
576
577 // Video
578 bool renderFrame(Common::Rect &rect);
579 bool getRenderRects(const Common::Rect &rect,
580 Common::Rect &realRect, Common::Rect &fakeRect);
581 void blit16(const Graphics::Surface &srcSurf, Common::Rect &rect);
582 void blit24(const Graphics::Surface &srcSurf, Common::Rect &rect);
583
584 // Sound
585 void emptySoundSlice (uint32 size);
586 void filledSoundSlice (uint32 size);
587 void filledSoundSlices(uint32 size, uint32 mask);
588 void createAudioStream();
589
590 uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
591
592 // Generating audio streams
593 Audio::AudioStream *create8bitRaw (Common::SeekableReadStream *stream);
594 Audio::AudioStream *create16bitDPCM (Common::SeekableReadStream *stream);
595 Audio::AudioStream *create16bitADPCM(Common::SeekableReadStream *stream);
596
597 bool getPartCoords(int16 frame, PartType type, int16 &x, int16 &y, int16 &width, int16 &height);
598};
599
604class AdvancedVMDDecoder : public VideoDecoder {
605public:
606 AdvancedVMDDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
607 ~AdvancedVMDDecoder();
608
609 bool loadStream(Common::SeekableReadStream *stream) override;
610 void close() override;
611
612 void setSurfaceMemory(void *mem, uint16 width, uint16 height, uint8 bpp);
613
614private:
615 class VMDVideoTrack : public FixedRateVideoTrack {
616 public:
617 VMDVideoTrack(VMDDecoder *decoder);
618
619 uint16 getWidth() const override;
620 uint16 getHeight() const override;
621 Graphics::PixelFormat getPixelFormat() const override;
622 int getCurFrame() const override;
623 int getFrameCount() const override;
624 const Graphics::Surface *decodeNextFrame() override;
625 const byte *getPalette() const override;
626 bool hasDirtyPalette() const override;
627
628 protected:
629 Common::Rational getFrameRate() const override;
630
631 private:
632 VMDDecoder *_decoder;
633 };
634
635 class VMDAudioTrack : public AudioTrack {
636 public:
637 VMDAudioTrack(VMDDecoder *decoder);
638
639 protected:
640 Audio::AudioStream *getAudioStream() const override;
641
642 private:
643 VMDDecoder *_decoder;
644 };
645
646 VMDDecoder *_decoder;
647 VMDVideoTrack *_videoTrack;
648 VMDAudioTrack *_audioTrack;
649};
650
651} // End of namespace Video
652
653#endif // VIDEO_COKTELDECODER_H
654
655#endif // Engine and dynamic plugins guard
Definition: audiostream.h:50
Definition: mixer.h:70
SoundType
Definition: mixer.h:73
@ kPlainSoundType
Definition: mixer.h:74
Definition: audiostream.h:370
Definition: mixer.h:49
Definition: array.h:52
Definition: memstream.h:283
Definition: rational.h:40
Definition: stream.h:745
Definition: str.h:59
Simple class for handling a palette data.
Definition: palette.h:61
Definition: codec.h:57
Definition: system.h:39
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: rect.h:536
Definition: pixelformat.h:138
Definition: surface.h:67