diff -ur ScummVM-cvs20030129/scummvm/scumm/smush/brenderer.cpp ScummVM-cvs20030129+hack/scummvm/scumm/smush/brenderer.cpp
old
|
new
|
|
67 | 67 | } |
68 | 68 | |
69 | 69 | bool BaseRenderer::flipFrame() { |
70 | | save(); |
| 70 | save(getFrame()); |
71 | 71 | return true; |
72 | 72 | } |
73 | 73 | |
diff -ur ScummVM-cvs20030129/scummvm/scumm/smush/brenderer.h ScummVM-cvs20030129+hack/scummvm/scumm/smush/brenderer.h
old
|
new
|
|
36 | 36 | private: |
37 | 37 | Palette _pal; //!< The current palette |
38 | 38 | char * _data; //!< The current frame buffer |
39 | | int32 _frame; //!< The current frame number |
40 | | int32 _nbframes; //!< The number of frames in the animation |
41 | | int32 _width; //!< The current frame's width |
| 39 | int32 _frame; //!< The current frame number |
| 40 | int32 _nbframes; //!< The number of frames in the animation |
| 41 | bool _frameSkip; //!< The player is skipping frames to catch up |
| 42 | int32 _width; //!< The current frame's width |
42 | 43 | int32 _height; //!< The current frame's height |
43 | 44 | const char * _fname; //!< The filename of the animation being played |
44 | 45 | protected: |
… |
… |
|
54 | 55 | void setFrame(int32 f) { _frame = f; }; //!< allows to change the frame number |
55 | 56 | public: |
56 | 57 | int32 getFrame() const { return _frame; }; //!< accessor for current frame number |
| 58 | bool frameSkip() { return _frameSkip; }; |
| 59 | void setFrameSkip(bool skip) { _frameSkip = skip; }; |
57 | 60 | BaseRenderer(); |
58 | 61 | virtual ~BaseRenderer(); |
59 | 62 | |
… |
… |
|
76 | 79 | protected: |
77 | 80 | void save(int32 frame = -1) {}; |
78 | 81 | public: |
79 | | NullRenderer() {}; |
| 82 | NullRenderer() { setFrameSkip(false); }; |
80 | 83 | virtual ~NullRenderer() {}; |
81 | 84 | bool wait(int32 ms) { return true; }; |
82 | 85 | }; |
diff -ur ScummVM-cvs20030129/scummvm/scumm/smush/scumm_renderer.cpp ScummVM-cvs20030129+hack/scummvm/scumm/smush/scumm_renderer.cpp
old
|
new
|
|
203 | 203 | _pending_updates(0) { |
204 | 204 | } |
205 | 205 | |
206 | | static ScummRenderer * s_renderer; |
207 | | |
208 | | static void smush_handler(void * engine) { |
209 | | s_renderer->update(); |
210 | | } |
211 | | |
212 | 206 | Mixer * ScummRenderer::getMixer() { |
213 | 207 | if(_smixer == 0) { |
214 | 208 | _smixer = new ScummMixer(_scumm->_mixer); |
215 | 209 | if(!_smixer) error("unable to allocate a smush mixer"); |
216 | 210 | _smixer->_silentMixer = _scumm->_silentDigitalImuse; |
217 | | s_renderer = this; |
218 | | _scumm->_timer->installProcedure(&smush_handler, _insaneSpeed); |
219 | 211 | } |
220 | 212 | return _smixer; |
221 | 213 | } |
… |
… |
|
224 | 216 | _scumm->_insaneState = false; |
225 | 217 | _scumm->exitCutscene(); |
226 | 218 | if(_smixer) { |
227 | | _scumm->_timer->releaseProcedure(&smush_handler); |
228 | 219 | delete _smixer; |
229 | 220 | _smixer = 0; |
230 | 221 | } |
… |
… |
|
240 | 231 | } |
241 | 232 | |
242 | 233 | bool ScummRenderer::wait(int32 ms) { |
243 | | // Because waitForTimer() also is the function that checks for user |
244 | | // input we always want to call it at least once between frames, or |
245 | | // the user may become unable to interrupt the movie. |
246 | | do { |
247 | | _scumm->waitForTimer(1); |
248 | | } while(_pending_updates <= 0); |
249 | 234 | return true; |
250 | 235 | } |
251 | 236 | |
… |
… |
|
277 | 262 | } |
278 | 263 | |
279 | 264 | void ScummRenderer::save(int32 frame) { |
| 265 | int32 elapsed_time, frame_time; |
| 266 | |
280 | 267 | int width = MIN(getWidth(), _scumm->_realWidth); |
281 | 268 | int height = MIN(getHeight(), _scumm->_realHeight); |
| 269 | |
| 270 | if (frame == 0) { |
| 271 | _startTime = _scumm->_system->get_msecs(); |
| 272 | elapsed_time = frame_time = 0; |
| 273 | setFrameSkip(false); |
| 274 | } else { |
| 275 | elapsed_time = _scumm->_system->get_msecs() - _startTime; |
| 276 | frame_time = (frame * _insaneSpeed) / 1000; |
| 277 | } |
| 278 | |
| 279 | if (frame_time <= elapsed_time) { |
| 280 | // Don't wait -- just check for user input. |
| 281 | _scumm->waitForTimer(0); |
| 282 | } else { |
| 283 | _scumm->waitForTimer(frame_time - elapsed_time); |
| 284 | } |
282 | 285 | |
| 286 | // If the movie is lagging too far behind, skip frames in an attempt |
| 287 | // to catch up. |
283 | 288 | |
284 | | // In theory, this will always be true. In reality, there may be |
285 | | // several pending updates because the computer wasn't fast enough to |
286 | | // process them all. In that case, skip the frame to catch up. |
287 | | if (--_pending_updates <= 0) { |
| 289 | if (elapsed_time - frame_time > 200) |
| 290 | setFrameSkip(true); |
| 291 | |
| 292 | if (!frameSkip()) { |
288 | 293 | _scumm->_system->copy_rect((const byte *)data(), getWidth(), 0, 0, width, height); |
289 | 294 | _scumm->_system->update_screen(); |
290 | 295 | } else { |
291 | 296 | warning("ScummRenderer: Skipping frame %d to catch up", getFrame()); |
292 | 297 | } |
| 298 | |
| 299 | if (elapsed_time - frame_time < 100) |
| 300 | setFrameSkip(false); |
| 301 | |
293 | 302 | _scumm->processKbd(); |
294 | 303 | } |
295 | 304 | |
diff -ur ScummVM-cvs20030129/scummvm/scumm/smush/scumm_renderer.h ScummVM-cvs20030129+hack/scummvm/scumm/smush/scumm_renderer.h
old
|
new
|
|
46 | 46 | ScummMixer * _smixer; |
47 | 47 | uint32 _insaneSpeed; |
48 | 48 | volatile int _pending_updates; |
| 49 | uint32 _startTime; |
49 | 50 | public: |
50 | 51 | ScummRenderer(Scumm * scumm, uint32 speed); |
51 | 52 | virtual ~ScummRenderer(); |