1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM 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
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.
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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GRIM_SMUSH_DECODER_H
24 #define GRIM_SMUSH_DECODER_H
25 
26 #include "audio/audiostream.h"
27 
28 #include "video/video_decoder.h"
29 
30 #include "graphics/surface.h"
31 
32 namespace Audio {
33 class QueuingAudioStream;
34 }
35 
36 namespace Grim {
37 
38 class Codec48Decoder;
39 class Blocky8;
40 class Blocky16;
41 
42 class SmushDecoder : public Video::VideoDecoder {
43 public:
44 	SmushDecoder();
45 	~SmushDecoder();
46 
getX()47 	int getX() const { return _videoTrack->_x; }
getY()48 	int getY() const { return _videoTrack->_y; }
49 	void setLooping(bool l);
isRewindable()50 	bool isRewindable() const override { return true; }
isSeekable()51 	bool isSeekable() const override { return true; }
52 	bool rewind() override;
53 	bool seekIntern(const Audio::Timestamp &time) override;
54 	bool loadStream(Common::SeekableReadStream *stream) override;
55 
56 protected:
57 	bool readHeader();
58 	void handleFrameDemo();
59 	void handleFrame();
60 	bool handleFramesHeader();
61 	void handleFRME(Common::SeekableReadStream *stream, uint32 size);
62 	void init();
63 	void close() override;
64 	const Graphics::Surface *decodeNextFrame() override;
65 	class SmushVideoTrack : public FixedRateVideoTrack {
66 	public:
67 		SmushVideoTrack(int width, int height, int fps, int numFrames, bool is16Bit);
68 		~SmushVideoTrack();
69 
getWidth()70 		uint16 getWidth() const override { return _width; }
getHeight()71 		uint16 getHeight() const override { return _height; }
getPixelFormat()72 		Graphics::PixelFormat getPixelFormat() const override { return _format; }
getCurFrame()73 		int getCurFrame() const override { return _curFrame; }
setCurFrame(int frame)74 		void setCurFrame(int frame) { _curFrame = frame; }
getFrameCount()75 		int getFrameCount() const override {	return _nbframes; }
getFrameRate()76 		Common::Rational getFrameRate() const override { return _frameRate; }
77 		void setMsPerFrame(int ms);
78 
79 		void finishFrame();
isSeekable()80 		bool isSeekable() const override { return true; }
seek(const Audio::Timestamp & time)81 		bool seek(const Audio::Timestamp &time) override { return true; }
82 		void setFrameStart(int frame);
83 
84 		void handleBlocky16(Common::SeekableReadStream *stream, uint32 size);
85 		void handleFrameObject(Common::SeekableReadStream *stream, uint32 size);
86 		void handleDeltaPalette(Common::SeekableReadStream *stream, int32 size);
87 		void init();
88 		Graphics::Surface *decodeNextFrame() override;
89 
getPal()90 		byte *getPal() { return _pal; }
91 		int _x, _y;
92 	private:
93 		void convertDemoFrame();
94 		bool _is16Bit;
95 		int32 _curFrame;
96 		byte _pal[0x300];
97 		int16 _deltaPal[0x300];
98 		int _width, _height;
99 		Graphics::Surface _surface;
100 		Graphics::PixelFormat _format;
101 		Common::Rational _frameRate;
102 		Blocky8 *_blocky8;
103 		Blocky16 *_blocky16;
104 		Codec48Decoder *_codec48;
105 		int32 _nbframes;
106 		int _frameStart;
107 	};
108 
109 	class SmushAudioTrack : public AudioTrack {
110 	public:
111 		SmushAudioTrack(Audio::Mixer::SoundType soundType, bool isVima, int freq = 22050, int channels = -1);
112 		~SmushAudioTrack();
113 
getAudioStream()114 		Audio::AudioStream *getAudioStream() const override { return _queueStream; }
isSeekable()115 		bool isSeekable() const override { return true; }
116 		bool seek(const Audio::Timestamp &time) override;
117 		void skipSamples(int samples);
getRate()118 		inline int getRate() const { return _queueStream->getRate(); }
119 
120 		void handleVIMA(Common::SeekableReadStream *stream, uint32 size);
121 		void handleIACT(Common::SeekableReadStream *stream, int32 size);
122 		void init();
123 	private:
124 		bool _isVima;
125 		byte _IACToutput[4096];
126 		int32 _IACTpos;
127 		int _channels;
128 		int _freq;
129 		Audio::QueuingAudioStream *_queueStream;
130 	};
131 private:
132 	void initFrames();
133 
134 	SmushAudioTrack *_audioTrack;
135 	SmushVideoTrack *_videoTrack;
136 
137 	Common::SeekableReadStream *_file;
138 
139 	uint32 _startPos;
140 
141 	bool _videoPause;
142 	bool _videoLooping;
143 	struct Frame {
144 		int frame;
145 		int pos;
146 		bool keyframe;
147 	};
148 	Frame *_frames;
149 	static bool _demo;
150 };
151 
152 } // end of namespace Grim
153 
154 #endif
155