aboutsummaryrefslogtreecommitdiff
path: root/engines/agos/animation.cpp
diff options
context:
space:
mode:
authorTravis Howell2008-12-21 04:36:11 +0000
committerTravis Howell2008-12-21 04:36:11 +0000
commit76624fc69c28bc422076740521e77f2ba83a2320 (patch)
treec5cc21ce21299c81721a7b8080e349ec0351136f /engines/agos/animation.cpp
parentcba892a61b2449192dbf9db9d9502ead6d9be633 (diff)
downloadscummvm-rg350-76624fc69c28bc422076740521e77f2ba83a2320.tar.gz
scummvm-rg350-76624fc69c28bc422076740521e77f2ba83a2320.tar.bz2
scummvm-rg350-76624fc69c28bc422076740521e77f2ba83a2320.zip
Add initial Smacker support for The Feeble Files.
svn-id: r35457
Diffstat (limited to 'engines/agos/animation.cpp')
-rw-r--r--engines/agos/animation.cpp553
1 files changed, 329 insertions, 224 deletions
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 328aa75acc..d6e5a1f414 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -41,120 +41,41 @@
namespace AGOS {
-MoviePlayer::MoviePlayer(AGOSEngine *vm, Audio::Mixer *mixer)
- : DXAPlayer(), _vm(vm), _mixer(mixer) {
- _omniTV = false;
-
- _omniTVFile = 0;
+MoviePlayer::MoviePlayer(AGOSEngine *vm)
+ : _vm(vm) {
+ _mixer = _vm->_mixer;
_leftButtonDown = false;
_rightButtonDown = false;
+ _skipMovie = false;
memset(baseName, 0, sizeof(baseName));
- _sequenceNum = 0;
_ticks = 0;
}
-bool MoviePlayer::load(const char *filename) {
- char videoName[20];
- uint i;
-
- int baseLen = strlen(filename) - 4;
- memset(baseName, 0, sizeof(baseName));
- memcpy(baseName, filename, baseLen);
-
- // Change file extension to dxa
- sprintf(videoName, "%s.dxa", baseName);
-
- if (!loadFile(videoName)) {
- // Check short filename to work around
- // bug in a German Windows 2CD version.
- if (baseLen >= 8) {
- char shortName[20];
- memset(shortName, 0, sizeof(shortName));
- memcpy(shortName, filename, 6);
-
- sprintf(shortName, "%s~1.dxa", shortName);
-
- if (!loadFile(shortName))
- error("Failed to load video file %s or %s", videoName, shortName);
-
- memset(baseName, 0, sizeof(baseName));
- memcpy(baseName, shortName, 8);
- debug(0, "Playing video %s", shortName);
- } else {
- error("Failed to load video file %s", videoName);
- }
- } else {
- debug(0, "Playing video %s", videoName);
- }
-
- CursorMan.showMouse(false);
-
- if ((_vm->getPlatform() == Common::kPlatformAmiga || _vm->getPlatform() == Common::kPlatformMacintosh) &&
- _vm->_language != Common::EN_ANY) {
- _sequenceNum = 0;
- for (i = 0; i < 90; i++) {
- if (!scumm_stricmp(baseName, _sequenceList[i]))
- _sequenceNum = i;
- }
- }
-
- return true;
-}
-
-void MoviePlayer::playOmniTV() {
- // Load OmniTV video
- if (_fileStream) {
- _vm->setBitFlag(42, false);
- _omniTV = true;
- startSound();
- } else {
- if (_omniTVFile) {
- // Restore state
- _fileStream = _omniTVFile;
- _mixer->pauseHandle(_omniTVSound, false);
-
- _vm->setBitFlag(42, false);
- _omniTV = true;
- } else {
- _vm->_variableArray[254] = 6747;
- }
- }
+MoviePlayer::~MoviePlayer() {
}
void MoviePlayer::play() {
if (_vm->getBitFlag(40)) {
- playOmniTV();
+ _vm->setBitFlag(42, false);
+ startSound();
return;
}
- if (_omniTVFile) {
- // Clear any paused OmniTV video
- _mixer->stopHandle(_omniTVSound);
- delete _omniTVFile;
- _omniTVFile = 0;
- }
-
_leftButtonDown = false;
_rightButtonDown = false;
+ _skipMovie = false;
- _mixer->stopAll();
-
- // Resolution is smaller in Amiga verison so always clear screen
- if (_width == 384 && _height == 280) {
- _vm->clearSurfaces();
- }
+ _vm->_mixer->stopAll();
_ticks = _vm->_system->getMillis();
startSound();
- while (_frameNum < _framesCount && !_vm->shouldQuit())
- handleNextFrame();
-
- closeFile();
+ playVideo();
+ stopVideo();
_vm->o_killAnimate();
@@ -171,92 +92,7 @@ void MoviePlayer::play() {
_vm->_fastFadeOutFlag = true;
}
-void MoviePlayer::startSound() {
- byte *buffer;
- uint32 offset, size, tag;
-
- tag = _fileStream->readUint32BE();
- if (tag == MKID_BE('WAVE')) {
- size = _fileStream->readUint32BE();
-
- if (_sequenceNum) {
- Common::File in;
-
- _fileStream->seek(size, SEEK_CUR);
-
- in.open((const char *)"audio.wav");
- if (!in.isOpen()) {
- error("Can't read offset file 'audio.wav'");
- }
-
- in.seek(_sequenceNum * 8, SEEK_SET);
- offset = in.readUint32LE();
- size = in.readUint32LE();
-
- buffer = (byte *)malloc(size);
- in.seek(offset, SEEK_SET);
- in.read(buffer, size);
- in.close();
- } else {
- buffer = (byte *)malloc(size);
- _fileStream->read(buffer, size);
- }
-
- Common::MemoryReadStream stream(buffer, size);
- _bgSoundStream = Audio::makeWAVStream(stream);
- free(buffer);
- } else {
- _bgSoundStream = Audio::AudioStream::openStreamFile(baseName);
- }
-
- if (_bgSoundStream != NULL) {
- if (_omniTV) {
- _mixer->stopHandle(_omniTVSound);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_omniTVSound, _bgSoundStream);
- } else {
- _mixer->stopHandle(_bgSound);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
- }
- }
-}
-
-void MoviePlayer::nextFrame() {
- if (!_omniTV)
- return;
-
- if (_vm->getBitFlag(42)) {
- // Save state
- _omniTVFile = _fileStream;
- _mixer->pauseHandle(_omniTVSound, true);
-
- _fileStream = 0;
- _omniTV = false;
- return;
- }
-
- if (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum) {
- copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
- return;
- }
-
- if (_frameNum < _framesCount) {
- decodeNextFrame();
- copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
- _frameNum++;
- } else {
- _omniTV = false;
- _omniTVFile = 0;
- closeFile();
- _vm->_variableArray[254] = 6747;
- }
-}
-
void MoviePlayer::handleNextFrame() {
- decodeNextFrame();
- if (processFrame())
- _vm->_system->updateScreen();
- _frameNum++;
-
Common::Event event;
Common::EventManager *eventMan = _vm->_system->getEventManager();
while (eventMan->pollEvent(event)) {
@@ -285,60 +121,16 @@ void MoviePlayer::handleNextFrame() {
}
if (_leftButtonDown && _rightButtonDown && !_vm->getBitFlag(41)) {
- _frameNum = _framesCount;
+ _skipMovie = true;
_mixer->stopHandle(_bgSound);
}
}
-void MoviePlayer::setPalette(byte *pal) {
- byte palette[1024];
- byte *p = palette;
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for DXA movies
+///////////////////////////////////////////////////////////////////////////////
- for (int i = 0; i < 256; i++) {
- *p++ = *pal++;
- *p++ = *pal++;
- *p++ = *pal++;
- *p++ = 0;
- }
-
- _vm->_system->setPalette(palette, 0, 256);
-}
-
-bool MoviePlayer::processFrame() {
- Graphics::Surface *screen = _vm->_system->lockScreen();
- copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2, _vm->_screenWidth);
- _vm->_system->unlockScreen();
-
- if ((_bgSoundStream == NULL) || ((int)(_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum + 1) ||
- _frameSkipped > _framesPerSec) {
- if (_frameSkipped > _framesPerSec) {
- warning("force frame %i redraw", _frameNum);
- _frameSkipped = 0;
- }
-
- if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) {
- while (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum) {
- _vm->_system->delayMillis(10);
- }
- // In case the background sound ends prematurely, update
- // _ticks so that we can still fall back on the no-sound
- // sync case for the subsequent frames.
- _ticks = _vm->_system->getMillis();
- } else {
- _ticks += _frameTicks;
- while (_vm->_system->getMillis() < _ticks)
- _vm->_system->delayMillis(10);
- }
-
- return true;
- }
-
- warning("dropped frame %i", _frameNum);
- _frameSkipped++;
- return false;
-}
-
-const char * MoviePlayer::_sequenceList[90] = {
+const char * MoviePlayerDXA::_sequenceList[90] = {
"agent32",
"Airlock",
"Badluck",
@@ -431,4 +223,317 @@ const char * MoviePlayer::_sequenceList[90] = {
"wurbatak"
};
+MoviePlayerDXA::MoviePlayerDXA(AGOSEngine *vm, const char *name)
+ : MoviePlayer(vm) {
+ debug(0, "Creating DXA cutscene player");
+
+ memset(baseName, 0, sizeof(baseName));
+ memcpy(baseName, name, strlen(name));
+
+ _sequenceNum = 0;
+}
+
+bool MoviePlayerDXA::load() {
+ char videoName[20];
+ uint i;
+
+ if ((_vm->getPlatform() == Common::kPlatformAmiga || _vm->getPlatform() == Common::kPlatformMacintosh) &&
+ _vm->_language != Common::EN_ANY) {
+ _sequenceNum = 0;
+ for (i = 0; i < 90; i++) {
+ if (!scumm_stricmp(baseName, _sequenceList[i]))
+ _sequenceNum = i;
+ }
+ }
+
+ sprintf(videoName, "%s.dxa", baseName);
+ if (!loadFile(videoName))
+ error("Failed to load video file %s", videoName);
+
+ debug(0, "Playing video %s", videoName);
+
+ CursorMan.showMouse(false);
+
+ return true;
+}
+
+void MoviePlayerDXA::playVideo() {
+ while (_frameNum < _framesCount && !_skipMovie && !_vm->shouldQuit())
+ handleNextFrame();
+}
+
+void MoviePlayerDXA::stopVideo() {
+ closeFile();
+ _mixer->stopHandle(_bgSound);
+}
+
+void MoviePlayerDXA::startSound() {
+ byte *buffer;
+ uint32 offset, size, tag;
+
+ tag = _fileStream->readUint32BE();
+ if (tag == MKID_BE('WAVE')) {
+ size = _fileStream->readUint32BE();
+
+ if (_sequenceNum) {
+ Common::File in;
+
+ _fileStream->seek(size, SEEK_CUR);
+
+ in.open((const char *)"audio.wav");
+ if (!in.isOpen()) {
+ error("Can't read offset file 'audio.wav'");
+ }
+
+ in.seek(_sequenceNum * 8, SEEK_SET);
+ offset = in.readUint32LE();
+ size = in.readUint32LE();
+
+ buffer = (byte *)malloc(size);
+ in.seek(offset, SEEK_SET);
+ in.read(buffer, size);
+ in.close();
+ } else {
+ buffer = (byte *)malloc(size);
+ _fileStream->read(buffer, size);
+ }
+
+ Common::MemoryReadStream stream(buffer, size);
+ _bgSoundStream = Audio::makeWAVStream(stream);
+ free(buffer);
+ } else {
+ _bgSoundStream = Audio::AudioStream::openStreamFile(baseName);
+ }
+
+ if (_bgSoundStream != NULL) {
+ _vm->_mixer->stopHandle(_bgSound);
+ _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
+ }
+}
+
+void MoviePlayerDXA::nextFrame() {
+ if (_vm->_mixer->isSoundHandleActive(_bgSound) && (_vm->_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum) {
+ copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
+ return;
+ }
+
+ if (_frameNum < _framesCount) {
+ decodeNextFrame();
+ copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
+ } else {
+ closeFile();
+ _vm->_variableArray[254] = 6747;
+ }
+}
+
+void MoviePlayerDXA::handleNextFrame() {
+ decodeNextFrame();
+ if (processFrame())
+ _vm->_system->updateScreen();
+
+ MoviePlayer::handleNextFrame();
+}
+
+void MoviePlayerDXA::setPalette(byte *pal) {
+ byte palette[1024];
+ byte *p = palette;
+
+ for (int i = 0; i < 256; i++) {
+ *p++ = *pal++;
+ *p++ = *pal++;
+ *p++ = *pal++;
+ *p++ = 0;
+ }
+
+ _vm->_system->setPalette(palette, 0, 256);
+}
+
+bool MoviePlayerDXA::processFrame() {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2, _vm->_screenWidth);
+ _vm->_system->unlockScreen();
+
+ if ((_bgSoundStream == NULL) || ((int)(_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum + 1) ||
+ _frameSkipped > _framesPerSec) {
+ if (_frameSkipped > _framesPerSec) {
+ warning("force frame %i redraw", _frameNum);
+ _frameSkipped = 0;
+ }
+
+ if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) {
+ while (_mixer->isSoundHandleActive(_bgSound) && (_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum) {
+ _vm->_system->delayMillis(10);
+ }
+ // In case the background sound ends prematurely, update
+ // _ticks so that we can still fall back on the no-sound
+ // sync case for the subsequent frames.
+ _ticks = _vm->_system->getMillis();
+ } else {
+ _ticks += _frameTicks;
+ while (_vm->_system->getMillis() < _ticks)
+ _vm->_system->delayMillis(10);
+ }
+
+ return true;
+ }
+
+ warning("dropped frame %i", _frameNum);
+ _frameSkipped++;
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for Smacker movies
+///////////////////////////////////////////////////////////////////////////////
+
+
+MoviePlayerSMK::MoviePlayerSMK(AGOSEngine *vm, const char *name)
+ : MoviePlayer(vm), SMKPlayer(vm->_mixer) {
+ debug(0, "Creating SMK cutscene player");
+
+ memset(baseName, 0, sizeof(baseName));
+ memcpy(baseName, name, strlen(name));
+}
+
+bool MoviePlayerSMK::load() {
+ char videoName[20];
+
+ sprintf(videoName, "%s.smk", baseName);
+ if (!loadFile(videoName))
+ error("Failed to load video file %s", videoName);
+
+ debug(0, "Playing video %s", videoName);
+
+ CursorMan.showMouse(false);
+
+ return true;
+}
+
+void MoviePlayerSMK::playVideo() {
+ while (getCurFrame() < getFrameCount() && !_skipMovie && !_vm->shouldQuit())
+ handleNextFrame();
+}
+
+void MoviePlayerSMK::stopVideo() {
+ closeFile();
+}
+
+void MoviePlayerSMK::startSound() {
+}
+
+void MoviePlayerSMK::handleNextFrame() {
+ decodeNextFrame();
+ if (processFrame())
+ _vm->_system->updateScreen();
+
+ MoviePlayer::handleNextFrame();
+}
+
+void MoviePlayerSMK::nextFrame() {
+ if (_vm->getBitFlag(42)) {
+ closeFile();
+ return;
+ }
+
+ if (getCurFrame() < getFrameCount()) {
+ decodeNextFrame();
+ copyFrameToBuffer(_vm->getBackBuf(), 465, 222, _vm->_screenWidth);
+ } else {
+ closeFile();
+ _vm->_variableArray[254] = 6747;
+ }
+}
+
+void MoviePlayerSMK::setPalette(byte *pal) {
+ byte palette[1024];
+ byte *p = palette;
+
+ for (int i = 0; i < 256; i++) {
+ *p++ = *pal++;
+ *p++ = *pal++;
+ *p++ = *pal++;
+ *p++ = 0;
+ }
+
+ _vm->_system->setPalette(palette, 0, 256);
+}
+
+bool MoviePlayerSMK::processFrame() {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, _vm->_screenWidth);
+ _vm->_system->unlockScreen();
+
+ if (!getAudioLag() || getAudioLag() > 0 || _frameSkipped > getFrameRate()) {
+ if (_frameSkipped > getFrameRate()) {
+ warning("force frame %i redraw", getCurFrame());
+ _frameSkipped = 0;
+ }
+
+ if (getAudioLag() > 0) {
+ while (getAudioLag() > 0) {
+ _vm->_system->delayMillis(10);
+ }
+ // In case the background sound ends prematurely, update
+ // _ticks so that we can still fall back on the no-sound
+ // sync case for the subsequent frames.
+ _ticks = _vm->_system->getMillis();
+ } else {
+ _ticks += getFrameDelay();
+ while (_vm->_system->getMillis() < _ticks)
+ _vm->_system->delayMillis(10);
+ }
+
+ return true;
+ }
+
+ warning("dropped frame %i", getCurFrame());
+ _frameSkipped++;
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Factory function for creating the appropriate cutscene player
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayer *makeMoviePlayer(AGOSEngine *vm, const char *name) {
+ char baseName[40];
+ char filename[20];
+
+ int baseLen = strlen(name) - 4;
+ memset(baseName, 0, sizeof(baseName));
+ memcpy(baseName, name, baseLen);
+
+ if (vm->getLanguage() == Common::DE_DEU && baseLen >= 8) {
+ // Check short filename to work around
+ // bug in a German Windows 2CD version.
+ char shortName[20];
+ memset(shortName, 0, sizeof(shortName));
+ memcpy(shortName, filename, 6);
+
+ sprintf(filename, "%s~1.dxa", shortName);
+ if (Common::File::exists(filename)) {
+ memset(baseName, 0, sizeof(baseName));
+ memcpy(baseName, shortName, 8);
+ }
+
+ sprintf(filename, "%s~1.smk", shortName);
+ if (Common::File::exists(filename)) {
+ memset(baseName, 0, sizeof(baseName));
+ memcpy(baseName, shortName, 8);
+ }
+ }
+
+ sprintf(filename, "%s.dxa", baseName);
+ if (Common::File::exists(filename)) {
+ return new MoviePlayerDXA(vm, baseName);
+ }
+
+ sprintf(filename, "%s.smk", baseName);
+ if (Common::File::exists(filename)) {
+ return new MoviePlayerSMK(vm, baseName);
+ }
+
+ return NULL;
+}
+
} // End of namespace AGOS