aboutsummaryrefslogtreecommitdiff
path: root/engines
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
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')
-rw-r--r--engines/agos/agos.cpp18
-rw-r--r--engines/agos/agos.h4
-rw-r--r--engines/agos/animation.cpp553
-rw-r--r--engines/agos/animation.h57
-rw-r--r--engines/agos/event.cpp11
-rw-r--r--engines/agos/script_ff.cpp21
6 files changed, 418 insertions, 246 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index b3690b3d59..9d8bf23533 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -459,7 +459,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_vgaTickCounter = 0;
- _moviePlay = 0;
+ _moviePlayer = 0;
_sound = 0;
_effectsPaused = false;
@@ -606,8 +606,6 @@ Common::Error AGOSEngine::init() {
_debugger = new Debugger(this);
_sound = new Sound(this, gss, _mixer);
- _moviePlay = new MoviePlayer(this, _mixer);
-
if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1) {
_musicPaused = true;
if (_midiEnabled) {
@@ -920,7 +918,7 @@ AGOSEngine::~AGOSEngine() {
delete[] _windowList;
delete _debugger;
- delete _moviePlay;
+ delete _moviePlayer;
delete _sound;
}
@@ -1007,8 +1005,14 @@ Common::Error AGOSEngine::go() {
if ((getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformMacintosh) &&
getGameType() == GType_FF) {
- _moviePlay->load((const char *)"epic.dxa");
- _moviePlay->play();
+ _moviePlayer = makeMoviePlayer(this, (const char *)"epic.dxa");
+ assert(_moviePlayer);
+
+ _moviePlayer->load();
+ _moviePlayer->play();
+
+ delete _moviePlayer;
+ _moviePlayer = NULL;
}
runSubroutine101();
@@ -1068,7 +1072,7 @@ void AGOSEngine::shutdown() {
delete[] _windowList;
delete _debugger;
- delete _moviePlay;
+ delete _moviePlayer;
delete _sound;
_system->shouldQuit();
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index df20192389..d0aa0d1494 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -162,6 +162,8 @@ class Debugger;
class AGOSEngine : public Engine {
friend class Debugger;
friend class MoviePlayer;
+ friend class MoviePlayerDXA;
+ friend class MoviePlayerSMK;
// Engine APIs
virtual Common::Error init();
@@ -535,7 +537,7 @@ protected:
int _vgaTickCounter;
- MoviePlayer *_moviePlay;
+ MoviePlayer *_moviePlayer;
Audio::SoundHandle _modHandle;
Sound *_sound;
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
diff --git a/engines/agos/animation.h b/engines/agos/animation.h
index 4e8f15e33a..822ac8ee73 100644
--- a/engines/agos/animation.h
+++ b/engines/agos/animation.h
@@ -30,13 +30,17 @@
#include "common/stream.h"
#include "graphics/dxa_player.h"
+#include "graphics/smk_player.h"
#include "sound/mixer.h"
namespace AGOS {
class AGOSEngine;
-class MoviePlayer : public Graphics::DXAPlayer {
+class MoviePlayer {
+ friend class MoviePlayerDXA;
+ friend class MoviePlayerSMK;
+
AGOSEngine *_vm;
Audio::Mixer *_mixer;
@@ -44,33 +48,66 @@ class MoviePlayer : public Graphics::DXAPlayer {
Audio::SoundHandle _bgSound;
Audio::AudioStream *_bgSoundStream;
- Audio::SoundHandle _omniTVSound;
- Common::SeekableReadStream *_omniTVFile;
-
- bool _omniTV;
bool _leftButtonDown;
bool _rightButtonDown;
+ bool _skipMovie;
uint32 _ticks;
+ uint16 _frameSkipped;
char baseName[40];
+public:
+ MoviePlayer(AGOSEngine *vm);
+ virtual ~MoviePlayer();
+
+ virtual bool load() = 0;
+ virtual void play();
+ virtual void playVideo() {};
+ virtual void nextFrame() {};
+ virtual void stopVideo() {};
+
+private:
+ virtual void handleNextFrame();
+ virtual bool processFrame() = 0;
+ virtual void startSound() {};
+};
+
+class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
static const char *_sequenceList[90];
uint8 _sequenceNum;
public:
- MoviePlayer(AGOSEngine *vm, Audio::Mixer *mixer);
+ MoviePlayerDXA(AGOSEngine *vm, const char *name);
- bool load(const char *filename);
- void play();
+ bool load();
+ void playVideo();
void nextFrame();
+ virtual void stopVideo();
protected:
- virtual void setPalette(byte *pal);
+ void setPalette(byte *pal);
+
private:
- void playOmniTV();
+ void handleNextFrame();
+ bool processFrame();
+ void startSound();
+};
+
+class MoviePlayerSMK : public MoviePlayer, ::Graphics::SMKPlayer {
+public:
+ MoviePlayerSMK(AGOSEngine *vm, const char *name);
+ bool load();
+ void playVideo();
+ void nextFrame();
+ virtual void stopVideo();
+protected:
+ void setPalette(byte *pal);
+private:
void handleNextFrame();
bool processFrame();
void startSound();
};
+MoviePlayer *makeMoviePlayer(AGOSEngine *vm, const char *name);
+
} // End of namespace AGOS
#endif
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index abb7aa056b..683a096219 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -580,8 +580,15 @@ void AGOSEngine_Feeble::timer_proc1() {
}
}
- if (getGameType() == GType_FF) {
- _moviePlay->nextFrame();
+ if (getGameType() == GType_FF && _moviePlayer) {
+ // Controls Omni TV videos
+ if (getBitFlag(42)) {
+ _moviePlayer->stopVideo();
+ delete _moviePlayer;
+ _moviePlayer = NULL;
+ } else {
+ _moviePlayer->nextFrame();
+ }
}
animateSprites();
diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp
index 2bc04708f4..ec6c191db9 100644
--- a/engines/agos/script_ff.cpp
+++ b/engines/agos/script_ff.cpp
@@ -562,12 +562,29 @@ void AGOSEngine_Feeble::off_mouseOff() {
void AGOSEngine_Feeble::off_loadVideo() {
// 182: load video file
const byte *filename = getStringPtrByID(getNextStringID());
- _moviePlay->load((const char *)filename);
+
+ _moviePlayer = makeMoviePlayer(this, (const char *)filename);
+
+ assert(_moviePlayer);
+ _moviePlayer->load();
}
void AGOSEngine_Feeble::off_playVideo() {
// 183: play video
- _moviePlay->play();
+ if (getBitFlag(40)) {
+ // Omni TV controls
+ if (_moviePlayer) {
+ _moviePlayer->play();
+ } else {
+ _variableArray[254] = 6747;
+ }
+ } else {
+ assert(_moviePlayer);
+ _moviePlayer->play();
+
+ delete _moviePlayer;
+ _moviePlayer = NULL;
+ }
}
void AGOSEngine_Feeble::off_centreScroll() {