[Scummvm-cvs-logs] SF.net SVN: scummvm: [25428] scummvm/trunk/engines/sword2

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Thu Feb 8 22:55:37 CET 2007


Revision: 25428
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25428&view=rev
Author:   eriktorbjorn
Date:     2007-02-08 13:55:37 -0800 (Thu, 08 Feb 2007)

Log Message:
-----------
Instead of pre-rendering all subtitles and pre-loading all sounds for a movie
cutscene, render the text and play the speech when needed. It probably won't
play as nicely from CD now, but using less memory seems more important to me.

Modified Paths:
--------------
    scummvm/trunk/engines/sword2/animation.cpp
    scummvm/trunk/engines/sword2/animation.h
    scummvm/trunk/engines/sword2/anims.cpp
    scummvm/trunk/engines/sword2/function.cpp
    scummvm/trunk/engines/sword2/logic.h
    scummvm/trunk/engines/sword2/music.cpp
    scummvm/trunk/engines/sword2/sound.h

Modified: scummvm/trunk/engines/sword2/animation.cpp
===================================================================
--- scummvm/trunk/engines/sword2/animation.cpp	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/animation.cpp	2007-02-08 21:55:37 UTC (rev 25428)
@@ -30,6 +30,7 @@
 #include "sword2/sword2.h"
 #include "sword2/defs.h"
 #include "sword2/header.h"
+#include "sword2/logic.h"
 #include "sword2/maketext.h"
 #include "sword2/mouse.h"
 #include "sword2/resman.h"
@@ -65,11 +66,11 @@
 	{ "enddemo",  110, false }
 };
 
-MoviePlayer::MoviePlayer(Sword2Engine *vm) {
+MoviePlayer::MoviePlayer(Sword2Engine *vm, const char *name) {
 	_vm = vm;
+	_name = strdup(name);
 	_mixer = _vm->_mixer;
 	_system = _vm->_system;
-	_name = NULL;
 	_textSurface = NULL;
 	_bgSoundStream = NULL;
 	_ticks = 0;
@@ -86,7 +87,6 @@
 	_seamless = false;
 	_framesSkipped = 0;
 	_forceFrame = false;
-	_textList = NULL;
 	_currentText = 0;
 }
 
@@ -202,84 +202,121 @@
 	_system->copyRectToScreen(_frameBuffer + _frameY * screenWidth + _frameX, screenWidth, _frameX, _frameY, _frameWidth, _frameHeight);
 }
 
