[Scummvm-cvs-logs] SF.net SVN: scummvm: [23420] scummvm/trunk/graphics

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Sat Jul 8 13:42:19 CEST 2006


Revision: 23420
Author:   eriktorbjorn
Date:     2006-07-08 04:42:07 -0700 (Sat, 08 Jul 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=23420&view=rev

Log Message:
-----------
Added support for DXA cutscenes, while still retaining support for the old MPEG
cutscenes and the "dummy" (subtitles and voice-over) mode. Several tweaks and
cleanups were made in this process, and there may very well be regressions, but
it should be stable enough to commit.

Modified Paths:
--------------
    scummvm/trunk/engines/sword2/animation.cpp
    scummvm/trunk/engines/sword2/animation.h
    scummvm/trunk/engines/sword2/function.cpp
    scummvm/trunk/engines/sword2/render.cpp
    scummvm/trunk/engines/sword2/screen.h
    scummvm/trunk/graphics/animation.h
Modified: scummvm/trunk/engines/sword2/animation.cpp
===================================================================
--- scummvm/trunk/engines/sword2/animation.cpp	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/engines/sword2/animation.cpp	2006-07-08 11:42:07 UTC (rev 23420)
@@ -20,9 +20,10 @@
  */
 
 #include "common/stdafx.h"
+#include "common/config-manager.h"
 #include "common/file.h"
-#include "common/config-manager.h"
 #include "common/system.h"
+
 #include "sound/vorbis.h"
 #include "sound/mp3.h"
 
@@ -30,6 +31,7 @@
 #include "sword2/defs.h"
 #include "sword2/header.h"
 #include "sword2/maketext.h"
+#include "sword2/mouse.h"
 #include "sword2/resman.h"
 #include "sword2/screen.h"
 #include "sword2/sound.h"
@@ -37,95 +39,16 @@
 
 namespace Sword2 {
 
-AnimationState::AnimationState(Sword2Engine *vm)
-	: BaseAnimationState(vm->_mixer, vm->_system, 640, 480), _vm(vm) {
-}
+// TODO: The interaction between the basic cutscene player class and the
+//       specific plyers is sometimes a bit awkward, since our classes for
+//       DXA and MPEG decoding are so fundamentally different. The DXA decoder
+//       is just a decoder, while the MPEG decoder has delusions of being a
+//       player. This could probably be simplified quite a bit.
 
-AnimationState::~AnimationState() {
-}
+///////////////////////////////////////////////////////////////////////////////
+// Basic movie player
+///////////////////////////////////////////////////////////////////////////////
 
-#ifdef BACKEND_8BIT
-
-void AnimationState::setPalette(byte *pal) {
-	_vm->_screen->setPalette(0, 256, pal, RDPAL_INSTANT);
-}
-
-#else
-
-void AnimationState::drawTextObject(SpriteInfo *s, byte *src) {
-	int moviePitch = _movieScale * _movieWidth;
-	int textX = _movieScale * s->x;
-	int textY = _movieScale * (_frameHeight - s->h - 12);
-
-	OverlayColor *dst = _overlay + textY * moviePitch + textX;
-
-	OverlayColor pen = _sys->RGBToColor(255, 255, 255);
-	OverlayColor border = _sys->RGBToColor(0, 0, 0);
-
-	// TODO: Use the AdvMame scalers for the text? Pre-scale it?
-
-	for (int y = 0; y < s->h; y++) {
-		OverlayColor *ptr = dst;
-
-		for (int x = 0; x < s->w; x++) {
-			switch (src[x]) {
-			case 1:
-				*ptr++ = border;
-				if (_movieScale > 1) {
-					*ptr++ = border;
-					if (_movieScale > 2)
-						*ptr++ = border;
-				}
-				break;
-			case 255:
-				*ptr++ = pen;
-				if (_movieScale > 1) {
-					*ptr++ = pen;
-					if (_movieScale > 2)
-						*ptr++ = pen;
-				}
-				break;
-			default:
-				ptr += _movieScale;
-				break;
-			}
-		}
-
-		if (_movieScale > 1) {
-			memcpy(dst + moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
-			if (_movieScale > 2)
-				memcpy(dst + 2 * moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
-		}
-
-		dst += _movieScale * moviePitch;
-		src += s->w;
-	}
-}
-
-#endif
-
-void AnimationState::clearScreen() {
-#ifdef BACKEND_8BIT
-	memset(_vm->_screen->getScreen(), 0, _movieWidth * _movieHeight);
-#else
-	OverlayColor black = _sys->RGBToColor(0, 0, 0);
-
-	for (int i = 0; i < _movieScale * _movieWidth * _movieScale * _movieHeight; i++)
-		_overlay[i] = black;
-#endif
-}
-
-void AnimationState::drawYUV(int width, int height, byte *const *dat) {
-	_frameWidth = width;
-	_frameHeight = height;
-
-#ifdef BACKEND_8BIT
-	_vm->_screen->plotYUV(_lut, width, height, dat);
-#else
-	plotYUV(width, height, dat);
-#endif
-}
-
 MovieInfo MoviePlayer::_movies[] = {
 	{ "carib",    222, false },
 	{ "escape",   187, false },
@@ -141,417 +64,752 @@
 	{ "river",    656, false },
 	{ "sailing",  138, false },
 	{ "shaman",   788, true  },
-	{ "stone1",    34, false },
+	{ "stone1",    34, true  },
 	{ "stone2",   282, false },
-	{ "stone3",    65, false },
+	{ "stone3",    65, true  },
 	{ "demo",      60, false },
 	{ "enddemo",  110, false }
 };
 
-MoviePlayer::MoviePlayer(Sword2Engine *vm)
-	: _vm(vm), _snd(_vm->_mixer), _sys(_vm->_system), _textSurface(NULL) {
+MoviePlayer::MoviePlayer(Sword2Engine *vm) {
+	_vm = vm;
+	_mixer = _vm->_mixer;
+	_system = _vm->_system;
+	_textSurface = NULL;
+	_bgSoundStream = NULL;
+	_ticks = 0;
+	_currentFrame = 0;
+	_frameBuffer = NULL;
+	_frameWidth = 0;
+	_frameHeight = 0;
+	_frameX = 0;
+	_frameY = 0;
+	_black = 1;
+	_white = 255;
+	_numFrames = 0;
+	_leadOutFrame = (uint)-1;
+	_seamless = false;
+	_framesSkipped = 0;
+	_forceFrame = false;
+	_textList = NULL;
+	_currentText = 0;
 }
 
-void MoviePlayer::openTextObject(MovieTextObject *obj) {
-	if (obj->textSprite)
-		_vm->_screen->createSurface(obj->textSprite, &_textSurface);
+MoviePlayer::~MoviePlayer() {
 }
 
-void MoviePlayer::closeTextObject(MovieTextObject *obj) {
-	if (_textSurface) {
-		_vm->_screen->deleteSurface(_textSurface);
-		_textSurface = NULL;
+void MoviePlayer::updatePalette(byte *pal, bool packed) {
+	byte palette[4 * 256];
+	byte *p = palette;
+
+	uint32 maxWeight = 0;
+	uint32 minWeight = 0xFFFFFFFF;
+
+	for (int i = 0; i < 256; i++) {
+		int r = *pal++;
+		int g = *pal++;
+		int b = *pal++;
+
+		if (!packed)
+			pal++;
+
+		uint32 weight = 3 * r * r + 6 * g * g + 2 * b * b;
+
+		if (weight >= maxWeight) {
+			_black = i;
+			maxWeight = weight;
+		}
+
+		if (weight <= minWeight) {
+			_white = i;
+			minWeight = i;
+		}
+
+		*p++ = r;
+		*p++ = g;
+		*p++ = b;
+		*p++ = 0;
 	}
+
+	_vm->_screen->setPalette(0, 256, palette, RDPAL_INSTANT);
+	_forceFrame = true;
 }
 
-void MoviePlayer::drawTextObject(AnimationState *anim, MovieTextObject *obj) {
-	if (obj->textSprite && _textSurface) {
-#ifdef BACKEND_8BIT
-		_vm->_screen->drawSurface(obj->textSprite, _textSurface);
-#else
-		if (anim)
-			anim->drawTextObject(obj->textSprite, _textSurface);
-		else
-			_vm->_screen->drawSurface(obj->textSprite, _textSurface);
-#endif
-	}
+void MoviePlayer::savePalette() {
+	memcpy(_originalPalette, _vm->_screen->getPalette(), sizeof(_originalPalette));
 }
 
-/**
- * Plays an animated cutscene.
- * @param filename the file name of the cutscene file
- * @param text the subtitles and voiceovers for the cutscene
- * @param leadInRes lead-in music resource id
- * @param leadOutRes lead-out music resource id
- */
+void MoviePlayer::restorePalette() {
+	_vm->_screen->setPalette(0, 256, _originalPalette, RDPAL_INSTANT);
+}
 
-int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], int32 leadInRes, int32 leadOutRes) {
-	Audio::SoundHandle leadInHandle;
+void MoviePlayer::clearScreen() {
+	_vm->_screen->clearScene();
+	_system->copyRectToScreen(_vm->_screen->getScreen(), _vm->_screen->getScreenWide(), 0, 0, _vm->_screen->getScreenWide(), _vm->_screen->getScreenDeep());
+}
 
-	// This happens if the user quits during the "eye" smacker
-	if (_vm->_quit)
-		return RD_OK;
+void MoviePlayer::updateScreen() {
+	_system->updateScreen();
+}
 
-	if (leadInRes) {
-		byte *leadIn = _vm->_resman->openResource(leadInRes);
-		uint32 leadInLen = _vm->_resman->fetchLen(leadInRes) - ResHeader::size();
+bool MoviePlayer::checkSkipFrame() {
+	if (_forceFrame) {
+		_forceFrame = false;
+		return false;
+	}
 
-		assert(_vm->_resman->fetchType(leadIn) == WAV_FILE);
+	if (_framesSkipped > 10) {
+		warning("Forced frame %d to be displayed", _currentFrame);
+		_framesSkipped = 0;
+		return false;
+	}
 
-		leadIn += ResHeader::size();
-
-		_vm->_sound->playFx(&leadInHandle, leadIn, leadInLen, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType);
+	if (_bgSoundStream) {
+		if ((_mixer->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame + 1)
+			return false;
+	} else {
+		if (_system->getMillis() <= _ticks)
+			return false;
 	}
 
-	byte *leadOut = NULL;
-	uint32 leadOutLen = 0;
+	_framesSkipped++;
+	return true;
+}
 
-	if (leadOutRes) {
-		leadOut = _vm->_resman->openResource(leadOutRes);
-		leadOutLen = _vm->_resman->fetchLen(leadOutRes) - ResHeader::size();
+void MoviePlayer::waitForFrame() {
+	if (_bgSoundStream) {
+		while (_mixer->isSoundHandleActive(_bgSoundHandle) && (_mixer->getSoundElapsedTime(_bgSoundHandle) * 12) / 1000 < _currentFrame) {
+			_system->delayMillis(10);
+		}
 
-		assert(_vm->_resman->fetchType(leadOut) == WAV_FILE);
+		// 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.
 
-		leadOut += ResHeader::size();
+		_ticks = _system->getMillis();
+	} else {
+		while (_system->getMillis() < _ticks) {
+			_system->delayMillis(10);
+		}
 	}
+}
 
-	_leadOutFrame = (uint)-1;
+void MoviePlayer::drawFrame() {
+	_ticks += 83;
 
-	int i;
-
-	for (i = 0; i < ARRAYSIZE(_movies); i++) {
-		if (scumm_stricmp(filename, _movies[i].name) == 0) {
-			_seamless = _movies[i].seamless;
-			if (_movies[i].frames > 60)
-				_leadOutFrame = _movies[i].frames - 60;
-			break;
-		}
+	if (checkSkipFrame()) {
+		warning("Skipped frame %d", _currentFrame);
+		return;
 	}
 
-	if (i == ARRAYSIZE(_movies))
-		warning("Unknown movie, '%s'", filename);
+	waitForFrame();
 
-#ifdef USE_MPEG2
-	playMPEG(filename, text, leadOut, leadOutLen);
-#else
-	// No MPEG2? Use the old 'Narration Only' hack
-	playDummy(filename, text, leadOut, leadOutLen);
-#endif
+	int screenWidth = _vm->_screen->getScreenWide();
 
-	_snd->stopHandle(leadInHandle);
+	_system->copyRectToScreen(_frameBuffer + _frameY * screenWidth + _frameX, screenWidth, _frameX, _frameY, _frameWidth, _frameHeight);
+	_vm->_screen->setNeedFullRedraw();
+}
 
-	// Wait for the lead-out to stop, if there is any. Though don't do it
-	// for seamless movies, since they are meant to blend into the rest of
-	// the game.
+void MoviePlayer::openTextObject(MovieTextObject *t) {
+	if (t->textSprite) {
+		_vm->_screen->createSurface(t->textSprite, &_textSurface);
+	}
+}
 
-	if (!_seamless) {
-		while (_vm->_mixer->isSoundHandleActive(_leadOutHandle)) {
-			_vm->_screen->updateDisplay();
-			_vm->_system->delayMillis(30);
+void MoviePlayer::closeTextObject(MovieTextObject *t) {
+	if (_textSurface) {
+		_vm->_screen->deleteSurface(_textSurface);
+		_textSurface = NULL;
+	}
+}
+
+void MoviePlayer::drawTextObject(MovieTextObject *t) {
+	if (t->textSprite && _textSurface) {
+		int screenWidth = _vm->_screen->getScreenWide();
+		byte *src = t->textSprite->data;
+		byte *dst = _frameBuffer + (_frameY + _frameHeight - t->textSprite->h - 20) * screenWidth + _frameX + (_frameWidth - t->textSprite->w) / 2;
+
+		for (int y = 0; y < t->textSprite->h; y++) {
+			for (int x = 0; x < t->textSprite->w; x++) {
+				if (src[x] == 1)
+					dst[x] = _white;
+				else if (src[x] == 255)
+					dst[x] = _black;
+			}
+			src += t->textSprite->w;
+			dst += screenWidth;
 		}
 	}
+}
 
-	if (leadInRes)
-		_vm->_resman->closeResource(leadInRes);
+void MoviePlayer::undrawTextObject(MovieTextObject *t) {
+}
 
-	if (leadOutRes)
-		_vm->_resman->closeResource(leadOutRes);
+bool MoviePlayer::load(const char *name, MovieTextObject *text[]) {
+	_bgSoundStream = NULL;
+	_textList = text;
+	_currentText = 0;
+	_currentFrame = 0;
 
-	return RD_OK;
+	for (int i = 0; i < ARRAYSIZE(_movies); i++) {
+		if (scumm_stricmp(name, _movies[i].name) == 0) {
+			_seamless = _movies[i].seamless;
+			_numFrames = _movies[i].frames;
+			if (_numFrames > 60)
+				_leadOutFrame = _numFrames - 60;
+			return true;
+		}
+	}
+
+	return false;
 }
 
-void MoviePlayer::playMPEG(const char *filename, MovieTextObject *text[], byte *leadOut, uint32 leadOutLen) {
-	uint frameCounter = 0, textCounter = 0;
-	Audio::SoundHandle handle;
-	bool skipCutscene = false, textVisible = false;
+void MoviePlayer::play(int32 leadIn, int32 leadOut) {
+	bool terminate = false;
+	bool textVisible = false;
+	bool startNextText = false;
+	byte *data;
+	uint32 len;
+	Audio::SoundHandle leadInHandle, leadOutHandle;
 	uint32 flags = Audio::Mixer::FLAG_16BITS;
-	bool startNextText = false;
 
-	byte oldPal[256 * 4];
-	memcpy(oldPal, _vm->_screen->getPalette(), sizeof(oldPal));
+	// This happens if the user quits during the "eye" cutscene.
+	if (_vm->_quit)
+		return;
 
-	AnimationState *anim = new AnimationState(_vm);
+	if (leadIn) {
+		data = _vm->_resman->openResource(leadIn);
+		len = _vm->_resman->fetchLen(leadIn) - ResHeader::size();
 
-	if (!anim->init(filename)) {
-		delete anim;
-		anim = NULL;
-		// Missing Files? Use the old 'Narration Only' hack
-		playDummy(filename, text, leadOut, leadOutLen);
-		return;
+		assert(_vm->_resman->fetchType(data) == WAV_FILE);
+
+		data += ResHeader::size();
+
+		_vm->_sound->playFx(&leadInHandle, data, len, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType);
 	}
 
-	// Clear the screen, because whatever is on it will be visible when the
-	// overlay is removed. And if there isn't an overlay, we don't want it
-	// to be visible during the cutscene. (Not all cutscenes cover the
-	// entire screen.)
-	_vm->_screen->clearScene();
+	savePalette();
+
+	// Not all cutscenes cover the entire screen, so clear it. We will
+	// always clear the game screen, no matter how the cutscene is to be
+	// displayed.
+
+	_vm->_mouse->closeMenuImmediately();
+
+	if (!_seamless) {
+		_vm->_screen->clearScene();
+	}
+
 	_vm->_screen->updateDisplay();
 
 #ifndef SCUMM_BIG_ENDIAN
 	flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
 #endif
 
-	while (!skipCutscene && anim->decodeFrame()) {
-		// The frame has been drawn. Now draw the subtitles, if any,
-		// before updating the screen.
+	_framesSkipped = 0;
 
-		if (text && text[textCounter]) {
-			if (frameCounter == text[textCounter]->startFrame) {
-				openTextObject(text[textCounter]);
+	_ticks = _system->getMillis();
+
+	if (_bgSoundStream) {
+		_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSoundHandle, _bgSoundStream);
+	}
+
+	while (!terminate && _currentFrame < _numFrames && decodeFrame()) {
+		_currentFrame++;
+
+		// The frame has been decoded. Now draw the subtitles, if any,
+		// before drawing it to the screen.
+
+		if (_textList && _textList[_currentText]) {
+			MovieTextObject *t = _textList[_currentText];
+
+			if (_currentFrame == t->startFrame) {
+				openTextObject(t);
 				textVisible = true;
 
-				if (text[textCounter]->speech) {
+				if (t->speech) {
 					startNextText = true;
 				}
 			}
 
-			if (startNextText && !_snd->isSoundHandleActive(handle)) {
-				_snd->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
+			if (startNextText && !_mixer->isSoundHandleActive(_speechHandle)) {
+				_mixer->playRaw(&_speechHandle, t->speech, t->speechBufferSize, 22050, flags);
 				startNextText = false;
 			}
 
-			if (frameCounter == text[textCounter]->endFrame) {
-				closeTextObject(text[textCounter]);
-				textCounter++;
+			if (_currentFrame == t->endFrame) {
+				undrawTextObject(t);
+				closeTextObject(t);
+				_currentText++;
 				textVisible = false;
 			}
 
 			if (textVisible)
-				drawTextObject(anim, text[textCounter]);
+				drawTextObject(t);
 		}
 
-#ifdef BACKEND_8BIT
-		_sys->copyRectToScreen(_vm->_screen->getScreen(), 640, 0, 0, 640, 480);
-#endif
+		if (leadOut && _currentFrame == _leadOutFrame) {
+			data = _vm->_resman->openResource(leadOut);
+			len = _vm->_resman->fetchLen(leadOut) - ResHeader::size();
 
-		anim->updateScreen();
-		frameCounter++;
+			assert(_vm->_resman->fetchType(data) == WAV_FILE);
 
-		if (frameCounter == _leadOutFrame && leadOut)
-			_vm->_sound->playFx(&_leadOutHandle, leadOut, leadOutLen, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType);
+			data += ResHeader::size();
 
+			_vm->_sound->playFx(&leadOutHandle, data, len, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType);
+		}
+
+		drawFrame();
+		updateScreen();
+
 		OSystem::Event event;
-		while (_sys->pollEvent(event)) {
+
+		while (_system->pollEvent(event)) {
 			switch (event.type) {
 			case OSystem::EVENT_SCREEN_CHANGED:
-				anim->handleScreenChanged();
+				handleScreenChanged();
 				break;
+			case OSystem::EVENT_QUIT:
+				_vm->closeGame();
+				terminate = true;
+				break;
 			case OSystem::EVENT_KEYDOWN:
 				if (event.kbd.keycode == 27)
-					skipCutscene = true;
+					terminate = true;
 				break;
-			case OSystem::EVENT_QUIT:
-				_vm->closeGame();
-				skipCutscene = true;
-				break;
 			default:
 				break;
 			}
 		}
 	}
 
-	if (!skipCutscene) {
-		// Sleep for one frame so that the last frame is displayed.
-		_sys->delayMillis(1000 / 12);
-	}
-
 	if (!_seamless) {
-		// Most movies fade to black on their own, but not all of them.
-		// Since we may be hanging around in the cutscene player for a
-		// while longer, waiting for the lead-out sound to finish,
-		// paint the overlay black.
+		// Most cutscenes fade to black on their own, but not all of
+		// them. I think it looks better if they do.
 
-		anim->clearScreen();
-	}
+		clearScreen();
 
-	// If the speech is still playing, redraw the subtitles. At least in
-	// the English version this is most noticeable in the "carib" cutscene.
+		// If the sound is still playing, draw the subtitles one final
+		// time. This happens in the "carib" cutscene.
 
-	if (textVisible && _snd->isSoundHandleActive(handle))
-		drawTextObject(anim, text[textCounter]);
+		if (textVisible && _mixer->isSoundHandleActive(_speechHandle)) {
+			drawTextObject(_textList[_currentText]);
+		}
 
-	if (text)
-		closeTextObject(text[textCounter]);
+		updateScreen();
+	}
 
-	anim->updateScreen();
+	if (!terminate) {
+		// Wait for the voice to stop playing. This is to make sure
+		// that we don't cut off the speech in mid-sentence, and - even
+		// more importantly - that we don't free the sound buffer while
+		// it's still in use.
 
-	// Wait for the voice to stop playing. This is to make sure that we
-	// don't cut off the speech in mid-sentence, and - even more
-	// importantly - that we don't free the sound buffer while it's in use.
+		while (_mixer->isSoundHandleActive(_speechHandle)) {
+			_system->delayMillis(100);
+		}
 
-	if (skipCutscene)
-		_snd->stopHandle(handle);
-
-	while (_snd->isSoundHandleActive(handle)) {
-		_vm->_screen->updateDisplay(false);
-		_sys->delayMillis(100);
+		while (_mixer->isSoundHandleActive(_bgSoundHandle)) {
+			_system->delayMillis(100);
+		}
+	} else {
+		_mixer->stopHandle(_speechHandle);
+		_mixer->stopHandle(_bgSoundHandle);
 	}
 
 	if (!_seamless) {
-		// Clear the screen again
-		anim->clearScreen();
-		anim->updateScreen();
+		clearScreen();
+		updateScreen();
 	}
 
-	_vm->_screen->setPalette(0, 256, oldPal, RDPAL_INSTANT);
+	// Setting the palette implies a full redraw.
+	restorePalette();
+}
 
-	delete anim;
-	anim = NULL;
+#ifdef USE_ZLIB
+
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for the new DXA movies
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayerDXA::MoviePlayerDXA(Sword2Engine *vm) : MoviePlayer(vm) {
+	debug(0, "Creating DXA cutscene player");
 }
 
-/**
- * This just plays the cutscene with voiceovers / subtitles, in case the files
- * are missing.
- */
+MoviePlayerDXA::~MoviePlayerDXA() {
+	closeFile();
+}
 
-void MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], byte *leadOut, uint32 leadOutLen) {
-	if (!text)
-		return;
+void MoviePlayerDXA::setPalette(byte *pal) {
+	updatePalette(pal);
+}
 
-	int frameCounter = 0, textCounter = 0;
+bool MoviePlayerDXA::decodeFrame() {
+	decodeNextFrame();
+	copyFrameToBuffer(_frameBuffer, _frameX, _frameY, _vm->_screen->getScreenWide());
+	return true;
+}
 
-	byte oldPal[256 * 4];
-	byte tmpPal[256 * 4];
+bool MoviePlayerDXA::load(const char *name, MovieTextObject *text[]) {
+	if (!MoviePlayer::load(name, text))
+		return false;
 
-	_vm->_screen->clearScene();
+	char filename[20];
 
-	// HACK: Draw instructions
-	//
-	// I'm using the the menu area, because that's unlikely to be touched
-	// by anything else during the cutscene.
+	snprintf(filename, sizeof(filename), "%s.dxa", name);
 
-	memset(_vm->_screen->getScreen(), 0, _vm->_screen->getScreenWide() * MENUDEEP);
+	if (loadFile(filename)) {
+		// The Broken Sword games always use external audio tracks.
+		if (_fd.readUint32BE() != MKID_BE('NULL'))
+			return false;
 
-	byte *data;
+		_frameBuffer = _vm->_screen->getScreen();
 
-	// Russian version substituted latin characters with cyrillic. That's
-	// why it renders completely unreadable with default message
-	if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
-		byte msg[] = "Po\344uk - to\344\345ko pev\345: hagmute k\344abuwy Ucke\343n, u\344u nocetute ca\343t npoekta u ckava\343te budeo po\344uku";
-		data = _vm->_fontRenderer->makeTextSprite(msg, RENDERWIDE, 255, _vm->_speechFontId);
-	} else {
-		// TODO: Translate message to other languages?
-#ifdef USE_MPEG2
-		byte msg[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos";
+		_frameWidth = getWidth();
+		_frameHeight = getHeight();
+
+		_frameX = (_vm->_screen->getScreenWide() - _frameWidth) / 2;
+		_frameY = (_vm->_screen->getScreenDeep() - _frameHeight) / 2;
+
+		_bgSoundStream = Audio::AudioStream::openStreamFile(name);
+
+		return true;
+	}
+
+	return false;
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Movie player for the old MPEG movies
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayerMPEG::MoviePlayerMPEG(Sword2Engine *vm) : MoviePlayer(vm) {
+#ifdef BACKEND_8BIT
+	debug(0, "Creating MPEG cutscene player (8-bit)");
 #else
-		byte msg[] = "Cutscene - Narration Only: Press ESC to exit, or recompile ScummVM with MPEG2 support";
+	debug(0, "Creating MPEG cutscene player (16-bit)");
 #endif
+}
 
-		data = _vm->_fontRenderer->makeTextSprite(msg, RENDERWIDE, 255, _vm->_speechFontId);
+MoviePlayerMPEG::~MoviePlayerMPEG() {
+	delete _anim;
+	_anim = NULL;
+}
+
+bool MoviePlayerMPEG::load(const char *name, MovieTextObject *text[]) {
+	if (!MoviePlayer::load(name, text))
+		return false;
+
+	_anim = new AnimationState(_vm, this);
+
+	if (!_anim->init(name)) {
+		delete _anim;
+		_anim = NULL;
+		return false;
 	}
 
-	FrameHeader frame_head;
-	SpriteInfo msgSprite;
-	byte *msgSurface;
+#ifdef BACKEND_8BIT
+	_frameBuffer = _vm->_screen->getScreen();
+#endif
 
-	frame_head.read(data);
+	return true;
+}
 
-	msgSprite.x = _vm->_screen->getScreenWide() / 2 - frame_head.width / 2;
-	msgSprite.y = MENUDEEP / 2 - frame_head.height / 2;
-	msgSprite.w = frame_head.width;
-	msgSprite.h = frame_head.height;
-	msgSprite.type = RDSPR_NOCOMPRESSION;
-	msgSprite.data = data + FrameHeader::size();
+bool MoviePlayerMPEG::checkSkipFrame() {
+	return false;
+}
 
-	_vm->_screen->createSurface(&msgSprite, &msgSurface);
-	_vm->_screen->drawSurface(&msgSprite, msgSurface);
-	_vm->_screen->deleteSurface(msgSurface);
+void MoviePlayerMPEG::waitForFrame() {
+}
 
-	free(data);
+bool MoviePlayerMPEG::decodeFrame() {
+	bool result = _anim->decodeFrame();
 
-	// In case the cutscene has a long lead-in, start just before the first
-	// line of text.
+#ifdef BACKEND_8BIT
+	_frameWidth = _anim->getFrameWidth();
+	_frameHeight = _anim->getFrameHeight();
 
-	frameCounter = text[0]->startFrame - 12;
+	_frameX = (_vm->_screen->getScreenWide() - _frameWidth) / 2;
+	_frameY = (_vm->_screen->getScreenDeep() - _frameHeight) / 2;
+#endif
 
-	// Fake a palette that will hopefully make the text visible. In the
-	// opening cutscene it seems to use colours 1 (black) and 255 (white).
+	return result;
+}
 
-	memcpy(oldPal, _vm->_screen->getPalette(), sizeof(oldPal));
-	memset(tmpPal, 0, sizeof(tmpPal));
-	tmpPal[255 * 4 + 0] = 255;
-	tmpPal[255 * 4 + 1] = 255;
-	tmpPal[255 * 4 + 2] = 255;
-	_vm->_screen->setPalette(0, 256, tmpPal, RDPAL_INSTANT);
+#ifndef BACKEND_8BIT
+void MoviePlayerMPEG::handleScreenChanged() {
+	_anim->handleScreenChanged();
+}
 
-	Audio::SoundHandle handle;
+void MoviePlayerMPEG::clearScreen() {
+	_anim->clearScreen();
+}
 
-	bool skipCutscene = false;
+void MoviePlayerMPEG::drawFrame() {
+}
 
-	uint32 flags = Audio::Mixer::FLAG_16BITS;
+void MoviePlayerMPEG::updateScreen() {
+	_anim->updateScreen();
+}
 
-#ifndef SCUMM_BIG_ENDIAN
-	flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
+void MoviePlayerMPEG::drawTextObject(MovieTextObject *t) {
+	if (t->textSprite && _textSurface) {
+		_anim->drawTextObject(t->textSprite, _textSurface);
+	}
+}
 #endif
 
-	while (1) {
-		if (!text[textCounter])
-			break;
+AnimationState::AnimationState(Sword2Engine *vm, MoviePlayer *player)
+	: BaseAnimationState(vm->_mixer, vm->_system, 640, 480) {
+	_vm = vm;
+	_player = player;
+}
 
-		if (frameCounter == text[textCounter]->startFrame) {
-			_vm->_screen->clearScene();
-			openTextObject(text[textCounter]);
-			drawTextObject(NULL, text[textCounter]);
-			if (text[textCounter]->speech) {
-				_snd->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
+AnimationState::~AnimationState() {
+}
+
+#ifdef BACKEND_8BIT
+void AnimationState::setPalette(byte *pal) {
+	_player->updatePalette(pal, false);
+}
+#else
+
+void AnimationState::drawTextObject(SpriteInfo *s, byte *src) {
+	int moviePitch = _movieScale * _movieWidth;
+	int textX = _movieScale * s->x;
+	int textY = _movieScale * (_frameHeight - s->h - 12);
+
+	OverlayColor *dst = _overlay + textY * moviePitch + textX;
+
+	OverlayColor pen = _sys->RGBToColor(255, 255, 255);
+	OverlayColor border = _sys->RGBToColor(0, 0, 0);
+
+	// TODO: Use the AdvMame scalers for the text? Pre-scale it?
+
+	for (int y = 0; y < s->h; y++) {
+		OverlayColor *ptr = dst;
+
+		for (int x = 0; x < s->w; x++) {
+			switch (src[x]) {
+			case 1:
+				*ptr++ = border;
+				if (_movieScale > 1) {
+					*ptr++ = border;
+					if (_movieScale > 2)
+						*ptr++ = border;
+				}
+				break;
+			case 255:
+				*ptr++ = pen;
+				if (_movieScale > 1) {
+					*ptr++ = pen;
+					if (_movieScale > 2)
+						*ptr++ = pen;
+				}
+				break;
+			default:
+				ptr += _movieScale;
+				break;
 			}
 		}
 
-		if (frameCounter == text[textCounter]->endFrame) {
-			closeTextObject(text[textCounter]);
-			_vm->_screen->clearScene();
-			_vm->_screen->setNeedFullRedraw();
-			textCounter++;
+		if (_movieScale > 1) {
+			memcpy(dst + moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
+			if (_movieScale > 2)
+				memcpy(dst + 2 * moviePitch, dst, _movieScale * s->w * sizeof(OverlayColor));
 		}
 
-		frameCounter++;
-		_vm->_screen->updateDisplay();
+		dst += _movieScale * moviePitch;
+		src += s->w;
+	}
+}
 
-		KeyboardEvent *ke = _vm->keyboardEvent();
+#endif
 
-		if ((ke && ke->keycode == 27) || _vm->_quit) {
-			_snd->stopHandle(handle);
-			skipCutscene = true;
-			break;
+void AnimationState::clearScreen() {
+#ifdef BACKEND_8BIT
+	memset(_vm->_screen->getScreen(), 0, _movieWidth * _movieHeight);
+#else
+	OverlayColor black = _sys->RGBToColor(0, 0, 0);
+
+	for (int i = 0; i < _movieScale * _movieWidth * _movieScale * _movieHeight; i++)
+		_overlay[i] = black;
+#endif
+}
+
+void AnimationState::drawYUV(int width, int height, byte *const *dat) {
+	_frameWidth = width;
+	_frameHeight = height;
+
+#ifdef BACKEND_8BIT
+	byte *buf = _vm->_screen->getScreen() + ((480 - height) / 2) * RENDERWIDE + (640 - width) / 2;
+
+	int x, y;
+
+	int ypos = 0;
+	int cpos = 0;
+	int linepos = 0;
+
+	for (y = 0; y < height; y += 2) {
+		for (x = 0; x < width; x += 2) {
+			int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH + 1)) + ((dat[1][cpos] + ROUNDADD) >> SHIFT)) * (BITDEPTH + 1);
+			cpos++;
+
+			buf[linepos               ] = _lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
+			buf[RENDERWIDE + linepos++] = _lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
+			buf[linepos               ] = _lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
+			buf[RENDERWIDE + linepos++] = _lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
 		}
+		linepos += (2 * RENDERWIDE - width);
+		ypos += width;
+	}
+#else
+	plotYUV(width, height, dat);
+#endif
+}
 
-		// Simulate ~12 frames per second. I don't know what frame rate
-		// the original movies had, or even if it was constant, but
-		// this seems to work reasonably.
+///////////////////////////////////////////////////////////////////////////////
+// Dummy player for subtitled speech only
+///////////////////////////////////////////////////////////////////////////////
 
-		_sys->delayMillis(90);
+MoviePlayerDummy::MoviePlayerDummy(Sword2Engine *vm) : MoviePlayer(vm) {
+	debug(0, "Creating Dummy cutscene player");
+}
+
+MoviePlayerDummy::~MoviePlayerDummy() {
+}
+
+bool MoviePlayerDummy::load(const char *name, MovieTextObject *text[]) {
+	if (!MoviePlayer::load(name, text))
+		return false;
+
+	_frameBuffer = _vm->_screen->getScreen();
+
+	_frameWidth = 640;
+	_frameHeight = 400;
+	_frameX = 0;
+	_frameY = 40;
+
+	return true;
+}
+
+bool MoviePlayerDummy::decodeFrame() {
+	if (_currentFrame == 0 && _textList) {
+		byte dummyPalette[] = {
+			  0,   0,   0, 0,
+			255, 255, 255, 0,
+		};
+
+		// 0 is always black
+		// 1 is the border colour - black
+		// 255 is the pen colour - white
+
+		_system->setPalette(dummyPalette, 0, 1);
+		_system->setPalette(dummyPalette, 1, 1);
+		_system->setPalette(dummyPalette + 4, 255, 1);
+
+		byte msgNoCutscenesRU[] = "Po\344uk - to\344\345ko pev\345: hagmute k\344abuwy Ucke\343n, u\344u nocetute ca\343t npoekta u ckava\343te budeo po\344uku";
+
+#if defined(USE_MPEG2) || defined(USE_ZLIB)
+		byte msgNoCutscenes[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos";
+#else
+		byte msgNoCutscenes[] = "Cutscene - Narration Only: Press ESC to exit, or recompile ScummVM with MPEG2 or ZLib support");
+#endif
+
+		byte *msg;
+
+		// Russian version substituted latin characters with Cyrillic.
+		if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
+			msg = msgNoCutscenesRU;
+		} else {
+			msg = msgNoCutscenes;
+		}
+
+		byte *data = _vm->_fontRenderer->makeTextSprite(msg, RENDERWIDE, 255, _vm->_speechFontId);
+
+		FrameHeader frame_head;
+		SpriteInfo msgSprite;
+		byte *msgSurface;
+
+		frame_head.read(data);
+
+		msgSprite.x = _vm->_screen->getScreenWide() / 2 - frame_head.width / 2;
+		msgSprite.y = (480 - frame_head.height) / 2;
+		msgSprite.w = frame_head.width;
+		msgSprite.h = frame_head.height;
+		msgSprite.type = RDSPR_NOCOMPRESSION;
+		msgSprite.data = data + FrameHeader::size();
+
+		_vm->_screen->createSurface(&msgSprite, &msgSurface);
+		_vm->_screen->drawSurface(&msgSprite, msgSurface);
+		_vm->_screen->deleteSurface(msgSurface);
+
+		free(data);
+		updateScreen();
 	}
 
-	// Wait for the voice to stop playing. This is to make sure that we
-	// don't cut off the speech in mid-sentence, and - even more
-	// importantly - that we don't free the sound buffer while it's in use.
+	// If we have played the final voice-over, skip ahead to the lead out
 
-	while (_snd->isSoundHandleActive(handle)) {
-		_vm->_screen->updateDisplay(false);
-		_sys->delayMillis(100);
+	if (_textList && !_textList[_currentText] && !_mixer->isSoundHandleActive(_speechHandle) && _leadOutFrame != (uint)-1 && _currentFrame < _leadOutFrame) {
+		_currentFrame = _leadOutFrame - 1;
 	}
 
-	closeTextObject(text[textCounter]);
+	return true;
+}
 
-	_vm->_screen->clearScene();
-	_vm->_screen->setNeedFullRedraw();
+bool MoviePlayerDummy::checkSkipFrame() {
+	return false;
+}
 
-	// HACK: Remove the instructions created above
-	Common::Rect r;
+void MoviePlayerDummy::waitForFrame() {
+	if (!_textList || _currentFrame < _textList[0]->startFrame) {
+		_ticks = _system->getMillis();
+		return;
+	}
 
-	memset(_vm->_screen->getScreen(), 0, _vm->_screen->getScreenWide() * MENUDEEP);
-	r.left = r.top = 0;
-	r.right = _vm->_screen->getScreenWide();
-	r.bottom = MENUDEEP;
-	_vm->_screen->updateRect(&r);
+	MoviePlayer::waitForFrame();
+}
 
-	// FIXME: For now, only play the lead-out music for cutscenes that have
-	// subtitles.
+void MoviePlayerDummy::drawFrame() {
+	_ticks += 83;
+	waitForFrame();
+}
 
-	if (!skipCutscene && leadOut)
-		_vm->_sound->playFx(&_leadOutHandle, leadOut, leadOutLen, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType);
+void MoviePlayerDummy::drawTextObject(MovieTextObject *t) {
+	_vm->_screen->drawSurface(t->textSprite, _textSurface);
+}
 
-	_vm->_screen->setPalette(0, 256, oldPal, RDPAL_INSTANT);
+void MoviePlayerDummy::undrawTextObject(MovieTextObject *t) {
+	memset(_textSurface, 1, t->textSprite->w * t->textSprite->h);
+	drawTextObject(t);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// Factory function for creating the appropriate cutscene player
+///////////////////////////////////////////////////////////////////////////////
+
+MoviePlayer *makeMoviePlayer(Sword2Engine *vm, const char *name) {
+	char filename[20];
+
+#ifdef USE_ZLIB
+	snprintf(filename, sizeof(filename), "%s.dxa", name);
+
+	if (Common::File::exists(filename)) {
+		return new MoviePlayerDXA(vm);
+	}
+#endif
+
+#ifdef USE_MPEG2
+	snprintf(filename, sizeof(filename), "%s.mp2", name);
+
+	if (Common::File::exists(filename)) {
+		return new MoviePlayerMPEG(vm);
+	}
+#endif
+
+	return new MoviePlayerDummy(vm);
+}
+
 } // End of namespace Sword2

Modified: scummvm/trunk/engines/sword2/animation.h
===================================================================
--- scummvm/trunk/engines/sword2/animation.h	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/engines/sword2/animation.h	2006-07-08 11:42:07 UTC (rev 23420)
@@ -23,6 +23,7 @@
 #define SWORD2_ANIMATION_H
 
 #include "graphics/animation.h"
+#include "graphics/dxa_player.h"
 #include "sound/mixer.h"
 
 namespace Sword2 {
@@ -41,12 +42,97 @@
 	uint16 *speech;
 };
 
+struct MovieInfo {
+	const char *name;
+	const uint frames;
+	const bool seamless;
+};
+
+class MoviePlayer {
+protected:
+	Sword2Engine *_vm;
+	Audio::Mixer *_mixer;
+	OSystem *_system;
+
+	byte _originalPalette[4 * 256];
+
+	byte *_textSurface;
+
+	Audio::SoundHandle _speechHandle;
+	Audio::SoundHandle _bgSoundHandle;
+	Audio::AudioStream *_bgSoundStream;
+
+	uint32 _ticks;
+
+	uint _currentFrame;
+	byte *_frameBuffer;
+	int _frameWidth, _frameHeight;
+	int _frameX, _frameY;
+
+	byte _black, _white;
+
+	uint _numFrames;
+	uint _leadOutFrame;
+	bool _seamless;
+
+	int _framesSkipped;
+	bool _forceFrame;
+
+	static struct MovieInfo _movies[];
+
+	MovieTextObject **_textList;
+	int _currentText;
+
+	void savePalette();
+	void restorePalette();
+
+	void openTextObject(MovieTextObject *t);
+	void closeTextObject(MovieTextObject *t);
+
+	virtual void handleScreenChanged() {}
+
+	virtual void clearScreen();
+	virtual void updateScreen();
+	virtual bool decodeFrame() = 0;
+	virtual bool checkSkipFrame();
+	virtual void waitForFrame();
+	virtual void drawFrame();
+	virtual void drawTextObject(MovieTextObject *t);
+	virtual void undrawTextObject(MovieTextObject *t);
+
+public:
+	MoviePlayer(Sword2Engine *vm);
+	virtual ~MoviePlayer();
+
+	void updatePalette(byte *pal, bool packed = true);
+	virtual bool load(const char *name, MovieTextObject *text[]);
+	void play(int32 leadIn, int32 leadOut);
+};
+
+class MoviePlayerDummy : public MoviePlayer {
+protected:
+	virtual bool decodeFrame();
+	virtual bool checkSkipFrame();
+	virtual void waitForFrame();
+	virtual void drawFrame();
+	virtual void drawTextObject(MovieTextObject *t);
+	virtual void undrawTextObject(MovieTextObject *t);
+
+public:
+	MoviePlayerDummy(Sword2Engine *vm);
+	virtual ~MoviePlayerDummy();
+
+	virtual bool load(const char *name, MovieTextObject *text[]);
+};
+
+#ifdef USE_MPEG2
 class AnimationState : public ::Graphics::BaseAnimationState {
 private:
 	Sword2Engine *_vm;
+	MoviePlayer *_player;
 
 public:
-	AnimationState(Sword2Engine *vm);
+	AnimationState(Sword2Engine *vm, MoviePlayer *player);
 	~AnimationState();
 
 #ifndef BACKEND_8BIT
@@ -63,39 +149,46 @@
 #endif
 };
 
-struct MovieInfo {
-	char name[9];
-	uint frames;
-	bool seamless;
-};
+class MoviePlayerMPEG : public MoviePlayer {
+protected:
+	AnimationState *_anim;
 
-class MoviePlayer {
-private:
-	Sword2Engine *_vm;
-	Audio::Mixer *_snd;
-	OSystem *_sys;
+	virtual bool checkSkipFrame();
+	virtual void waitForFrame();
+	virtual bool decodeFrame();
 
-	byte *_textSurface;
+#ifndef BACKEND_8BIT
+	virtual void handleScreenChanged();
+	virtual void clearScreen();
+	virtual void drawFrame();
+	virtual void updateScreen();
+	virtual void drawTextObject(MovieTextObject *t);
+#endif
 
-	Audio::SoundHandle _leadOutHandle;
+public:
+	MoviePlayerMPEG(Sword2Engine *vm);
+	virtual ~MoviePlayerMPEG();
 
-	uint _leadOutFrame;
-	bool _seamless;
+	virtual bool load(const char *name, MovieTextObject *text[]);
+};
+#endif
 
-	static struct MovieInfo _movies[];
+#ifdef USE_ZLIB
+class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
+protected:
+	virtual void setPalette(byte *pal);
+	virtual bool decodeFrame();
 
-	void openTextObject(MovieTextObject *obj);
-	void closeTextObject(MovieTextObject *obj);
-	void drawTextObject(AnimationState *anim, MovieTextObject *obj);
+public:
+	MoviePlayerDXA(Sword2Engine *vm);
+	virtual ~MoviePlayerDXA();
 
-	void playMPEG(const char *filename, MovieTextObject *text[], byte *leadOut, uint32 leadOutLen);
-	void playDummy(const char *filename, MovieTextObject *text[], byte *leadOut, uint32 leadOutLen);
-
-public:
-	MoviePlayer(Sword2Engine *vm);
-	int32 play(const char *filename, MovieTextObject *text[], int32 leadInRes, int32 leadOutRes);
+	virtual bool load(const char *name, MovieTextObject *text[]);
 };
+#endif
 
+MoviePlayer *makeMoviePlayer(Sword2Engine *vm, const char *name);
+
 } // End of namespace Sword2
 
 #endif

Modified: scummvm/trunk/engines/sword2/function.cpp
===================================================================
--- scummvm/trunk/engines/sword2/function.cpp	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/engines/sword2/function.cpp	2006-07-08 11:42:07 UTC (rev 23420)
@@ -2131,17 +2131,13 @@
 	// pause sfx during sequence
 	_vm->_sound->pauseFx();
 
-	MoviePlayer player(_vm);
- 	uint32 rv;
+	MoviePlayer *player = makeMoviePlayer(_vm, filename);
 
-	if (_sequenceTextLines && !readVar(DEMO))
-		rv = player.play(filename, sequenceSpeechArray, _smackerLeadIn, _smackerLeadOut);
-	else
-		rv = player.play(filename, NULL, _smackerLeadIn, _smackerLeadOut);
+	if (player->load(filename, (_sequenceTextLines && !readVar(DEMO)) ? sequenceSpeechArray : NULL)) {
+		player->play(_smackerLeadIn, _smackerLeadOut);
+	}
 
-	// check the error return-value
-	if (rv)
-		debug(5, "MoviePlayer.play(\"%s\") returned 0x%.8x", filename, rv);
+	delete player;
 
 	// unpause sound fx again, in case we're staying in same location
 	_vm->_sound->unpauseFx();

Modified: scummvm/trunk/engines/sword2/render.cpp
===================================================================
--- scummvm/trunk/engines/sword2/render.cpp	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/engines/sword2/render.cpp	2006-07-08 11:42:07 UTC (rev 23420)
@@ -29,10 +29,6 @@
 #include "sword2/defs.h"
 #include "sword2/screen.h"
 
-#ifdef BACKEND_8BIT
-#include "sword2/animation.h"
-#endif
-
 namespace Sword2 {
 
 #define MILLISECSPERCYCLE  83
@@ -555,31 +551,4 @@
 	_layer = 0;
 }
 
-#ifdef BACKEND_8BIT
-void Screen::plotYUV(byte *lut, int width, int height, byte *const *dat) {
-	byte *buf = _buffer + ((480 - height) / 2) * RENDERWIDE + (640 - width) / 2;
-
-	int x, y;
-
-	int ypos = 0;
-	int cpos = 0;
-	int linepos = 0;
-
-	for (y = 0; y < height; y += 2) {
-		for (x = 0; x < width; x += 2) {
-			int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH + 1)) + ((dat[1][cpos] + ROUNDADD) >> SHIFT)) * (BITDEPTH + 1);
-			cpos++;
-
-			buf[linepos               ] = lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
-			buf[RENDERWIDE + linepos++] = lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
-			buf[linepos               ] = lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];
-			buf[RENDERWIDE + linepos++] = lut[i + ((dat[0][width + ypos++] + ROUNDADD) >> SHIFT)];
-		}
-		linepos += (2 * RENDERWIDE - width);
-		ypos += width;
-	}
-}
-#endif
-
-
 } // End of namespace Sword2

Modified: scummvm/trunk/engines/sword2/screen.h
===================================================================
--- scummvm/trunk/engines/sword2/screen.h	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/engines/sword2/screen.h	2006-07-08 11:42:07 UTC (rev 23420)
@@ -428,10 +428,6 @@
 	void plotPoint(int x, int y, uint8 colour);
 	void drawLine(int x0, int y0, int x1, int y1, uint8 colour);
 
-#ifdef BACKEND_8BIT
-	void plotYUV(byte *lut, int width, int height, byte *const *dat);
-#endif
-
 	void rollCredits();
 	void splashScreen();
 };

Modified: scummvm/trunk/graphics/animation.h
===================================================================
--- scummvm/trunk/graphics/animation.h	2006-07-08 10:28:35 UTC (rev 23419)
+++ scummvm/trunk/graphics/animation.h	2006-07-08 11:42:07 UTC (rev 23420)
@@ -141,6 +141,9 @@
 	void buildLookup();
 #endif
 
+	int getFrameWidth() { return _frameWidth; }
+	int getFrameHeight() { return _frameHeight; }
+
 protected:
 	bool checkPaletteSwitch();
 	virtual void drawYUV(int width, int height, byte *const *dat) = 0;


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