ScummVM API documentation
smush_player.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
22#if !defined(SCUMM_SMUSH_PLAYER_H) && defined(ENABLE_SCUMM_7_8)
23#define SCUMM_SMUSH_PLAYER_H
24
25#include "common/util.h"
26#include "common/list.h"
27#include "common/rect.h"
28#include "scumm/charset_v7.h"
29#include "scumm/smush/saud.h"
30
31namespace Audio {
32class SoundHandle;
33class QueuingAudioStream;
34}
35
36namespace Scumm {
37
38#define SMUSH_MAX_TRACKS 4
39#define SMUSH_FADE_SIZE 0xC00
40
41#define IS_SFX 0x00
42#define IS_BKG_MUSIC 0x40
43#define IS_SPEECH 0x80
44
45#define CHN_BKGMUS 1
46#define CHN_SPEECH 2
47#define CHN_OTHER 3
48
49#define GRP_MASTER 0xFF01
50#define GRP_SFX 0xFF02
51#define GRP_BKGMUS 0xFF03
52#define GRP_SPEECH 0xFF04
53
54#define TRK_STATE_INACTIVE 0
55#define TRK_STATE_PLAYING 1
56#define TRK_STATE_FADING 2
57#define TRK_STATE_ENDING 3
58
59#define TRK_TYPE_MASK 0xC0
60
61#define TRK_USERID_SPEECH 1
62#define TRK_USERID_MUSIC 2
63#define TRK_USERID_SFX 3
64
65#define SMUSH_CODEC_RLE 1
66#define SMUSH_CODEC_RA1_SCATTER 2 // RA1: Scatter/point draw (starfield)
67#define SMUSH_CODEC_RLE_ALT 3
68#define SMUSH_CODEC_RA1_DELTA 4 // RA1: Delta block codec (skip on idx 0x80)
69#define SMUSH_CODEC_RA1_BLOCK 5 // RA1: Block-based frame codec (no skip)
70#define SMUSH_CODEC_UNCOMPRESSED 20
71#define SMUSH_CODEC_LINE_UPDATE 21 // RA2: Skip/copy with literal pixels
72#define SMUSH_CODEC_SKIP_RLE 23 // RA1: additive line-update overlay; RA2: skip/copy with embedded RLE
73#define SMUSH_CODEC_DELTA_BLOCKS 37
74#define SMUSH_CODEC_LINE_UPDATE2 44 // RA2: Variant of codec 21
75
76#define SMUSH_CODEC_SEGACD_RLE 31 // RA1 Sega CD: transparent 4bpp line RLE
77#define SMUSH_CODEC_SEGACD_OPAQUE 32 // RA1 Sega CD: opaque 4bpp line RLE
78#define SMUSH_CODEC_SEGACD_BLOCK33 33 // RA1 Sega CD: codec 4 with Sega glyph table
79#define SMUSH_CODEC_SEGACD_BLOCK34 34 // RA1 Sega CD: codec 5 with Sega glyph table and no skip glyph
80#define SMUSH_CODEC_RA2_BOMP 45 // RA2: BOMP RLE with variable header
81#define SMUSH_CODEC_DELTA_GLYPHS 47
82
83class ScummEngine_v7;
84class SmushFont;
85class SmushMultiFont;
86class SmushMixer;
87class StringResource {
88public:
89 virtual ~StringResource() {}
90 virtual const char *get(int id) = 0;
91};
92class SmushDeltaBlocksDecoder;
93class SmushDeltaGlyphsDecoder;
94class IMuseDigital;
95class Insane;
96class RebelAudio;
97class SmushPlayerRebel1;
98class SmushPlayerRebel2;
99
100class SmushPlayer {
101 friend class Insane;
102 friend class InsaneRebel1;
103 friend class InsaneRebel2;
104 friend class RebelAudio;
105 friend class SmushPlayerRebel1;
106 friend class SmushPlayerRebel2;
107 friend class SmushMultiFont;
108private:
109 struct SmushAudioDispatch {
110 uint8 *headerPtr;
111 uint8 *dataBuf;
112 int32 dataSize;
113 int32 audioRemaining;
114 int32 currentOffset;
115 int sampleRate;
116 int state;
117 int fadeSampleRate;
118 int fadeVolume;
119 int32 fadeRemaining;
120 int volumeStep;
121 int32 elapsedAudio;
122 int32 audioLength;
123 };
124
125 struct SmushAudioTrack {
126 uint8 *blockPtr;
127 uint8 *fadeBuf;
128 uint8 *dataBuf;
129 uint8 *subChunkPtr;
130 int32 blockSize;
131 byte volume;
132 byte pan;
133 int16 state;
134 int16 flags;
135 int groupId;
136 int parsedChunks;
137 int32 dataSize;
138 int32 availableSize;
139 int32 audioRemaining;
140 int32 sdatSize;
141 };
142
143 ScummEngine_v7 *_vm;
144 IMuseDigital *_imuseDigital;
145 Insane *_insane;
146 int32 _nbframes;
147 int16 _deltaPal[0x300];
148 int32 _shiftedDeltaPal[0x300];
149 byte _pal[0x300];
150 SmushFont *_sf[5];
151 SmushMultiFont *_multiFont; // Multi-font renderer for inline font switching
152 StringResource *_strings;
153 SmushDeltaBlocksDecoder *_deltaBlocksCodec;
154 SmushDeltaGlyphsDecoder *_deltaGlyphsCodec;
156 uint32 _baseSize;
157 byte *_frameBuffer;
158 byte *_specialBuffer;
159 int _specialBufferSize;
160
161 // RA1/RA2: Raw FOBJ data stored by STOR chunk for later re-decoding by FTCH.
162 byte *_storedFobjData;
163 int32 _storedFobjDataSize;
164 int _storedFobjCodec;
165 uint16 _storedFobjParm2;
166 int _storedFobjLeft;
167 int _storedFobjTop;
168 int _storedFobjWidth;
169 int _storedFobjHeight;
170
171 // RA1/RA2: Most recently decoded FOBJ in the current frame, used by GOST
172 // chunks to re-render the same sprite payload at a different position.
173 byte *_lastFobjData;
174 int32 _lastFobjDataSize;
175 int _lastFobjCodec;
176 int _lastFobjLeft;
177 int _lastFobjTop;
178 int _lastFobjWidth;
179 int _lastFobjHeight;
180 bool _hasFrameFobjForGost;
181
182 // RA2: Global FOBJ position offsets.
183 // Set by InsaneRebel2 during IACT opcode 6 processing, reset in procPostRendering.
184 int16 _fobjOffsetX;
185 int16 _fobjOffsetY;
186
187 Common::String _seekFile;
188 uint32 _startFrame;
189 uint32 _startTime;
190 int32 _seekPos;
191 uint32 _seekFrame;
192
193 bool _skipNext;
194 uint32 _frame;
195 uint32 _fastForwardFromFrame;
196 uint32 _fastForwardToFrame;
197 bool _preserveVideoStateOnNextPlay;
198 bool _preserveGameVideoStateOnRelease;
199
200 Audio::SoundHandle *_IACTchannel;
201 Audio::QueuingAudioStream *_IACTstream;
202
203 Audio::SoundHandle *_compressedFileSoundHandle;
204 bool _compressedFileMode;
205 byte _IACToutput[4096];
206 int32 _IACTpos;
207 bool _storeFrame;
208 int _speed;
209 bool _endOfFile;
210
211 byte *_dst;
212 bool _updateNeeded;
213 bool _warpNeeded;
214 int _palDirtyMin, _palDirtyMax;
215 int _warpX, _warpY;
216 int _warpButtons;
217 bool _insanity;
218 bool _middleAudio;
219 bool _skipPalette;
220 int _iactTable[4];
221
222 SmushAudioTrack _smushTracks[SMUSH_MAX_TRACKS];
223 SmushAudioDispatch _smushDispatch[SMUSH_MAX_TRACKS];
224
225 int _smushMaxFrames[SMUSH_MAX_TRACKS];
226 int _smushTrackIds[SMUSH_MAX_TRACKS];
227 int _smushTrackIdxs[SMUSH_MAX_TRACKS];
228 uint8 _smushAudioTable[256];
229 int _smushNumTracks;
230 int _smushTrackFlags[SMUSH_MAX_TRACKS];
231 int _smushTrackVols[SMUSH_MAX_TRACKS];
232
233 int _smushAudioSampleRate;
234 int _gainReductionLowerBound;
235 int _gainReductionFactor;
236 int _gainReductionMultiplier;
237
238 bool _smushTracksNeedInit;
239 bool _smushAudioInitialized;
240 bool _smushAudioCallbackEnabled;
241
242public:
243 SmushPlayer(ScummEngine_v7 *scumm, IMuseDigital *_imuseDigital, Insane *insane);
244 virtual ~SmushPlayer();
245
246 void pause();
247 virtual void unpause();
248
249 void play(const char *filename, int32 speed, int32 offset = 0, int32 startFrame = 0);
250 void release();
251 void warpMouse(int x, int y, int buttons);
252 int setChanFlag(int id, int flagVal);
253 void setGroupVolume(int groupId, int volValue);
254 void processDispatches(int16 feedSize);
255 bool isAudioCallbackEnabled();
256 byte *getVideoPalette();
257 void setCurVideoFlags(int16 flags);
258 SmushMultiFont *getMultiFont() const { return _multiFont; }
259 void ensureMultiFont();
260 bool isFastForwardingCurrentFrame() const;
261 void setPreserveVideoStateOnNextPlay(bool preserve) { _preserveVideoStateOnNextPlay = preserve; }
262 void setPreserveGameVideoStateOnRelease(bool preserve) { _preserveGameVideoStateOnRelease = preserve; }
263 void setFastForwardFromFrame(uint32 frame) { _fastForwardFromFrame = frame; }
264 void setFastForwardToFrame(uint32 frame) { _fastForwardToFrame = frame; }
265
266 // Masked regions - areas where video should not update (e.g., destroyed enemies)
267 // The Insane class can add/remove regions, and decodeFrameObject will restore
268 // these areas from the previous frame after decoding
269 void addMaskedRegion(const Common::Rect &rect);
270 void removeMaskedRegion(const Common::Rect &rect);
271 void clearMaskedRegions();
272 Common::List<Common::Rect> _maskedRegions;
273
274
275protected:
276 int _width, _height;
277
278 int _origPitch, _origNumStrips;
279 bool _paused;
280 uint32 _pauseStartTime;
281 uint32 _pauseTime;
282 int16 _curVideoFlags = 0;
283 int _scrollX;
284 int _scrollY;
285
286 void insanity(bool);
287 void setPalette(const byte *palette);
288 void setPaletteValue(int n, byte r, byte g, byte b);
289 void setDirtyColors(int min, int max);
290 void setScrollOffset(int x, int y);
291 void seekSan(const char *file, int32 pos, int32 contFrame);
292 const char *getString(int id);
293 virtual void initGamePlayerFields() {}
294 virtual void destroyGamePlayerFields() {}
295 virtual void resetGameVideoState() {}
296 virtual void initGameVideoState() {}
297 virtual void releaseGameVideoState() {}
298 virtual bool shouldPreserveFrameBuffer() const { return false; }
299 virtual bool handleGameFetch(int32 subSize, Common::SeekableReadStream &b) { return false; }
300 virtual bool handleGameTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &b) { return false; }
301 virtual bool handleGameTextRendering(const char *str, int fontId, int color, int pos_x, int pos_y, int left, int top, int width, int height, TextStyleFlags flg) { return false; }
302 virtual bool shouldAlwaysShowSubtitles() const { return false; }
303 virtual SmushFont *getGameFont(int font) { return nullptr; }
304 virtual void adjustGamePalette() {}
305 virtual bool shouldLoadAnimHeaderPalette() const { return true; }
306 virtual bool handleGameAnimHeader(byte *headerContent) { return false; }
307 virtual bool handleGameSetupStrings() { return false; }
308 virtual void handleGameParseNextFrame() {}
309 virtual bool shouldRouteAllIACTs() const { return false; }
310 virtual bool handleGameFrameBufferSelect(int codec, int width, int height) { return false; }
311 virtual bool handleGameDimensionOverride(int codec, int width, int height) { return false; }
312 virtual int handleGameFrameObjectPitch(int pitch) { return pitch; }
313 virtual bool handleGameAdjustCoords(int codec, int &left, int &top, int &width, int &height, int pitch, int *srcSkipY) { return false; }
314 virtual bool handleGameCodecDecode(int codec, const uint8 *src, int left, int top, int width, int height, int pitch, int dataSize, uint8 param = 0, uint16 parm2 = 0) { return false; }
315 virtual bool handleGameStoreFrame() { return false; }
316 virtual void handleGameFrameObjectPre(int codec, int left, int top, int width, int height, int dataSize) {}
317 virtual void handleGameFrameObjectPost(int codec, const byte *data, int32 dataSize, int left, int top, int width, int height) {}
318 virtual void handleGameFrameObjectDecoded(int codec, int left, int top, int width, int height) {}
319 virtual void handleGameFrameStart() {}
320 virtual bool handleGameSkipChunk(uint32 subType, int32 subSize, Common::SeekableReadStream &b) { return false; }
321 virtual void handleGameGost(int32 subSize, Common::SeekableReadStream &b) {}
322 virtual void handleGameProcessAudio(int16 feedSize) {}
323 virtual bool isInsaneGame() const { return false; }
324 virtual void handleGameLoad(int32 subSize, Common::SeekableReadStream &b) {}
325 virtual void handleFrameObject(int32 subSize, Common::SeekableReadStream &b);
326 virtual void handleFrame(int32 frameSize, Common::SeekableReadStream &b);
327 virtual void handleGameUpdateScreen(const byte *
328 src, int srcPitch, int width, int height);
329
330private:
331 SmushFont *getFont(int font);
332 void parseNextFrame();
333 void init(int32 spped);
334 void setupAnim(const char *file);
335 void updateScreen();
336 void tryCmpFile(const char *filename);
337
338 bool readString(const char *file);
339 void decodeFrameObject(int codec, const uint8 *src, int left, int top, int width, int height, int dataSize = 0, uint8 ra1Param = 0, uint16 ra1Parm2 = 0);
340 void handleAnimHeader(int32 subSize, Common::SeekableReadStream &);
341 void handleNewPalette(int32 subSize, Common::SeekableReadStream &);
342 void handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b);
343 void handleSAUDChunk(uint8 *srcBuf, uint32 size, int groupId, int vol, int pan, int16 flags, int trkId, int index, int maxFrames);
344 void handleStore(int32 subSize, Common::SeekableReadStream &);
345 void handleFetch(int32 subSize, Common::SeekableReadStream &);
346 void handleIACT(int32 subSize, Common::SeekableReadStream &);
347 void handleTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &);
348 void handleDeltaPalette(int32 subSize, Common::SeekableReadStream &);
349 void readPalette(byte *, Common::SeekableReadStream &);
350
351 // Shared RA1/RA2 helpers (access _storedFobj*/_lastFobj* on base)
352 void adjustFrameCoords(int &left, int &top, int &width, int &height, int pitch, int *srcSkipY = nullptr);
353 void rememberLastFobj(int codec, const byte *data, int32 dataSize,
354 int left, int top, int width, int height);
355
356 void initAudio(int samplerate, int32 maxChunkSize);
357 void terminateAudio();
358 int isChanActive(int flagId);
359 int addAudioTrack(int32 trackBlockSize, int32 maxBlockSize);
360 void resetAudioTracks();
361 void setGainReductionParams(int16 gainReductionLowerBound, int16 gainReductionMultiplier);
362 void fillAudioTrackInfo(uint8 *srcBuf, uint16 *flagsAccumulator, uint32 size, int groupId, int vol, int pan, int16 flags, int trkId, int index, int maxFrames);
363 bool processAudioCodes(int idx, int32 &tmpFeedSize, int &mixVolume);
364 void feedAudio(uint8 *srcBuf, int groupId, int volume, int pan, int16 flags);
365 void sendAudioToDiMUSE(uint8 *mixBuf, int32 mixStartingPoint, int32 mixFeedSize, int32 mixInFrameCount, int volume, int pan);
366
367 void timerCallback();
368};
369
370} // End of namespace Scumm
371
372#endif
Definition: audiostream.h:370
Definition: mixer.h:49
Definition: stream.h:745
Definition: str.h:59
Definition: system.h:39
Definition: actor.h:30
Definition: rect.h:536