[Scummvm-cvs-logs] SF.net SVN: scummvm: [23753] scummvm/trunk/engines/sword1

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Sat Aug 26 13:34:44 CEST 2006


Revision: 23753
Author:   eriktorbjorn
Date:     2006-08-26 04:34:35 -0700 (Sat, 26 Aug 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=23753&view=rev

Log Message:
-----------
Added support for DXA cutscenes. Still needs a bit of cleanup, and the DCA
player does not support the (unreleased) multi-lingual cutscene pack, since I
don't have one to test with.

It needs to be cleaned up a bit, but the next step will be to clean up the MPEG
decoder first.

Modified Paths:
--------------
    scummvm/trunk/engines/sword1/animation.cpp
    scummvm/trunk/engines/sword1/animation.h
    scummvm/trunk/engines/sword1/logic.cpp
    scummvm/trunk/engines/sword1/screen.cpp
    scummvm/trunk/engines/sword1/screen.h
Modified: scummvm/trunk/engines/sword1/animation.cpp
===================================================================
--- scummvm/trunk/engines/sword1/animation.cpp	2006-08-26 11:33:41 UTC (rev 23752)
+++ scummvm/trunk/engines/sword1/animation.cpp	2006-08-26 11:34:35 UTC (rev 23753)
@@ -28,83 +28,132 @@
 #include "sound/vorbis.h"
 
 #include "common/config-manager.h"
+#include "common/endian.h"
 #include "common/str.h"
 #include "common/system.h"
 
 namespace Sword1 {
 
-AnimationState::AnimationState(Screen *scr, Audio::Mixer *snd, OSystem *sys)
-	: BaseAnimationState(snd, sys, 640, 400), _scr(scr) {
-}
+static const char *sequenceList[20] = {
+    "ferrari",  // 0  CD2   ferrari running down fitz in sc19
+    "ladder",   // 1  CD2   george walking down ladder to dig sc24->sc$
+    "steps",    // 2  CD2   george walking down steps sc23->sc24
+    "sewer",    // 3  CD1   george entering sewer sc2->sc6
+    "intro",    // 4  CD1   intro sequence ->sc1
+    "river",    // 5  CD1   george being thrown into river by flap & g$
+    "truck",    // 6  CD2   truck arriving at bull's head sc45->sc53/4
+    "grave",    // 7  BOTH  george's grave in scotland, from sc73 + from sc38 $
+    "montfcon", // 8  CD2   monfaucon clue in ireland dig, sc25
+    "tapestry", // 9  CD2   tapestry room beyond spain well, sc61
+    "ireland",  // 10 CD2   ireland establishing shot europe_map->sc19
+    "finale",   // 11 CD2   grand finale at very end, from sc73
+    "history",  // 12 CD1   George's history lesson from Nico, in sc10
+    "spanish",  // 13 CD2   establishing shot for 1st visit to Spain, europe_m$
+    "well",     // 14 CD2   first time being lowered down well in Spai$
+    "candle",   // 15 CD2   Candle burning down in Spain mausoleum sc59
+    "geodrop",  // 16 CD2   from sc54, George jumping down onto truck
+    "vulture",  // 17 CD2   from sc54, vultures circling George's dead body
+    "enddemo",  // 18 ---   for end of single CD demo
+    "credits",  // 19 CD2   credits, to follow "finale" sequence
+};
 
-AnimationState::~AnimationState() {
-}
+///////////////////////////////////////////////////////////////////////////////
+// Basic movie player
+///////////////////////////////////////////////////////////////////////////////
 
-
-#ifdef BACKEND_8BIT
-void AnimationState::setPalette(byte *pal) {
-	_sys->setPalette(pal, 0, 256);
+MoviePlayer::MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys)
+	: _scr(scr), _snd(snd), _sys(sys) {
+	_bgSoundStream = NULL;
+	_ticks = 0;
+	_frameBuffer = NULL;
+	_currentFrame = 0;
+	_forceFrame = false;
+	_framesSkipped = 0;
 }
-#endif
 
-void AnimationState::drawYUV(int width, int height, byte *const *dat) {
-	_frameWidth = width;
-	_frameHeight = height;
-
-#ifdef BACKEND_8BIT
-	_scr->plotYUV(_lut, width, height, dat);
-#else
-	plotYUV(width, height, dat);
-#endif
+MoviePlayer::~MoviePlayer(void) {
 }
 
-OverlayColor *AnimationState::giveRgbBuffer(void) {
-#ifdef BACKEND_8BIT
-	return NULL;
-#else
-	return _overlay;
-#endif
+void MoviePlayer::updatePalette(byte *pal, bool packed) {
+	byte palette[4 * 256];
+	byte *p = palette;
+	for (int i = 0; i < 256; i++) {
+		*p++ = *pal++;
+		*p++ = *pal++;
+		*p++ = *pal++;
+		if (!packed)
+			*p++ = *pal++;
+		else
+			*p++ = 0;
+	}
+	_sys->setPalette(palette, 0, 256);
+	_forceFrame = true;
 }
 
-bool AnimationState::soundFinished(void) {
-	return !_snd->isSoundHandleActive(_bgSound);
+void MoviePlayer::handleScreenChanged(void) {
 }
 
-Audio::AudioStream *AnimationState::createAudioStream(const char *name, void *arg) {
-	if (arg)
-		return (Audio::AudioStream*)arg;
-	else
-		return Audio::AudioStream::openStreamFile(name);
+bool MoviePlayer::initOverlays(uint32 id) {
+	return true;
 }
 
-MoviePlayer::MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys)
-	: _scr(scr), _snd(snd), _sys(sys) {
-		for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
-			_logoOvls[cnt] = NULL;
-		_introPal = NULL;
+bool MoviePlayer::checkSkipFrame(void) {
+	if (_forceFrame) {
+		_forceFrame = false;
+		return false;
+	}
+	if (_framesSkipped > 10) {
+		warning("Forced frame %d to be displayed", _currentFrame);
+		_framesSkipped = 0;
+		return false;
+	}
+	if (_bgSoundStream) {
+		if ((_snd->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame + 1)
+			return false;
+	} else {
+		if (_sys->getMillis() <= _ticks)
+			return false;
+	}
+	_framesSkipped++;
+	return true;
 }
 
-MoviePlayer::~MoviePlayer(void) {
-	if (_introPal)
-		free(_introPal);
-	for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
-		if (_logoOvls[cnt])
-			free(_logoOvls[cnt]);
+void MoviePlayer::syncFrame(void) {
+	_ticks += 83;
+	if (checkSkipFrame()) {
+		warning("Skipped frame %d", _currentFrame);
+		return;
+	}
+	if (_bgSoundStream) {
+		while (_snd->isSoundHandleActive(_bgSoundHandle) && (_snd->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame) {
+			_sys->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 = _sys->getMillis();
+	} else {
+		while (_sys->getMillis() < _ticks) {
+			_sys->delayMillis(10);
+		}
+	}
 }
 
 /**
  * Plays an animated cutscene.
  * @param id the id of the file
  */
-void MoviePlayer::play(uint32 id) {
-#if defined(USE_MPEG2) && defined(USE_VORBIS)
-	AnimationState *anim = new AnimationState(_scr, _snd, _sys);
-	Audio::AudioStream *stream = NULL;
+bool MoviePlayer::load(uint32 id) {
+	_id = id;
+	_bgSoundStream = NULL;
 	if (SwordEngine::_systemVars.cutscenePackVersion == 1) {
 		if ((id == SEQ_INTRO) || (id == SEQ_FINALE) || (id == SEQ_HISTORY) || (id == SEQ_FERRARI)) {
+#ifdef USE_VORBIS
 			// these sequences are language specific
 			char sndName[20];
-			sprintf(sndName, "%s.snd", _sequenceList[id]);
+			sprintf(sndName, "%s.snd", sequenceList[id]);
 			Common::File *oggSource = new Common::File();
 			if (oggSource->open(sndName)) {
 				SplittedAudioStream *sStream = new SplittedAudioStream();
@@ -122,98 +171,63 @@
 					sStream->appendStream(apStream);
 				}
 				free(header);
-				stream = sStream;
+				_bgSoundStream = sStream;
 			} else
 				warning("Sound file \"%s\" not found", sndName);
+			oggSource->decRef();
+#endif
 			initOverlays(id);
-			oggSource->decRef();
 		}
 	}
-	bool initOK = anim->init(_sequenceList[id], stream);
+	return true;
+}
 
-	uint32 frameCount = 0;
-	if (initOK) {
-		while (anim->decodeFrame()) {
-			processFrame(id, anim, frameCount);
-			anim->updateScreen();
-			frameCount++;
-			OSystem::Event event;
-			while (_sys->pollEvent(event)) {
-				switch (event.type) {
-				case OSystem::EVENT_SCREEN_CHANGED:
-					anim->handleScreenChanged();
-					break;
-				case OSystem::EVENT_KEYDOWN:
-					if (event.kbd.keycode == 27) {
-						delete anim;
-						return;
-					}
-					break;
-				case OSystem::EVENT_QUIT:
-					_sys->quit();
-					break;
-				default:
-					break;
+void MoviePlayer::play(void) {
+	_scr->clearScreen();
+	_framesSkipped = 0;
+	_ticks = _sys->getMillis();
+	if (_bgSoundStream) {
+		_snd->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSoundHandle, _bgSoundStream);
+	}
+	_currentFrame = 0;
+	while (decodeFrame()) {
+		processFrame();
+		syncFrame();
+		updateScreen();
+		_currentFrame++;
+		OSystem::Event event;
+		while (_sys->pollEvent(event)) {
+			switch (event.type) {
+			case OSystem::EVENT_SCREEN_CHANGED:
+				handleScreenChanged();
+				break;
+			case OSystem::EVENT_KEYDOWN:
+				if (event.kbd.keycode == 27) {
+					_snd->stopHandle(_bgSoundHandle);
+					return;
 				}
+				break;
+			case OSystem::EVENT_QUIT:
+				_sys->quit();
+				break;
+			default:
+				break;
 			}
 		}
 	}
-	while (!anim->soundFinished())
+	while (_snd->isSoundHandleActive(_bgSoundHandle))
 		_sys->delayMillis(100);
-	delete anim;
-#endif // USE_MPEG2 && USE_VORBIS
-}
 
-void MoviePlayer::insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor *pal) {
-	if (ovl != NULL)
-		for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
-			if (ovl[cnt])
-				buf[cnt] = pal[ovl[cnt]];
-}
+	// It's tempting to call _screen->fullRefresh() here to restore the old
+	// palette. However, that causes glitches with DXA movies, here the
+	// previous location would be momentarily drawn, before switching to
+	// the new one. Work around this by setting the palette to black.
 
-void MoviePlayer::processFrame(uint32 animId, AnimationState *anim, uint32 frameNo) {
-#if defined(USE_MPEG2) && !defined(BACKEND_8BIT)
-	if ((animId != 4) || (SwordEngine::_systemVars.cutscenePackVersion == 0))
-		return;
-	OverlayColor *buf = anim->giveRgbBuffer();
-	if ((frameNo > 397) && (frameNo < 444)) { // Broken Sword Logo
-		if (frameNo <= 403)
-			insertOverlay(buf, _logoOvls[frameNo - 398], _introPal); // fade up
-		else if (frameNo <= 437)
-			insertOverlay(buf, _logoOvls[(frameNo - 404) % 6 + 6], _introPal); // animation
-		else {
-			insertOverlay(buf, _logoOvls[5 - (frameNo - 438)], _introPal); // fade down
-		}
-	}
-#endif
+	byte pal[3 * 256];
+	memset(pal, 0, sizeof(pal));
+	updatePalette(pal, true);
 }
 
-bool MoviePlayer::initOverlays(uint32 id) {
-#if defined(USE_MPEG2) && !defined(BACKEND_8BIT)
-	if (id == SEQ_INTRO) {
-		ArcFile ovlFile;
-		if (!ovlFile.open("intro.dat")) {
-			warning("\"intro.dat\" not found");
-			return false;
-		}
-		ovlFile.enterPath(SwordEngine::_systemVars.language);
-		for (uint8 fcnt = 0; fcnt < 12; fcnt++) {
-			_logoOvls[fcnt] = ovlFile.decompressFile(fcnt);
-			if (fcnt > 0)
-				for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
-					if (_logoOvls[fcnt - 1][cnt] && !_logoOvls[fcnt][cnt])
-						_logoOvls[fcnt][cnt] = _logoOvls[fcnt - 1][cnt];
-		}
-		uint8 *pal = ovlFile.fetchFile(12);
-		_introPal = (OverlayColor*)malloc(256 * sizeof(OverlayColor));
-		for (uint16 cnt = 0; cnt < 256; cnt++)
-			_introPal[cnt] = _sys->RGBToColor(pal[cnt * 3 + 0], pal[cnt * 3 + 1], pal[cnt * 3 + 2]);
-	}
-#endif
-
-	return true;
-}
-
 SplittedAudioStream::SplittedAudioStream(void) {
 	_queue = NULL;
 }
@@ -275,27 +289,237 @@
 	return retVal;
 }
 
-const char * MoviePlayer::_sequenceList[20] = {
-    "ferrari",  // 0  CD2   ferrari running down fitz in sc19
-    "ladder",   // 1  CD2   george walking down ladder to dig sc24->sc$
-    "steps",    // 2  CD2   george walking down steps sc23->sc24
-    "sewer",    // 3  CD1   george entering sewer sc2->sc6
-    "intro",    // 4  CD1   intro sequence ->sc1
-    "river",    // 5  CD1   george being thrown into river by flap & g$
-    "truck",    // 6  CD2   truck arriving at bull's head sc45->sc53/4
-    "grave",    // 7  BOTH  george's grave in scotland, from sc73 + from sc38 $
-    "montfcon", // 8  CD2   monfaucon clue in ireland dig, sc25
-    "tapestry", // 9  CD2   tapestry room beyond spain well, sc61
-    "ireland",  // 10 CD2   ireland establishing shot europe_map->sc19
-    "finale",   // 11 CD2   grand finale at very end, from sc73
-    "history",  // 12 CD1   George's history lesson from Nico, in sc10
-    "spanish",  // 13 CD2   establishing shot for 1st visit to Spain, europe_m$
-    "well",     // 14 CD2   first time being lowered down well in Spai$
-    "candle",   // 15 CD2   Candle burning down in Spain mausoleum sc59
-    "geodrop",  // 16 CD2   from sc54, George jumping down onto truck
-    "vulture",  // 17 CD2   from sc54, vultures circling George's dead body
-    "enddemo",  // 18 ---   for end of single CD demo
-    "credits",  // 19 CD2   credits, to follow "finale" sequence
-};
+#ifdef USE_ZLIB
 
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for the new DXA movies
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayerDXA::MoviePlayerDXA(Screen *src, Audio::Mixer *snd, OSystem *sys)
+	: MoviePlayer(src, snd, sys) {
+	debug(0, "Creating DXA cutscene player");
+}
+
+MoviePlayerDXA::~MoviePlayerDXA(void) {
+	// free(_frameBuffer);
+}
+
+bool MoviePlayerDXA::load(uint32 id) {
+	if (!MoviePlayer::load(id))
+		return false;
+
+	char filename[20];
+	snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
+	if (loadFile(filename)) {
+		// The Broken Sword games always use external audio tracks.
+		if (_fd.readUint32BE() != MKID_BE('NULL'))
+			return false;
+		_frameWidth = getWidth();
+		_frameHeight = getHeight();
+		_frameX = (640 - _frameWidth) / 2;
+		_frameY = (480 - _frameHeight) / 2;
+		if (!_bgSoundStream) {
+			_bgSoundStream = Audio::AudioStream::openStreamFile(sequenceList[id]);
+		}
+		return true;
+	}
+	return false;
+}
+
+bool MoviePlayerDXA::initOverlays(uint32 id) {
+	// TODO
+	return true;
+}
+
+void MoviePlayerDXA::setPalette(byte *pal) {
+	updatePalette(pal, true);
+}
+
+bool MoviePlayerDXA::decodeFrame(void) {
+	if (_currentFrame < _framesCount) {
+		decodeNextFrame();
+		return true;
+	}
+	return false;
+}
+
+void MoviePlayerDXA::processFrame(void) {
+	// TODO
+}
+
+void MoviePlayerDXA::updateScreen(void) {
+	// Using _frameBuffer1 directly should work, as long as we don't do any
+	// post-processing of the frame.
+	_sys->copyRectToScreen(_frameBuffer1, _frameWidth, _frameX, _frameY, _frameWidth, _frameHeight);
+	_sys->updateScreen();
+}
+
+#endif
+
+#ifdef USE_MPEG2
+
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for the old MPEG movies
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayerMPEG::MoviePlayerMPEG(Screen *src, Audio::Mixer *snd, OSystem *sys)
+	: MoviePlayer(src, snd, sys) {
+#ifdef BACKEND_8BIT
+	debug(0, "Creating MPEG cutscene player (8-bit)");
+#else
+	debug(0, "Creating MPEG cutscene player (16-bit)");
+#endif
+	for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
+		_logoOvls[cnt] = NULL;
+	_introPal = NULL;
+	_anim = NULL;
+}
+
+MoviePlayerMPEG::~MoviePlayerMPEG(void) {
+	free(_introPal);
+	for (uint8 cnt = 0; cnt < INTRO_LOGO_OVLS; cnt++)
+		free(_logoOvls[cnt]);
+	delete _anim;
+}
+
+void MoviePlayerMPEG::handleScreenChanged(void) {
+	_anim->handleScreenChanged();
+}
+
+void MoviePlayerMPEG::insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor *pal) {
+	if (ovl != NULL)
+		for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
+			if (ovl[cnt])
+				buf[cnt] = pal[ovl[cnt]];
+}
+
+bool MoviePlayerMPEG::load(uint32 id) {
+	if (MoviePlayer::load(id)) {
+		_anim = new AnimationState(this, _scr, _snd, _sys);
+		return _anim->init(sequenceList[id], _bgSoundStream);
+	}
+	return false;
+}
+
+bool MoviePlayerMPEG::initOverlays(uint32 id) {
+	if (id == SEQ_INTRO) {
+		ArcFile ovlFile;
+		if (!ovlFile.open("intro.dat")) {
+			warning("\"intro.dat\" not found");
+			return false;
+		}
+		ovlFile.enterPath(SwordEngine::_systemVars.language);
+		for (uint8 fcnt = 0; fcnt < 12; fcnt++) {
+			_logoOvls[fcnt] = ovlFile.decompressFile(fcnt);
+			if (fcnt > 0)
+				for (uint32 cnt = 0; cnt < 640 * 400; cnt++)
+					if (_logoOvls[fcnt - 1][cnt] && !_logoOvls[fcnt][cnt])
+						_logoOvls[fcnt][cnt] = _logoOvls[fcnt - 1][cnt];
+		}
+		uint8 *pal = ovlFile.fetchFile(12);
+		_introPal = (OverlayColor*)malloc(256 * sizeof(OverlayColor));
+		for (uint16 cnt = 0; cnt < 256; cnt++)
+			_introPal[cnt] = _sys->RGBToColor(pal[cnt * 3 + 0], pal[cnt * 3 + 1], pal[cnt * 3 + 2]);
+	}
+
+	return true;
+}
+
+bool MoviePlayerMPEG::decodeFrame(void) {
+	return _anim->decodeFrame();
+}
+
+void MoviePlayerMPEG::updateScreen(void) {
+	_anim->updateScreen();
+}
+
+void MoviePlayerMPEG::processFrame(void) {
+#ifndef BACKEND_8BIT
+	if ((_id != 4) || (SwordEngine::_systemVars.cutscenePackVersion == 0))
+		return;
+	OverlayColor *buf = _anim->giveRgbBuffer();
+	if ((_currentFrame > 397) && (_currentFrame < 444)) { // Broken Sword Logo
+		if (_currentFrame <= 403)
+			insertOverlay(buf, _logoOvls[_currentFrame - 398], _introPal); // fade up
+		else if (_currentFrame <= 437)
+			insertOverlay(buf, _logoOvls[(_currentFrame - 404) % 6 + 6], _introPal); // animation
+		else {
+			insertOverlay(buf, _logoOvls[5 - (_currentFrame - 438)], _introPal); // fade down
+		}
+	}
+#endif
+}
+
+void MoviePlayerMPEG::syncFrame(void) {
+}
+
+AnimationState::AnimationState(MoviePlayer *player, Screen *scr, Audio::Mixer *snd, OSystem *sys)
+	: BaseAnimationState(snd, sys, 640, 400), _player(player), _scr(scr) {
+}
+
+AnimationState::~AnimationState(void) {
+}
+
+#ifdef BACKEND_8BIT
+void AnimationState::setPalette(byte *pal) {
+	_player->updatePalette(pal, false);
+}
+#endif
+
+void AnimationState::drawYUV(int width, int height, byte *const *dat) {
+	_frameWidth = width;
+	_frameHeight = height;
+
+#ifdef BACKEND_8BIT
+	_scr->plotYUV(_lut, width, height, dat);
+#else
+	plotYUV(width, height, dat);
+#endif
+}
+
+OverlayColor *AnimationState::giveRgbBuffer(void) {
+#ifdef BACKEND_8BIT
+	return NULL;
+#else
+	return _overlay;
+#endif
+}
+
+Audio::AudioStream *AnimationState::createAudioStream(const char *name, void *arg) {
+	if (arg)
+		return (Audio::AudioStream*)arg;
+	else
+		return Audio::AudioStream::openStreamFile(name);
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Factory function for creating the appropriate cutscene player
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem *sys) {
+#if defined(USE_ZLIB) || defined(USE_MPEG2)
+	char filename[20];
+#endif
+
+#ifdef USE_ZLIB
+	snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
+
+	if (Common::File::exists(filename)) {
+		return new MoviePlayerDXA(scr, snd, sys);
+	}
+#endif
+
+#ifdef USE_MPEG2
+	snprintf(filename, sizeof(filename), "%s.mp2", sequenceList[id]);
+
+	if (Common::File::exists(filename)) {
+		return new MoviePlayerMPEG(scr, snd, sys);
+	}
+#endif
+
+	return NULL;
+}
+
 } // End of namespace Sword1

Modified: scummvm/trunk/engines/sword1/animation.h
===================================================================
--- scummvm/trunk/engines/sword1/animation.h	2006-08-26 11:33:41 UTC (rev 23752)
+++ scummvm/trunk/engines/sword1/animation.h	2006-08-26 11:34:35 UTC (rev 23753)
@@ -24,6 +24,7 @@
 #define ANIMATION_H
 
 #include "graphics/animation.h"
+#include "graphics/dxa_player.h"
 
 #include "sword1/screen.h"
 #include "sword1/sound.h"
@@ -57,15 +58,71 @@
 #define INTRO_LOGO_OVLS 12
 #define INTRO_TEXT_OVLS 8
 
+class MoviePlayer {
+public:
+	MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys);
+	virtual ~MoviePlayer(void);
+	virtual bool load(uint32 id);
+	void play(void);
+	void updatePalette(byte *pal, bool packed = true);
+private:
+	bool checkSkipFrame(void);
+protected:
+	Screen *_scr;
+	Audio::Mixer *_snd;
+	OSystem *_sys;
+
+	uint32 _id;
+
+	byte *_frameBuffer;
+	uint _currentFrame;
+	int _framesSkipped;
+	bool _forceFrame;
+
+	int _frameWidth, _frameHeight;
+	int _frameX, _frameY;
+
+	Audio::SoundHandle _bgSoundHandle;
+	Audio::AudioStream *_bgSoundStream;
+	uint32 _ticks;
+
+	virtual void handleScreenChanged(void);
+	virtual bool initOverlays(uint32 id);
+	virtual bool decodeFrame(void) = 0;
+	virtual void processFrame(void) = 0;
+	virtual void syncFrame(void);
+	virtual void updateScreen(void) = 0;
+};
+
+#ifdef USE_ZLIB
+
+class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
+protected:
+	virtual void setPalette(byte *pal);
+public:
+	MoviePlayerDXA(Screen *scr, Audio::Mixer *snd, OSystem *sys);
+	virtual ~MoviePlayerDXA(void);
+	bool load(uint32 id);
+protected:
+	bool initOverlays(uint32 id);
+	bool decodeFrame(void);
+	void processFrame(void);
+	void updateScreen(void);
+};
+
+#endif 
+
+#ifdef USE_MPEG2 
+
 class AnimationState : public Graphics::BaseAnimationState {
 private:
+	MoviePlayer *_player;
 	Screen *_scr;
 
 public:
-	AnimationState(Screen *scr, Audio::Mixer *snd, OSystem *sys);
-	~AnimationState();
+	AnimationState(MoviePlayer *player, Screen *scr, Audio::Mixer *snd, OSystem *sys);
+	~AnimationState(void);
 	OverlayColor *giveRgbBuffer(void);
-	bool soundFinished();
 
 private:
 	void drawYUV(int width, int height, byte *const *dat);
@@ -78,24 +135,27 @@
 	virtual Audio::AudioStream *createAudioStream(const char *name, void *arg);
 };
 
-class MoviePlayer {
+class MoviePlayerMPEG : public MoviePlayer {
 public:
-	MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys);
-	~MoviePlayer(void);
-	void play(uint32 id);
-private:
+	MoviePlayerMPEG(Screen *scr, Audio::Mixer *snd, OSystem *sys);
+	virtual ~MoviePlayerMPEG(void);
+	bool load(uint32 id);
+protected:
 	void insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor *pal);
-	void processFrame(uint32 animId, AnimationState *anim, uint32 frameNo);
+	AnimationState *_anim;
+	OverlayColor *_introPal;
+	uint8 *_logoOvls[INTRO_LOGO_OVLS];
+
 	bool initOverlays(uint32 id);
-	Screen *_scr;
-	Audio::Mixer *_snd;
-	OSystem *_sys;
-
-	static const char *_sequenceList[20];
-	uint8 *_logoOvls[INTRO_LOGO_OVLS];
-	OverlayColor *_introPal;
+	bool decodeFrame(void);
+	void processFrame(void);
+	void syncFrame(void);
+	void updateScreen(void);
+	void handleScreenChanged(void);
 };
 
+#endif
+
 struct FileQueue {
 	Audio::AudioStream *stream;
 	FileQueue *next;
@@ -114,6 +174,8 @@
 	FileQueue *_queue;
 };
 
+MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem *sys);
+
 } // End of namespace Sword1
 
 #endif

Modified: scummvm/trunk/engines/sword1/logic.cpp
===================================================================
--- scummvm/trunk/engines/sword1/logic.cpp	2006-08-26 11:33:41 UTC (rev 23752)
+++ scummvm/trunk/engines/sword1/logic.cpp	2006-08-26 11:34:35 UTC (rev 23753)
@@ -951,8 +951,12 @@
 		CreditsPlayer player(_system, _mixer);
 		player.play();
 	} else {
-		MoviePlayer player(_screen, _mixer, _system);
-		player.play(sequenceId);
+		MoviePlayer *player = makeMoviePlayer(sequenceId, _screen, _mixer, _system);
+		if (player) {
+			if (player->load(sequenceId))
+				player->play();
+			delete player;
+		}
 	}
 	return SCRIPT_CONT;
 }

Modified: scummvm/trunk/engines/sword1/screen.cpp
===================================================================
--- scummvm/trunk/engines/sword1/screen.cpp	2006-08-26 11:33:41 UTC (rev 23752)
+++ scummvm/trunk/engines/sword1/screen.cpp	2006-08-26 11:34:35 UTC (rev 23753)
@@ -64,6 +64,14 @@
 		quitScreen();
 }
 
+void Screen::clearScreen(void) {
+	if (_screenBuf) {
+		_fullRefresh = true;
+		memset(_screenBuf, 0, _scrnSizeX * _scrnSizeY);
+		_system->copyRectToScreen(_screenBuf, 640, 0, 0, 640, 480);
+	}
+}
+
 void Screen::useTextManager(Text *pTextMan) {
 	_textMan = pTextMan;
 }

Modified: scummvm/trunk/engines/sword1/screen.h
===================================================================
--- scummvm/trunk/engines/sword1/screen.h	2006-08-26 11:33:41 UTC (rev 23752)
+++ scummvm/trunk/engines/sword1/screen.h	2006-08-26 11:34:35 UTC (rev 23753)
@@ -69,6 +69,7 @@
 public:
 	Screen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan);
 	~Screen(void);
+	void clearScreen(void);
 	void useTextManager(Text *pTextMan);
 	void draw(void);
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list