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
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 BLADERUNNER_VQA_PLAYER_H
24 #define BLADERUNNER_VQA_PLAYER_H
25 
26 #include "bladerunner/vqa_decoder.h"
27 
28 #include "audio/audiostream.h"
29 #include "audio/mixer.h"
30 
31 #include "graphics/surface.h"
32 
33 namespace BladeRunner {
34 
35 enum LoopSetModes {
36 	kLoopSetModeJustStart = 0, // sets _frameBeginNext, _repeatsCount, _frameEnd
37 	kLoopSetModeEnqueue   = 1, // sets _frameBeginNext, _repeatsCountQueued, _frameEndQueued
38 	kLoopSetModeImmediate = 2  // like ModeJustStart, but also sets _frameNext to _frameBeginNext and updates _frameNextTime to current
39 };
40 
41 class BladeRunnerEngine;
42 class View;
43 class Lights;
44 class ZBuffer;
45 
46 class VQAPlayer {
47 	friend class Debugger;
48 	friend class OuttakePlayer;
49 
50 	BladeRunnerEngine           *_vm;
51 	Common::String               _name;
52 	Common::SeekableReadStream  *_s;
53 	VQADecoder                   _decoder;
54 	Audio::QueuingAudioStream   *_audioStream;
55 	Graphics::Surface           *_surface;
56 
57 	static const uint32  kVqaFrameTimeDiff             = 4000; // 60 * 1000 / 15
58 	static const int     kMaxAudioPreloadedFrames      = 15;
59 	// Use speech sound type as in original engine
60 	static const Audio::Mixer::SoundType kVQASoundType = Audio::Mixer::kSpeechSoundType;
61 
62 	int _frame;
63 	int _frameNext;
64 	int _frameBeginNext; // The frame to begin from, after current playing loop ends.
65 	                     // Does not necessarily reflect current playing loop's start frame
66 	int _frameEnd;       // The frame to end at for current playing loop
67 	int _loopNext;       // Does not necessarily reflect current playing loop's id
68 	                     // Used: - as param for _callbackLoopEnded() (which typically is loopEnded()), but never actually used in there)
69 	                     //       - for the MA05 inshot glitch workaround
70 	                     // It is set at every setLoop call except for the _loopInitial case (when no video stream is loaded)
71 	int _repeatsCount;   // -1 loop forever
72 	                     //  0 final repetition (or don't repeat after playing)
73 	                     //    When that repetition is completeed VQAPlayer::update() returns -3 value
74 	                     //    See Scene::advanceFrame() and OuttakePlayer::play() for checks for -3 result
75 	                     // Value is decreased per completed loop of current playing videoloop until it reaches 0
76 
77 	int _repeatsCountQueued;
78 	int _frameEndQueued;
79 
80 	int _lastAudioFrameSuccessfullyQueued;
81 
82 	int _loopInitial;
83 	int _repeatsCountInitial;
84 
85 	uint32 _frameNextTime;
86 	bool   _hasAudio;
87 	bool   _audioStarted;
88 	Audio::SoundHandle _soundHandle;
89 
90 	void (*_callbackLoopEnded)(void *, int frame, int loopId);
91 	void  *_callbackData;
92 
93 public:
94 
VQAPlayer(BladeRunnerEngine * vm,Graphics::Surface * surface,const Common::String & name)95 	VQAPlayer(BladeRunnerEngine *vm, Graphics::Surface *surface, const Common::String &name)
96 		: _vm(vm),
97 		  _name(name),
98 		  _s(nullptr),
99 		  _surface(surface),
100 		  _decoder(),
101 		  _audioStream(nullptr),
102 		  _frame(-1),
103 		  _frameNext(-1),
104 		  _frameBeginNext(-1),
105 		  _frameEnd(-1),
106 		  _loopNext(-1),
107 		  _repeatsCount(-1),
108 		  _repeatsCountQueued(-1),
109 		  _frameEndQueued(-1),
110 		  _lastAudioFrameSuccessfullyQueued(-1),
111 		  _loopInitial(-1),
112 		  _repeatsCountInitial(-1),
113 		  _frameNextTime(0),
114 		  _hasAudio(false),
115 		  _audioStarted(false),
116 		  _callbackLoopEnded(nullptr),
117 		  _callbackData(nullptr) { }
118 
~VQAPlayer()119 	~VQAPlayer() {
120 		close();
121 	}
122 
123 	bool open();
124 	void close();
125 
126 	int  update(bool forceDraw = false, bool advanceFrame = true, bool useTime = true, Graphics::Surface *customSurface = nullptr);
127 	void updateZBuffer(ZBuffer *zbuffer);
128 	void updateView(View *view);
129 	void updateScreenEffects(ScreenEffects *screenEffects);
130 	void updateLights(Lights *lights);
131 
132 	bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void(*callback)(void *, int, int), void *callbackData);
133 	bool setLoop(int loop, int repeatsCount, int loopSetMode, void(*callback)(void*, int, int), void *callbackData);
134 
135 	bool seekToFrame(int frame);
136 
137 	bool getCurrentBeginAndEndFrame(int frame, int *begin, int *end);
138 	int getLoopBeginFrame(int loop);
139 	int getLoopEndFrame(int loop);
140 
141 	int getFrameCount() const;
142 
143 	int getQueuedAudioFrames() const;
144 
145 private:
146 	void queueAudioFrame(Audio::AudioStream *audioStream);
147 };
148 
149 } // End of namespace BladeRunner
150 
151 #endif
152