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 #include "titanic/support/movie.h"
24 #include "titanic/core/game_object.h"
25 #include "titanic/events.h"
26 #include "titanic/messages/messages.h"
27 #include "titanic/support/avi_surface.h"
28 #include "titanic/support/screen_manager.h"
29 #include "titanic/support/video_surface.h"
30 #include "titanic/sound/sound_manager.h"
31 #include "titanic/titanic.h"
32
33 namespace Titanic {
34
35 #define CLIP_WIDTH 600
36 #define CLIP_WIDTH_REDUCED (CLIP_WIDTH / 2)
37 #define CLIP_HEIGHT 340
38 #define CLIP_HEIGHT_REDUCED (CLIP_HEIGHT / 2)
39
40 CMovieList *CMovie::_playingMovies;
41 CVideoSurface *CMovie::_movieSurface;
42
CMovie()43 CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false) {
44 }
45
~CMovie()46 CMovie::~CMovie() {
47 removeFromPlayingMovies();
48 }
49
init()50 void CMovie::init() {
51 _playingMovies = new CMovieList();
52 _movieSurface = nullptr;
53 }
54
deinit()55 void CMovie::deinit() {
56 // At this point, there shouldn't be any playing movies left,
57 // since their owning objects should have freed them
58 assert(_playingMovies->empty());
59 delete _playingMovies;
60 delete _movieSurface;
61 }
62
addToPlayingMovies()63 void CMovie::addToPlayingMovies() {
64 if (!isActive())
65 _playingMovies->push_back(this);
66 }
67
removeFromPlayingMovies()68 void CMovie::removeFromPlayingMovies() {
69 _playingMovies->remove(this);
70 }
71
isActive() const72 bool CMovie::isActive() const {
73 return _playingMovies->contains(this);
74 }
75
hasVideoFrame()76 bool CMovie::hasVideoFrame() {
77 if (_hasVideoFrame) {
78 _hasVideoFrame = 0;
79 return true;
80 } else {
81 return false;
82 }
83 }
84
85 /*------------------------------------------------------------------------*/
86
OSMovie(const CResourceKey & name,CVideoSurface * surface)87 OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
88 _aviSurface(name), _videoSurface(surface) {
89 _field18 = 0;
90 _field24 = 0;
91 _field28 = 0;
92 _field2C = 0;
93
94 surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
95 _aviSurface.setVideoSurface(surface);
96 }
97
~OSMovie()98 OSMovie::~OSMovie() {
99 }
100
play(uint flags,CGameObject * obj)101 void OSMovie::play(uint flags, CGameObject *obj) {
102 _aviSurface.play(flags, obj);
103
104 if (_aviSurface.isPlaying())
105 movieStarted();
106 }
107
play(uint startFrame,uint endFrame,uint flags,CGameObject * obj)108 void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
109 _aviSurface.play(startFrame, endFrame, flags, obj);
110
111 if (_aviSurface.isPlaying())
112 movieStarted();
113 }
114
play(uint startFrame,uint endFrame,uint initialFrame,uint flags,CGameObject * obj)115 void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
116 _aviSurface.play(startFrame, endFrame, initialFrame, flags, obj);
117
118 if (_aviSurface.isPlaying())
119 movieStarted();
120 }
121
playCutscene(const Rect & drawRect,uint startFrame,uint endFrame)122 bool OSMovie::playCutscene(const Rect &drawRect, uint startFrame, uint endFrame) {
123 if (!_movieSurface)
124 _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 32);
125
126 // Set a new event target whilst the clip plays, so standard scene drawing isn't called
127 CEventTarget eventTarget;
128 g_vm->_events->addTarget(&eventTarget);
129
130 bool result = _aviSurface.playCutscene(drawRect, startFrame, endFrame);
131
132 g_vm->_events->removeTarget();
133 return result;
134 }
135
pause()136 void OSMovie::pause() {
137 _aviSurface.pause();
138 }
139
stop()140 void OSMovie::stop() {
141 _aviSurface.stop();
142 removeFromPlayingMovies();
143 }
144
addEvent(int frameNumber,CGameObject * obj)145 void OSMovie::addEvent(int frameNumber, CGameObject *obj) {
146 if (_aviSurface.addEvent(&frameNumber, obj)) {
147 CMovieFrameMsg frameMsg(frameNumber, 0);
148 frameMsg.execute(obj);
149 }
150 }
151
setFrame(uint frameNumber)152 void OSMovie::setFrame(uint frameNumber) {
153 _aviSurface.setFrame(frameNumber);
154 _videoSurface->setTransparencySurface(_aviSurface.getSecondarySurface());
155 }
156
handleEvents(CMovieEventList & events)157 bool OSMovie::handleEvents(CMovieEventList &events) {
158 // WORKAROUND: If a movie is paused as part of initial
159 // scene loading, now's the time to un-pause it
160 _aviSurface.resume();
161
162 if (!_aviSurface.isPlaying())
163 return false;
164
165 // Handle updating the frame
166 while (_aviSurface.isPlaying() && _aviSurface.isNextFrame()) {
167 _aviSurface.handleEvents(events);
168 _videoSurface->setTransparencySurface(_aviSurface.getSecondarySurface());
169
170 // Flag there's a video frame
171 _hasVideoFrame = true;
172 }
173
174 return _aviSurface.isPlaying();
175 }
176
getMovieRangeInfo() const177 const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const {
178 return _aviSurface.getMovieRangeInfo();
179 }
180
setSoundManager(CSoundManager * soundManager)181 void OSMovie::setSoundManager(CSoundManager *soundManager) {
182 _aviSurface._soundManager = soundManager;
183 }
184
getFrame() const185 int OSMovie::getFrame() const {
186 return _aviSurface.getFrame();
187 }
188
movieStarted()189 void OSMovie::movieStarted() {
190 //if (_aviSurface._hasAudio)
191 // _aviSurface._soundManager->movieStarted();
192
193 // Register the movie in the playing list
194 addToPlayingMovies();
195 _hasVideoFrame = true;
196 }
197
setFrameRate(double rate)198 void OSMovie::setFrameRate(double rate) {
199 _aviSurface.setFrameRate(rate);
200 }
201
setPlaying(bool playingFlag)202 void OSMovie::setPlaying(bool playingFlag) {
203 _aviSurface.setPlaying(playingFlag);
204 }
205
duplicateTransparency() const206 Graphics::ManagedSurface *OSMovie::duplicateTransparency() const {
207 return _aviSurface.duplicateTransparency();
208 }
209
210 } // End of namespace Titanic
211