-void MoviePlayer::openTextObject(MovieTextObject *t) {
-	if (t->textSprite) {
-		_vm->_screen->createSurface(t->textSprite, &_textSurface);
+void MoviePlayer::openTextObject(SequenceTextInfo *t) {
+	// Pull out the text line to get the official text number (for WAV id)
+
+	uint32 res = t->textNumber / SIZE;
+	uint32 localText = t->textNumber & 0xffff;
+
+	// Open text resource and get the line
+
+	byte *text = _vm->fetchTextLine(_vm->_resman->openResource(res), localText);
+
+	_textObject.speechId = READ_LE_UINT16(text);
+
+	// Is it speech or subtitles, or both?
+
+	// If we want subtitles, or there was no sound
+
+	if (_vm->getSubtitles() || !_textObject.speechId) {
+		_textObject.textMem = _vm->_fontRenderer->makeTextSprite(text + 2, 600, 255, _vm->_speechFontId, 1);
 	}
+
+	_vm->_resman->closeResource(res);
+
+	if (_textObject.textMem) {
+		FrameHeader frame;
+
+		frame.read(_textObject.textMem);
+
+		_textObject.textSprite.x = 320 - frame.width / 2;
+		_textObject.textSprite.y = 440 - frame.height;
+		_textObject.textSprite.w = frame.width;
+		_textObject.textSprite.h = frame.height;
+		_textObject.textSprite.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION;
+		_textObject.textSprite.data = _textObject.textMem + FrameHeader::size();
+		_vm->_screen->createSurface(&_textObject.textSprite, &_textSurface);
+	}
 }
 
-void MoviePlayer::closeTextObject(MovieTextObject *t) {
+void MoviePlayer::closeTextObject() {
+	free(_textObject.textMem);
+	_textObject.textMem = NULL;
+
+	_textObject.speechId = 0;
+
 	if (_textSurface) {
 		_vm->_screen->deleteSurface(_textSurface);
 		_textSurface = NULL;
 	}
 }
 
-void MoviePlayer::calcTextPosition(MovieTextObject *t, int &xPos, int &yPos) {
-	xPos = 320 - t->textSprite->w / 2;
-	yPos = 420 - t->textSprite->h;
+void MoviePlayer::calcTextPosition(int &xPos, int &yPos) {
+	xPos = 320 - _textObject.textSprite.w / 2;
+	yPos = 420 - _textObject.textSprite.h;
 }
 
-void MoviePlayer::drawTextObject(MovieTextObject *t) {
-	if (t->textSprite && _textSurface) {
+void MoviePlayer::drawTextObject() {
+	if (_textObject.textMem && _textSurface) {
 		int screenWidth = _vm->_screen->getScreenWide();
-		byte *src = t->textSprite->data;
+		byte *src = _textObject.textSprite.data;
+		uint16 width = _textObject.textSprite.w;
+		uint16 height = _textObject.textSprite.h;
 		int xPos, yPos;
 
-		calcTextPosition(t, xPos, yPos);
+		calcTextPosition(xPos, yPos);
 
 		byte *dst = _frameBuffer + yPos * screenWidth + xPos;
 
-		for (int y = 0; y < t->textSprite->h; y++) {
-			for (int x = 0; x < t->textSprite->w; x++) {
+		for (int y = 0; y < height; y++) {
+			for (int x = 0; x < width; x++) {
 				if (src[x] == 1)
 					dst[x] = _black;
 				else if (src[x] == 255)
 					dst[x] = _white;
 			}
-			src += t->textSprite->w;
+			src += width;
 			dst += screenWidth;
 		}
 
-		if (yPos + t->textSprite->h > _frameY + _frameHeight || t->textSprite->w > _frameWidth) {
-			_system->copyRectToScreen(_frameBuffer + yPos * screenWidth + xPos, screenWidth, xPos, yPos, t->textSprite->w, t->textSprite->h);
+		if (yPos + height > _frameY + _frameHeight || width > _frameWidth) {
+			_system->copyRectToScreen(_frameBuffer + yPos * screenWidth + xPos, screenWidth, xPos, yPos, width, height);
 		}
 	}
 }
 
-void MoviePlayer::undrawTextObject(MovieTextObject *t) {
-	if (t->textSprite) {
+void MoviePlayer::undrawTextObject() {
+	if (_textObject.textMem) {
 		int xPos, yPos;
 
-		calcTextPosition(t, xPos, yPos);
+		calcTextPosition(xPos, yPos);
+		uint16 width = _textObject.textSprite.w;
+		uint16 height = _textObject.textSprite.h;
 
 		// We only need to undraw the text if it's outside the frame.
 		// Otherwise the next frame will cover the old text anyway.
 
-		if (yPos + t->textSprite->h > _frameY + _frameHeight || t->textSprite->w > _frameWidth) {
+		if (yPos + height > _frameY + _frameHeight || width > _frameWidth) {
 			int screenWidth = _vm->_screen->getScreenWide();
 			byte *dst = _frameBuffer + yPos * screenWidth + xPos;
 
-			for (int y = 0; y < t->textSprite->h; y++) {
-				memset(dst, 0, t->textSprite->w);
+			for (int y = 0; y < height; y++) {
+				memset(dst, 0, width);
 				dst += screenWidth;
 			}
 
-			_system->copyRectToScreen(_frameBuffer + yPos * screenWidth + xPos, screenWidth, xPos, yPos, t->textSprite->w, t->textSprite->h);
+			_system->copyRectToScreen(_frameBuffer + yPos * screenWidth + xPos, screenWidth, xPos, yPos, width, height);
 		}
 	}
 }
 
-bool MoviePlayer::load(const char *name, MovieTextObject *text[]) {
+bool MoviePlayer::load() {
 	_bgSoundStream = NULL;
-	_textList = text;
 	_currentText = 0;
 	_currentFrame = 0;
 
-	_name = strdup(name);
-
 	for (int i = 0; i < ARRAYSIZE(_movies); i++) {
-		if (scumm_stricmp(name, _movies[i].name) == 0) {
+		if (scumm_stricmp(_name, _movies[i].name) == 0) {
 			_seamless = _movies[i].seamless;
 			_numFrames = _movies[i].frames;
 			if (_numFrames > 60)
@@ -304,26 +341,24 @@
 	return false;
 }
 
-void MoviePlayer::play(int32 leadIn, int32 leadOut) {
+void MoviePlayer::play(SequenceTextInfo *textList, uint32 numLines, int32 leadIn, int32 leadOut) {
 	bool terminate = false;
 	bool textVisible = false;
 	bool startNextText = false;
-	uint32 flags = Audio::Mixer::FLAG_16BITS;
 
 	// This happens if the user quits during the "eye" cutscene.
 	if (_vm->_quit)
 		return;
 
+	_numSpeechLines = numLines;
+	_firstSpeechFrame = (numLines > 0) ? textList[0].startFrame : 0;
+
 	if (leadIn) {
 		_vm->_sound->playMovieSound(leadIn, kLeadInSound);
 	}
 
 	savePalette();
 
-#ifndef SCUMM_BIG_ENDIAN
-	flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
-#endif
-
 	_framesSkipped = 0;
 	_ticks = _system->getMillis();
 	_bgSoundStream = Audio::AudioStream::openStreamFile(_name);
@@ -338,32 +373,32 @@
 		// 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 (_currentText < numLines) {
+			SequenceTextInfo *t = &textList[_currentText];
 
 			if (_currentFrame == t->startFrame) {
 				openTextObject(t);
 				textVisible = true;
 
-				if (t->speech) {
+				if (_textObject.speechId) {
 					startNextText = true;
 				}
 			}
 
-			if (startNextText && !_mixer->isSoundHandleActive(_speechHandle)) {
-				_mixer->playRaw(Audio::Mixer::kSpeechSoundType, &_speechHandle, t->speech, t->speechBufferSize, 22050, flags);
+			if (startNextText && _vm->_sound->amISpeaking() == RDSE_QUIET) {
+				_vm->_sound->playCompSpeech(_textObject.speechId, 16, 0);
 				startNextText = false;
 			}
 
 			if (_currentFrame == t->endFrame) {
-				undrawTextObject(t);
-				closeTextObject(t);
+				undrawTextObject();
+				closeTextObject();
 				_currentText++;
 				textVisible = false;
 			}
 
 			if (textVisible)
-				drawTextObject(t);
+				drawTextObject();
 		}
 
 		if (leadOut && _currentFrame == _leadOutFrame) {
@@ -404,8 +439,8 @@
 		// If the sound is still playing, draw the subtitles one final
 		// time. This happens in the "carib" cutscene.
 
-		if (textVisible && _mixer->isSoundHandleActive(_speechHandle)) {
-			drawTextObject(_textList[_currentText]);
+		if (textVisible && _vm->_sound->amISpeaking() == RDSE_SPEAKING) {
+			drawTextObject();
 		}
 
 		drawFrame();
@@ -418,19 +453,17 @@
 		// mid-sentence, and - even more importantly - that we don't
 		// free the sound buffer while it's still in use.
 
-		while (_mixer->isSoundHandleActive(_speechHandle) || _mixer->isSoundHandleActive(_bgSoundHandle)) {
+		while (_vm->_sound->amISpeaking() == RDSE_SPEAKING || _mixer->isSoundHandleActive(_bgSoundHandle)) {
 			_system->delayMillis(100);
 		}
 	} else {
-		_mixer->stopHandle(_speechHandle);
+		_vm->_sound->stopSpeech();
 		_mixer->stopHandle(_bgSoundHandle);
 	}
 
 	// The current text object may still be open
-	if (_textList && _textList[_currentText]) {
-		undrawTextObject(_textList[_currentText]);
-		closeTextObject(_textList[_currentText]);
-	}
+	undrawTextObject();
+	closeTextObject();
 
 	if (!_seamless) {
 		clearFrame();
@@ -448,7 +481,8 @@
 // Movie player for the new DXA movies
 ///////////////////////////////////////////////////////////////////////////////
 
-MoviePlayerDXA::MoviePlayerDXA(Sword2Engine *vm) : MoviePlayer(vm) {
+MoviePlayerDXA::MoviePlayerDXA(Sword2Engine *vm, const char *name)
+	: MoviePlayer(vm, name) {
 	debug(0, "Creating DXA cutscene player");
 }
 
@@ -466,13 +500,13 @@
 	return true;
 }
 
-bool MoviePlayerDXA::load(const char *name, MovieTextObject *text[]) {
-	if (!MoviePlayer::load(name, text))
+bool MoviePlayerDXA::load() {
+	if (!MoviePlayer::load())
 		return false;
 
 	char filename[20];
 
-	snprintf(filename, sizeof(filename), "%s.dxa", name);
+	snprintf(filename, sizeof(filename), "%s.dxa", _name);
 
 	if (loadFile(filename)) {
 		// The Broken Sword games always use external audio tracks.
@@ -501,7 +535,8 @@
 // Movie player for the old MPEG movies
 ///////////////////////////////////////////////////////////////////////////////
 
-MoviePlayerMPEG::MoviePlayerMPEG(Sword2Engine *vm) : MoviePlayer(vm) {
+MoviePlayerMPEG::MoviePlayerMPEG(Sword2Engine *vm, const char *name)
+	: MoviePlayer(vm, name) {
 #ifdef BACKEND_8BIT
 	debug(0, "Creating MPEG cutscene player (8-bit)");
 #else
@@ -514,13 +549,13 @@
 	_anim = NULL;
 }
 
-bool MoviePlayerMPEG::load(const char *name, MovieTextObject *text[]) {
-	if (!MoviePlayer::load(name, text))
+bool MoviePlayerMPEG::load() {
+	if (!MoviePlayer::load())
 		return false;
 
 	_anim = new AnimationState(_vm, this);
 
-	if (!_anim->init(name)) {
+	if (!_anim->init(_name)) {
 		delete _anim;
 		_anim = NULL;
 		return false;
@@ -579,13 +614,13 @@
 	_anim->updateScreen();
 }
 
-void MoviePlayerMPEG::drawTextObject(MovieTextObject *t) {
-	if (t->textSprite && _textSurface) {
-		_anim->drawTextObject(t->textSprite, _textSurface);
+void MoviePlayerMPEG::drawTextObject() {
+	if (_textObject.textMem && _textSurface) {
+		_anim->drawTextObject(&_textObject.textSprite, _textSurface);
 	}
 }
 
-void MoviePlayerMPEG::undrawTextObject(MovieTextObject *t) {
+void MoviePlayerMPEG::undrawTextObject() {
 	// As long as we only have subtitles for full-sized cutscenes, we don't
 	// really need to implement this function.
 }
@@ -689,15 +724,16 @@
 // Dummy player for subtitled speech only
 ///////////////////////////////////////////////////////////////////////////////
 
-MoviePlayerDummy::MoviePlayerDummy(Sword2Engine *vm) : MoviePlayer(vm) {
+MoviePlayerDummy::MoviePlayerDummy(Sword2Engine *vm, const char *name)
+	: MoviePlayer(vm, name) {
 	debug(0, "Creating Dummy cutscene player");
 }
 
 MoviePlayerDummy::~MoviePlayerDummy() {
 }
 
-bool MoviePlayerDummy::load(const char *name, MovieTextObject *text[]) {
-	if (!MoviePlayer::load(name, text))
+bool MoviePlayerDummy::load() {
+	if (!MoviePlayer::load())
 		return false;
 
 	_frameBuffer = _vm->_screen->getScreen();
@@ -711,7 +747,7 @@
 }
 
 bool MoviePlayerDummy::decodeFrame() {
-	if (_currentFrame == 0 && _textList) {
+	if (_currentFrame == 0 && _numSpeechLines > 0) {
 		byte dummyPalette[] = {
 			  0,   0,   0, 0,
 			255, 255, 255, 0,
@@ -767,7 +803,7 @@
 
 	// If we have played the final voice-over, skip ahead to the lead out
 
-	if (_textList && !_textList[_currentText] && !_mixer->isSoundHandleActive(_speechHandle) && _leadOutFrame != (uint)-1 && _currentFrame < _leadOutFrame) {
+	if (_currentText >= _numSpeechLines && _vm->_sound->amISpeaking() == RDSE_QUIET && _leadOutFrame != (uint)-1 && _currentFrame < _leadOutFrame) {
 		_currentFrame = _leadOutFrame - 1;
 	}
 
@@ -775,7 +811,7 @@
 }
 
 void MoviePlayerDummy::syncFrame() {
-	if (!_textList || _currentFrame < _textList[0]->startFrame) {
+	if (_numSpeechLines == 0 || _currentFrame < _firstSpeechFrame) {
 		_ticks = _system->getMillis();
 		return;
 	}
@@ -786,16 +822,16 @@
 void MoviePlayerDummy::drawFrame() {
 }
 
-void MoviePlayerDummy::drawTextObject(MovieTextObject *t) {
-	if (t->textSprite && _textSurface) {
-		_vm->_screen->drawSurface(t->textSprite, _textSurface);
+void MoviePlayerDummy::drawTextObject() {
+	if (_textObject.textMem && _textSurface) {
+		_vm->_screen->drawSurface(&_textObject.textSprite, _textSurface);
 	}
 }
 
-void MoviePlayerDummy::undrawTextObject(MovieTextObject *t) {
-	if (t->textSprite && _textSurface) {
-		memset(_textSurface, 1, t->textSprite->w * t->textSprite->h);
-		drawTextObject(t);
+void MoviePlayerDummy::undrawTextObject() {
+	if (_textObject.textMem && _textSurface) {
+		memset(_textSurface, 1, _textObject.textSprite.w * _textObject.textSprite.h);
+		drawTextObject();
 	}
 }
 
@@ -804,13 +840,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 MoviePlayer *makeMoviePlayer(Sword2Engine *vm, const char *name) {
-	char filename[20];
+	static char filename[20];
 
 #ifdef USE_ZLIB
 	snprintf(filename, sizeof(filename), "%s.dxa", name);
 
 	if (Common::File::exists(filename)) {
-		return new MoviePlayerDXA(vm);
+		return new MoviePlayerDXA(vm, name);
 	}
 #endif
 
@@ -818,11 +854,11 @@
 	snprintf(filename, sizeof(filename), "%s.mp2", name);
 
 	if (Common::File::exists(filename)) {
-		return new MoviePlayerMPEG(vm);
+		return new MoviePlayerMPEG(vm, name);
 	}
 #endif
 
-	return new MoviePlayerDummy(vm);
+	return new MoviePlayerDummy(vm, name);
 }
 
 } // End of namespace Sword2

Modified: scummvm/trunk/engines/sword2/animation.h
===================================================================
--- scummvm/trunk/engines/sword2/animation.h	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/animation.h	2007-02-08 21:55:37 UTC (rev 25428)
@@ -26,22 +26,27 @@
 #include "graphics/mpeg_player.h"
 #include "sound/mixer.h"
 
+#include "sword2/screen.h"
+
 namespace Sword2 {
 
-struct SpriteInfo;
-
-// This is the structure which is passed to the sequence player. It includes
-// the smack to play, and any text lines which are to be displayed over the top
-// of the sequence.
-
-struct MovieTextObject {
+struct SequenceTextInfo {
+	uint32 textNumber;
 	uint16 startFrame;
 	uint16 endFrame;
-	SpriteInfo *textSprite;
-	uint32 speechBufferSize;
-	uint16 *speech;
 };
 
+struct MovieTextObject {
+	byte *textMem;
+	SpriteInfo textSprite;
+	uint16 speechId;
+
+	MovieTextObject() {
+		textMem = NULL;
+		speechId = 0;
+	}
+};
+
 struct MovieInfo {
 	const char *name;
 	uint frames;
@@ -61,9 +66,11 @@
 
 	byte _originalPalette[4 * 256];
 
+	uint32 _numSpeechLines;
+	uint32 _firstSpeechFrame;
+	MovieTextObject _textObject;
 	byte *_textSurface;
 
-	Audio::SoundHandle _speechHandle;
 	Audio::SoundHandle _bgSoundHandle;
 	Audio::AudioStream *_bgSoundStream;
 
@@ -85,15 +92,14 @@
 
 	static const MovieInfo _movies[];
 
-	MovieTextObject **_textList;
-	int _currentText;
+	uint32 _currentText;
 
 	void savePalette();
 	void restorePalette();
 
-	void openTextObject(MovieTextObject *t);
-	void closeTextObject(MovieTextObject *t);
-	void calcTextPosition(MovieTextObject *t, int &xPos, int &yPos);
+	void openTextObject(SequenceTextInfo *t);
+	void closeTextObject();
+	void calcTextPosition(int &xPos, int &yPos);
 
 	virtual void handleScreenChanged() {}
 
@@ -102,16 +108,16 @@
 	virtual bool decodeFrame() = 0;
 	virtual void syncFrame();
 	virtual void drawFrame();
-	virtual void drawTextObject(MovieTextObject *t);
-	virtual void undrawTextObject(MovieTextObject *t);
+	virtual void drawTextObject();
+	virtual void undrawTextObject();
 
 public:
-	MoviePlayer(Sword2Engine *vm);
+	MoviePlayer(Sword2Engine *vm, const char *name);
 	virtual ~MoviePlayer();
 
 	void updatePalette(byte *pal, bool packed = true);
-	virtual bool load(const char *name, MovieTextObject *text[]);
-	void play(int32 leadIn, int32 leadOut);
+	virtual bool load();
+	void play(SequenceTextInfo *textList, uint32 numLines, int32 leadIn, int32 leadOut);
 };
 
 class MoviePlayerDummy : public MoviePlayer {
@@ -119,14 +125,14 @@
 	bool decodeFrame();
 	void syncFrame();
 	void drawFrame();
-	void drawTextObject(MovieTextObject *t);
-	void undrawTextObject(MovieTextObject *t);
+	void drawTextObject();
+	void undrawTextObject();
 
 public:
-	MoviePlayerDummy(Sword2Engine *vm);
+	MoviePlayerDummy(Sword2Engine *vm, const char *name);
 	virtual ~MoviePlayerDummy();
 
-	bool load(const char *name, MovieTextObject *text[]);
+	bool load();
 };
 
 #ifdef USE_MPEG2
@@ -164,15 +170,15 @@
 	void clearFrame();
 	void drawFrame();
 	void updateScreen();
-	void drawTextObject(MovieTextObject *t);
-	void undrawTextObject(MovieTextObject *t);
+	void drawTextObject();
+	void undrawTextObject();
 #endif
 
 public:
-	MoviePlayerMPEG(Sword2Engine *vm);
+	MoviePlayerMPEG(Sword2Engine *vm, const char *name);
 	~MoviePlayerMPEG();
 
-	bool load(const char *name, MovieTextObject *text[]);
+	bool load();
 };
 #endif
 
@@ -183,10 +189,10 @@
 	bool decodeFrame();
 
 public:
-	MoviePlayerDXA(Sword2Engine *vm);
+	MoviePlayerDXA(Sword2Engine *vm, const char *name);
 	~MoviePlayerDXA();
 
-	bool load(const char *name, MovieTextObject *text[]);
+	bool load();
 };
 #endif
 

Modified: scummvm/trunk/engines/sword2/anims.cpp
===================================================================
--- scummvm/trunk/engines/sword2/anims.cpp	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/anims.cpp	2007-02-08 21:55:37 UTC (rev 25428)
@@ -179,131 +179,4 @@
 	obGraph.setType((obGraph.getType() & 0x0000ffff) | type);
 }
 
-void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) {
-	uint32 line;
- 	uint32 local_text;
-	uint32 text_res;
-	byte *text;
-	uint32 wavId;	// ie. offical text number (actor text number)
-	bool speechRunning;
-
-	// for each sequence text line that's been logged
-	for (line = 0; line < _sequenceTextLines; line++) {
-		// allocate this structure
-		sequenceText[line] = new MovieTextObject;
-
-		sequenceText[line]->startFrame = _sequenceTextList[line].startFrame;
-		sequenceText[line]->endFrame = _sequenceTextList[line].endFrame;
-
-		// pull out the text line to get the official text number
-		// (for wav id)
-
-  		text_res = _sequenceTextList[line].textNumber / SIZE;
-		local_text = _sequenceTextList[line].textNumber & 0xffff;
-
-		// open text resource & get the line
-		text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
-		wavId = (int32)READ_LE_UINT16(text);
-
-		// now ok to close the text file
-		_vm->_resman->closeResource(text_res);
-
-		// 1st word of text line is the official line number
-		debug(5,"(%d) SEQUENCE TEXT: %s", READ_LE_UINT16(text), text + 2);
-
-		// is it to be speech or subtitles or both?
-		// assume speech is not running until know otherwise
-
-		speechRunning = false;
-		_sequenceTextList[line].speech_mem = NULL;
-		sequenceText[line]->speech = NULL;
-
-		if (!_vm->_sound->isSpeechMute()) {
-			_sequenceTextList[line].speechBufferSize = _vm->_sound->preFetchCompSpeech(wavId, &_sequenceTextList[line].speech_mem);
-			if (_sequenceTextList[line].speechBufferSize) {
-				// ok, we've got speech!
-				speechRunning = true;
-			}
-		}
-
-		// if we want subtitles, or speech failed to load
-
-		if (_vm->getSubtitles() || !speechRunning) {
-			// open text resource & get the line
-			text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
-			// make the sprite
-			// 'text+2' to skip the first 2 bytes which form the
-			// line reference number
-
-			// NB. The mem block containing the text sprite is
-			// currently FLOATING!
-
-			// When rendering text over a sequence we need a
-			// different colour for the border.
-
-			_sequenceTextList[line].text_mem = _vm->_fontRenderer->makeTextSprite(text + 2, 600, 255, _vm->_speechFontId, 1);
-
-			// ok to close the text resource now
-			_vm->_resman->closeResource(text_res);
-		} else {
-			_sequenceTextList[line].text_mem = NULL;
-			sequenceText[line]->textSprite = NULL;
-		}
-	}
-
-	// for drivers: NULL-terminate the array of pointers to
-	// MovieTextObject's
-	sequenceText[_sequenceTextLines] = NULL;
-
-	for (line = 0; line < _sequenceTextLines; line++) {
-		// if we've made a text sprite for this line...
-
-		if (_sequenceTextList[line].text_mem) {
-			// now fill out the SpriteInfo structure in the
-			// MovieTextObjectStructure
-			FrameHeader frame;
-
-			frame.read(_sequenceTextList[line].text_mem);
-
-			sequenceText[line]->textSprite = new SpriteInfo;
-
-			// center text at bottom of screen
-			sequenceText[line]->textSprite->x = 320 - frame.width / 2;
-			sequenceText[line]->textSprite->y = 440 - frame.height;
-			sequenceText[line]->textSprite->w = frame.width;
-			sequenceText[line]->textSprite->h = frame.height;
-			sequenceText[line]->textSprite->type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION;
-			sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem + FrameHeader::size();
-		}
-
-		// if we've loaded a speech sample for this line...
-
- 		if (_sequenceTextList[line].speech_mem) {
-			// for drivers: set up pointer to decompressed wav in
-			// memory
-
-			sequenceText[line]->speechBufferSize = _sequenceTextList[line].speechBufferSize;
-			sequenceText[line]->speech = _sequenceTextList[line].speech_mem;
-		}
-	}
-}
-
-void Logic::clearSequenceSpeech(MovieTextObject *sequenceText[]) {
-	for (uint i = 0; i < _sequenceTextLines; i++) {
-		// free up the memory used by this MovieTextObject
-		delete sequenceText[i];
-
-		// free up the mem block containing this text sprite
-		if (_sequenceTextList[i].text_mem)
-			free(_sequenceTextList[i].text_mem);
-
-		// free up the mem block containing this speech sample
-		if (_sequenceTextList[i].speech_mem)
-			free(_sequenceTextList[i].speech_mem);
-	}
-
-	// IMPORTANT! Reset the line count ready for the next sequence!
-	_sequenceTextLines = 0;
-}
-
 } // End of namespace Sword2

Modified: scummvm/trunk/engines/sword2/function.cpp
===================================================================
--- scummvm/trunk/engines/sword2/function.cpp	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/function.cpp	2007-02-08 21:55:37 UTC (rev 25428)
@@ -2102,7 +2102,6 @@
 	// 		1 number of frames in the sequence, used for PSX.
 
 	char filename[30];
-	MovieTextObject *sequenceSpeechArray[MAX_SEQUENCE_TEXT_LINES + 1];
 
 	// The original code had some #ifdef blocks for skipping or muting the
 	// cutscenes - fondly described as "the biggest fudge in the history
@@ -2118,12 +2117,7 @@
 	// Write to walkthrough file (zebug0.txt)
  	debug(5, "PLAYING SEQUENCE \"%s\"", filename);
 
-	// now create the text sprites, if any
-
-	if (_sequenceTextLines)
-		createSequenceSpeech(sequenceSpeechArray);
-
-	// don't want to carry on streaming game music when smacker starts!
+	// don't want to carry on streaming game music when cutscene starts!
 	fnStopMusic(NULL);
 
 	// pause sfx during sequence
@@ -2131,10 +2125,12 @@
 
 	MoviePlayer *player = makeMoviePlayer(_vm, filename);
 
-	if (player->load(filename, (_sequenceTextLines && !readVar(DEMO)) ? sequenceSpeechArray : NULL)) {
-		player->play(_smackerLeadIn, _smackerLeadOut);
+	if (player->load()) {
+		player->play(_sequenceTextList, _sequenceTextLines, _smackerLeadIn, _smackerLeadOut);
 	}
 
+	_sequenceTextLines = 0;
+
 	delete player;
 
 	// unpause sound fx again, in case we're staying in same location
@@ -2143,11 +2139,6 @@
 	_smackerLeadIn = 0;
 	_smackerLeadOut = 0;
 
-	// now clear the text sprites, if any
-
-	if (_sequenceTextLines)
-		clearSequenceSpeech(sequenceSpeechArray);
-
 	// now clear the screen in case the Sequence was quitted (using ESC)
 	// rather than fading down to black
 
@@ -2219,12 +2210,15 @@
 	//		1 frame number to start the text displaying
 	//		2 frame number to stop the text dispalying
 
-	assert(_sequenceTextLines < MAX_SEQUENCE_TEXT_LINES);
+	if (!readVar(DEMO)) {
+		assert(_sequenceTextLines < MAX_SEQUENCE_TEXT_LINES);
 
-	_sequenceTextList[_sequenceTextLines].textNumber = params[0];
-	_sequenceTextList[_sequenceTextLines].startFrame = params[1];
-	_sequenceTextList[_sequenceTextLines].endFrame = params[2];
-	_sequenceTextLines++;
+		_sequenceTextList[_sequenceTextLines].textNumber = params[0];
+		_sequenceTextList[_sequenceTextLines].startFrame = params[1];
+		_sequenceTextList[_sequenceTextLines].endFrame = params[2];
+		_sequenceTextLines++;
+	}
+
 	return IR_CONT;
 }
 

Modified: scummvm/trunk/engines/sword2/logic.h
===================================================================
--- scummvm/trunk/engines/sword2/logic.h	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/logic.h	2007-02-08 21:55:37 UTC (rev 25428)
@@ -24,13 +24,12 @@
 #ifndef SWORD2_LOGIC_H
 #define SWORD2_LOGIC_H
 
-#include "sword2/memory.h"
 #include "common/endian.h"
+#include "sword2/animation.h"
+#include "sword2/memory.h"
 
 namespace Sword2 {
 
-struct MovieTextObject;
-
 #define MAX_events 10
 
 #define TREE_SIZE 3
@@ -79,22 +78,8 @@
 	// keeps count of number of text lines to disaply during the sequence
 	uint32 _sequenceTextLines;
 
-	// FOR TEXT LINES IN SEQUENCE PLAYER
-
-	struct SequenceTextInfo {
-		uint32 textNumber;
-		uint16 startFrame;
-		uint16 endFrame;
-		byte *text_mem;
-		uint32 speechBufferSize;
-		uint16 *speech_mem;
-	};
-
 	SequenceTextInfo _sequenceTextList[MAX_SEQUENCE_TEXT_LINES];
 
-	void createSequenceSpeech(MovieTextObject *sequenceText[]);
-	void clearSequenceSpeech(MovieTextObject *sequenceText[]);
-
 	// when not playing a wav we calculate the speech time based upon
 	// length of ascii
 

Modified: scummvm/trunk/engines/sword2/music.cpp
===================================================================
--- scummvm/trunk/engines/sword2/music.cpp	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/music.cpp	2007-02-08 21:55:37 UTC (rev 25428)
@@ -705,46 +705,6 @@
 }
 
 /**
- * This function loads and decompresses a list of speech from a cluster, but
- * does not play it. This is used for cutscene voice-overs, presumably to
- * avoid having to read from more than one file on the CD during playback.
- * @param speechId the text line id used to reference the speech
- * @param buf a pointer to the buffer that will be allocated for the sound
- */
-
-uint32 Sound::preFetchCompSpeech(uint32 speechId, uint16 **buf) {
-	int cd = _vm->_resman->getCD();
-	uint32 numSamples;
-
-	SoundFileHandle *fh = (cd == 1) ? &_speechFile[0] : &_speechFile[1];
-
-	Audio::AudioStream *input = getAudioStream(fh, "speech", cd, speechId, &numSamples);
-
-	if (!input)
-		return 0;
-
-	*buf = NULL;
-
-	// Decompress data into speech buffer.
-
-	uint32 bufferSize = 2 * numSamples;
-
-	*buf = (uint16 *)malloc(bufferSize);
-	if (!*buf) {
-		delete input;
-		fh->file.close();
-		return 0;
-	}
-
-	uint32 readSamples = input->readBuffer((int16 *)*buf, numSamples);
-
-	fh->file.close();
-	delete input;
-
-	return 2 * readSamples;
-}
-
-/**
  * This function loads, decompresses and plays a line of speech. An error
  * occurs if speech is already playing.
  * @param speechId the text line id used to reference the speech

Modified: scummvm/trunk/engines/sword2/sound.h
===================================================================
--- scummvm/trunk/engines/sword2/sound.h	2007-02-08 21:08:54 UTC (rev 25427)
+++ scummvm/trunk/engines/sword2/sound.h	2007-02-08 21:55:37 UTC (rev 25428)
@@ -269,7 +269,6 @@
 	int32 getSpeechStatus();
 	int32 amISpeaking();
 	int32 playCompSpeech(uint32 speechId, uint8 vol, int8 pan);
-	uint32 preFetchCompSpeech(uint32 speechId, uint16 **buf);
 	int32 stopSpeech();
 
 	int32 streamCompMusic(uint32 musicId, bool loop);


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