Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

coktelvideo.h

/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/engines/gob/coktelvideo.h $
 * $Id: coktelvideo.h 30944 2008-02-23 22:50:18Z sev $
 *
 */

#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. */
00036 class CoktelVideo {
public:
00038       enum Features {
            kFeaturesNone = 0,
            /** Has an own palette. */
00041             kFeaturesPalette = 8,
            /** Suggests a data size. */
00043             kFeaturesDataSize = 0x20,
            /** Has sound. */
00045             kFeaturesSound = 0x40,
            /** Has specific frame coordinates. */
00047             kFeaturesFrameCoords = 0x80,
            /** Has general standard coordinates. */
00049             kFeaturesStdCoords = 0x100,
            /** Has a frame positions table. */
00051             kFeaturesFramesPos = 0x200,
            /** Has video. */
00053             kFeaturesVideo = 0x400
      };

00056       enum StateFlags {
            kStateNone = 0,
            /** Changed the palette. */
00059             kStatePalette = 0x10,
            /** Performed a jump to another frame. */
00061             kStateJump = 0x200,
            /** Updated according to the specific frame coordinates. */
00063             kStateFrameCoords = 0x400,
            /** Got no frame data. */
00065             kStateNoVideoData = 0x800,
            /** Updated according to the general standard coordinates. */
00067             kStateStdCoords = 0x1000,
            /** Had to explicitely seek to the frame. */
00069             kStateSeeked = 0x2000,
            /** Reached a break-point. */
00071             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.
 */
00159 class Imd : public CoktelVideo {
public:
      Imd();
      ~Imd();

00164       uint16 getFeatures() const { return _features; }
00165       int16 getX() const { return _x; }
00166       int16 getY() const { return _y; }
00167       int16 getWidth() const { return _width; }
00168       int16 getHeight() const { return _height; }
00169       uint16 getFramesCount() const { return _framesCount; }
00170       uint16 getCurrentFrame() const { return _curFrame; }
00171       int16 getFrameRate() const { if (_hasSound) return 1000 / _soundSliceLength; return 12; }
00172       uint32 getSyncLag() const { return _skipFrames; }
00173       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

Generated by  Doxygen 1.6.0   Back to index