aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/smush
diff options
context:
space:
mode:
authorMax Horn2006-11-13 19:46:52 +0000
committerMax Horn2006-11-13 19:46:52 +0000
commit1a2853f7e0786e0ae1d072f5ce97391ad5d67978 (patch)
treea2e83c8592662cdbba11344d362b1653e3d5583d /engines/scumm/smush
parent9f74b031828b2a309b8194a0da9fdee85dec0cd7 (diff)
downloadscummvm-rg350-1a2853f7e0786e0ae1d072f5ce97391ad5d67978.tar.gz
scummvm-rg350-1a2853f7e0786e0ae1d072f5ce97391ad5d67978.tar.bz2
scummvm-rg350-1a2853f7e0786e0ae1d072f5ce97391ad5d67978.zip
Patch from bug #1584888 (SMUSH: Too dependent on accurate timers). Watch out for regressions in SMUSH movie playback / syncing
svn-id: r24709
Diffstat (limited to 'engines/scumm/smush')
-rw-r--r--engines/scumm/smush/smush_mixer.cpp6
-rw-r--r--engines/scumm/smush/smush_player.cpp110
-rw-r--r--engines/scumm/smush/smush_player.h9
3 files changed, 86 insertions, 39 deletions
diff --git a/engines/scumm/smush/smush_mixer.cpp b/engines/scumm/smush/smush_mixer.cpp
index 9b0f67045f..9e6631a365 100644
--- a/engines/scumm/smush/smush_mixer.cpp
+++ b/engines/scumm/smush/smush_mixer.cpp
@@ -45,14 +45,12 @@ SmushMixer::SmushMixer(Audio::Mixer *m) :
}
SmushMixer::~SmushMixer() {
- Common::StackLock lock(_mutex);
for (int32 i = 0; i < NUM_CHANNELS; i++) {
_mixer->stopHandle(_channels[i].handle);
}
}
SmushChannel *SmushMixer::findChannel(int32 track) {
- Common::StackLock lock(_mutex);
debugC(DEBUG_SMUSH, "SmushMixer::findChannel(%d)", track);
for (int32 i = 0; i < NUM_CHANNELS; i++) {
if (_channels[i].id == track)
@@ -62,7 +60,6 @@ SmushChannel *SmushMixer::findChannel(int32 track) {
}
void SmushMixer::addChannel(SmushChannel *c) {
- Common::StackLock lock(_mutex);
int32 track = c->getTrackIdentifier();
int i;
@@ -91,7 +88,6 @@ void SmushMixer::addChannel(SmushChannel *c) {
}
bool SmushMixer::handleFrame() {
- Common::StackLock lock(_mutex);
debugC(DEBUG_SMUSH, "SmushMixer::handleFrame()");
for (int i = 0; i < NUM_CHANNELS; i++) {
if (_channels[i].id != -1) {
@@ -136,7 +132,6 @@ bool SmushMixer::handleFrame() {
}
bool SmushMixer::stop() {
- Common::StackLock lock(_mutex);
debugC(DEBUG_SMUSH, "SmushMixer::stop()");
for (int i = 0; i < NUM_CHANNELS; i++) {
if (_channels[i].id != -1) {
@@ -154,7 +149,6 @@ bool SmushMixer::stop() {
}
bool SmushMixer::flush() {
- Common::StackLock lock(_mutex);
debugC(DEBUG_SMUSH, "SmushMixer::flush()");
for (int i = 0; i < NUM_CHANNELS; i++) {
if (_channels[i].id != -1) {
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 952665ce80..bd4261d60c 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -27,7 +27,6 @@
#include "common/config-manager.h"
#include "common/file.h"
#include "common/system.h"
-#include "common/timer.h"
#include "common/util.h"
#include "graphics/cursorman.h"
@@ -220,18 +219,17 @@ static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_enc
return sr;
}
-void SmushPlayer::timerCallback(void *refCon) {
- SmushPlayer *sp = (SmushPlayer *)refCon;
- sp->parseNextFrame();
+void SmushPlayer::timerCallback() {
+ parseNextFrame();
#ifdef _WIN32_WCE
- sp->_inTimer = true;
- sp->_inTimerCount++;
+ _inTimer = true;
+ _inTimerCount++;
#endif
#ifdef __SYMBIAN32__
- if (sp->_closeOnTextTick) {
- delete sp->_base;
- sp->_base = NULL;
- sp->_closeOnTextTick = false;
+ if (_closeOnTextTick) {
+ delete _base;
+ _base = NULL;
+ _closeOnTextTick = false;
}
#endif
}
@@ -267,6 +265,9 @@ SmushPlayer::SmushPlayer(ScummEngine_v7 *scumm) {
_skipPalette = false;
_IACTstream = NULL;
_smixer = _vm->_smixer;
+ _paused = false;
+ _pauseStartTime = 0;
+ _pauseTime = 0;
#ifdef _WIN32_WCE
_inTimer = false;
_inTimerCount = 0;
@@ -307,8 +308,6 @@ void SmushPlayer::init(int32 speed) {
_vm->_mixer->stopHandle(_IACTchannel);
_vm->_smixer->stop();
- _vm->_timer->installTimerProc(&timerCallback, 1000000 / _speed, this);
-
_initDone = true;
}
@@ -322,7 +321,6 @@ void SmushPlayer::release() {
User::After(15624);
}
#endif
- _vm->_timer->removeTimerProc(&timerCallback);
_vm->_smushVideoShouldFinish = true;
@@ -1071,13 +1069,8 @@ void SmushPlayer::setupAnim(const char *file) {
}
void SmushPlayer::parseNextFrame() {
- Common::StackLock lock(_mutex);
-
Chunk *sub;
- if (_vm->_smushPaused)
- return;
-
if (_seekPos >= 0) {
if (_smixer)
_smixer->stop();
@@ -1230,8 +1223,6 @@ void SmushPlayer::insanity(bool flag) {
}
void SmushPlayer::seekSan(const char *file, int32 pos, int32 contFrame) {
- Common::StackLock lock(_mutex);
-
_seekFile = file ? file : "";
_seekPos = pos;
_seekFrame = contFrame;
@@ -1274,8 +1265,22 @@ void SmushPlayer::tryCmpFile(const char *filename) {
#endif
}
-void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 startFrame) {
+void SmushPlayer::pause() {
+ if (!_paused) {
+ _paused = true;
+ _pauseStartTime = _vm->_system->getMillis();
+ }
+}
+
+void SmushPlayer::unpause() {
+ if (_paused) {
+ _paused = false;
+ _pauseTime += (_vm->_system->getMillis() - _pauseStartTime);
+ _pauseStartTime = 0;
+ }
+}
+void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 startFrame) {
// Verify the specified file exists
ScummFile f;
_vm->openFile(f, filename);
@@ -1302,7 +1307,39 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
setupAnim(filename);
init(speed);
+ uint32 startTime = _vm->_system->getMillis();
+
+ _pauseTime = 0;
+ uint frameNo = 0;
+
+ int skipped = 0;
+
for (;;) {
+ uint32 elapsed;
+ bool skipFrame = false;
+
+ if (_vm->_mixer->isSoundHandleActive(_compressedFileSoundHandle)) {
+ // Compressed SMUSH files.
+ elapsed = _vm->_mixer->getSoundElapsedTime(_compressedFileSoundHandle);
+ } else if (_vm->_mixer->isSoundHandleActive(_IACTchannel)) {
+ // Curse of Monkey Island SMUSH files.
+ elapsed = _vm->_mixer->getSoundElapsedTime(_IACTchannel);
+ } else {
+ // For other SMUSH files, we don't necessarily have any
+ // one channel to sync against, so we have to use
+ // elapsed real time.
+ uint32 now = _vm->_system->getMillis() - _pauseTime;
+ elapsed = now - startTime;
+ }
+
+ if (elapsed >= (frameNo * 1000) / _speed) {
+ if (elapsed >= ((frameNo + 1) * 1000) / _speed)
+ skipFrame = true;
+ else
+ skipFrame = false;
+ timerCallback();
+ }
+
if (_warpNeeded) {
_vm->_system->warpMouse(_warpX, _warpY);
_warpNeeded = false;
@@ -1326,25 +1363,36 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
_palDirtyMax = -1;
_palDirtyMin = 256;
+ skipFrame = false;
}
+ if (skipFrame) {
+ if (++skipped > 10) {
+ skipFrame = false;
+ skipped = 0;
+ }
+ } else
+ skipped = 0;
if (_updateNeeded) {
- int w = _width, h = _height;
+ if (!skipFrame) {
+ int w = _width, h = _height;
- // Workaround for bug #1386333: "FT DEMO: assertion triggered
- // when playing movie". Some frames there are 384 x 224
- if (w > _vm->_screenWidth)
- w = _vm->_screenWidth;
+ // Workaround for bug #1386333: "FT DEMO: assertion triggered
+ // when playing movie". Some frames there are 384 x 224
+ if (w > _vm->_screenWidth)
+ w = _vm->_screenWidth;
- if (h > _vm->_screenHeight)
- h = _vm->_screenHeight;
+ if (h > _vm->_screenHeight)
+ h = _vm->_screenHeight;
- _vm->_system->copyRectToScreen(_dst, _width, 0, 0, w, h);
- _vm->_system->updateScreen();
- _updateNeeded = false;
+ _vm->_system->copyRectToScreen(_dst, _width, 0, 0, w, h);
+ _vm->_system->updateScreen();
+ _updateNeeded = false;
+ }
#ifdef _WIN32_WCE
_inTimer = false;
_inTimerCount = 0;
#endif
+ frameNo++;
}
if (_endOfFile)
break;
diff --git a/engines/scumm/smush/smush_player.h b/engines/scumm/smush/smush_player.h
index 53fee75f9c..a6e83ef8ed 100644
--- a/engines/scumm/smush/smush_player.h
+++ b/engines/scumm/smush/smush_player.h
@@ -91,12 +91,14 @@ private:
#ifdef __SYMBIAN32__
bool _closeOnTextTick;
#endif
- Common::Mutex _mutex;
public:
SmushPlayer(ScummEngine_v7 *scumm);
~SmushPlayer();
+ void pause();
+ void unpause();
+
void play(const char *filename, int32 speed, int32 offset = 0, int32 startFrame = 0);
void release();
void warpMouse(int x, int y, int buttons);
@@ -106,6 +108,9 @@ protected:
int _width, _height;
int _origPitch, _origNumStrips;
+ bool _paused;
+ uint32 _pauseStartTime;
+ uint32 _pauseTime;
void insanity(bool);
void setPalette(const byte *palette);
@@ -139,7 +144,7 @@ private:
void handleDeltaPalette(Chunk &);
void readPalette(byte *, Chunk &);
- static void timerCallback(void *ptr);
+ void timerCallback();
};
} // End of namespace Scumm