diff options
| author | Florian Kagerer | 2009-03-08 23:28:19 +0000 | 
|---|---|---|
| committer | Florian Kagerer | 2009-03-08 23:28:19 +0000 | 
| commit | 6cb3f665aff572fdbdb12c940ace9c4bfe912138 (patch) | |
| tree | 67d00c26b63633c7445e6db84cf3a9f7deaed9b1 | |
| parent | 2abfb968a601031e211e01d742f7d78f9b5e8134 (diff) | |
| download | scummvm-rg350-6cb3f665aff572fdbdb12c940ace9c4bfe912138.tar.gz scummvm-rg350-6cb3f665aff572fdbdb12c940ace9c4bfe912138.tar.bz2 scummvm-rg350-6cb3f665aff572fdbdb12c940ace9c4bfe912138.zip  | |
LOL: some more work on the text displayer so that it handles longer texts (needed for some library books)
svn-id: r39249
| -rw-r--r-- | engines/kyra/lol.cpp | 55 | ||||
| -rw-r--r-- | engines/kyra/lol.h | 8 | ||||
| -rw-r--r-- | engines/kyra/screen_lol.cpp | 5 | ||||
| -rw-r--r-- | engines/kyra/screen_lol.h | 1 | ||||
| -rw-r--r-- | engines/kyra/script_lol.cpp | 16 | ||||
| -rw-r--r-- | engines/kyra/sound.cpp | 10 | ||||
| -rw-r--r-- | engines/kyra/sound.h | 2 | ||||
| -rw-r--r-- | engines/kyra/text_lol.cpp | 143 | ||||
| -rw-r--r-- | engines/kyra/text_lol.h | 10 | 
9 files changed, 197 insertions, 53 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index f2ec3950fa..b6b655bd9c 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -190,7 +190,8 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy  	memset(_activeTim, 0, sizeof(_activeTim));  	memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile));  	memset(_openDoorState, 0, sizeof(_openDoorState)); - +	 +	_activeVoiceFileTotalTime = 0;  	_pageBuffer1 = _pageBuffer2 = 0;  	memset(_charStatsTemp, 0, sizeof(_charStatsTemp)); @@ -359,8 +360,7 @@ Common::Error LoLEngine::init() {  	_pageBuffer2 = new uint8[0xfa00];  	memset(_pageBuffer2, 0, 0xfa00); -	// FIXME: Why do we allocate a 401 entry array, if only 400 entries are used? -	_itemsInPlay = new ItemInPlay[401]; +	_itemsInPlay = new ItemInPlay[400];  	memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400);  	_characters = new LoLCharacter[4]; @@ -416,7 +416,7 @@ Common::Error LoLEngine::init() {  	memset(_tmpData136, 0, 136);  	memset(_gameFlags, 0, 16 * sizeof(uint16)); -	memset(_unkEMC46, 0, 16 * sizeof(uint16)); +	memset(_globalScriptVars, 0, 16 * sizeof(uint16));  	_levelFileData = 0;  	_lvlShpFileHandle = 0; @@ -1167,9 +1167,44 @@ void LoLEngine::restoreAfterAnimatedDialogue(int redraw) {  }  void LoLEngine::initNonAnimatedDialogue(int controlMode, int pageNum) { +	if (controlMode) { +		_timer->disable(11); +		_fadeText = false; +		int cp = _screen->setCurPage(pageNum); + +		_screen->fillRect(0, 128, 319, 199, 1); +		gui_drawBox(0, 129, 320, 71, 136, 251, -1); +		gui_drawBox(1, 130, 318, 69, 136, 251, 252); + +		_screen->modifyScreenDim(5, 8, 131, 304, 66); +		_screen->modifyScreenDim(4, 1, 133, 38, 60); +		_screen->clearDim(4); + +		_updateFlags |= 2; +		_hideControls = controlMode; +		calcCharPortraitXpos(); + +		if (!textEnabled() && (!(controlMode & 2))) { +			int nc = countActiveCharacters(); +			for (int i = 0; i < nc; i++) { +				_portraitSpeechAnimMode = 2; +				_updateCharNum = i; +				_screen->drawShape(0, _gameShapes[88], _activeCharsXpos[_updateCharNum] + 8, 142, 0, 0); +				updatePortraits(); +			} +		} + +		_screen->setCurPage(cp); + +	} else { +		_txt->setupField(true); +		_txt->expandField(); +		setupScreenDims(); +		_screen->clearDim(4); +	} -	_dialogueField = true; -	 +	_hideControls = controlMode; +	_dialogueField = true;	  }  void LoLEngine::restoreAfterNonAnimatedDialogue(int controlMode) { @@ -1327,7 +1362,7 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {  	};  	strcpy(_activeVoiceFile, *playList.begin()); -	_sound->voicePlayFromList(playList); +	_activeVoiceFileTotalTime = _sound->voicePlayFromList(playList);  	for (Common::List<const char*>::iterator i = playList.begin(); i != playList.end(); i++)  		delete []*i; @@ -1343,6 +1378,7 @@ int LoLEngine::snd_characterSpeaking() {  		return 2;  	_lastSpeechId = _lastSpeaker = -1; +	_activeVoiceFileTotalTime = 0;  	return 1;  } @@ -1353,11 +1389,16 @@ void LoLEngine::snd_stopSpeech(bool setFlag) {  	//_dlgTimer = 0;  	_sound->voiceStop(_activeVoiceFile); +	_activeVoiceFileTotalTime = 0;  	if (setFlag)  		_tim->_abortFlag = 1;  } +uint32 LoLEngine::snd_getElapsedSpeechTime() { +	return _sound->voicePlayedTime(_activeVoiceFile); +} +  void LoLEngine::snd_playSoundEffect(int track, int volume) {  	debugC(9, kDebugLevelMain | kDebugLevelSound, "LoLEngine::snd_playSoundEffect(%d, %d)", track, volume); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 91883117a1..3e7ab12547 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -327,6 +327,7 @@ private:  	bool snd_playCharacterSpeech(int id, int8 speaker, int);  	int snd_characterSpeaking();  	void snd_stopSpeech(bool setFlag); +	uint32 snd_getElapsedSpeechTime();  	void snd_playSoundEffect(int track, int volume);  	void snd_processEnvironmentalSoundEffect(int soundId, int block);  	void snd_loadSoundFile(int track); @@ -336,6 +337,7 @@ private:  	int _lastSpeechId;  	int _lastSpeaker;  	char _activeVoiceFile[13]; +	uint32 _activeVoiceFileTotalTime;  	int _lastSfxTrack;  	int _lastMusicTrack;  	int _curMusicFileIndex; @@ -494,7 +496,7 @@ private:  	bool _sceneUpdateRequired;  	int16 _currentBlockPropertyIndex[18];  	uint16 _gameFlags[16]; -	uint16 _unkEMC46[16]; +	uint16 _globalScriptVars[16];  	// emc opcode  	int olol_drawScene(EMCState *script); @@ -519,8 +521,8 @@ private:  	int olol_getDirection(EMCState *script);  	int olol_setMusicTrack(EMCState *script);  	int olol_clearDialogueField(EMCState *script); -	int olol_getUnkArrayVal(EMCState *script); -	int olol_setUnkArrayVal(EMCState *script); +	int olol_getGlobalScriptVar(EMCState *script); +	int olol_setGlobalScriptVar(EMCState *script);  	int olol_getGlobalVar(EMCState *script);  	int olol_setGlobalVar(EMCState *script);  	int olol_triggerDoorSwitch(EMCState *script); diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index 615dd0c4b3..884dee4712 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -92,11 +92,6 @@ void Screen_LoL::clearDim(int dim) {  	fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, tmp->unkA);  } -void Screen_LoL::clearCurDim() { -	fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA); -	_dimLineCount = 0; -} -  void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...) {  	debugC(9, kDebugLevelScreen, "Screen_LoL::fprintString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags);  	if (!format) diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index 1b1842bffc..4de43788b1 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -44,7 +44,6 @@ public:  	int curDimIndex() { return _curDimIndex; }  	void modifyScreenDim(int dim, int x, int y, int w, int h);  	void clearDim(int dim); -	void clearCurDim();  	void fprintString(const char *format, int x, int y, uint8 col1, uint8 col2, uint16 flags, ...);  	void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...); diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index b4127a7774..31414f3b50 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -452,12 +452,16 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) {  	return 1;  } -int LoLEngine::olol_getUnkArrayVal(EMCState *script) { -	return _unkEMC46[stackPos(0)]; +int LoLEngine::olol_getGlobalScriptVar(EMCState *script) { +	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getGlobalScriptVar(%p) (%d)", (const void *)script, stackPos(0)); +	assert(stackPos(0) < 16); +	return _globalScriptVars[stackPos(0)];  } -int LoLEngine::olol_setUnkArrayVal(EMCState *script) { -	_unkEMC46[stackPos(0)] = stackPos(1); +int LoLEngine::olol_setGlobalScriptVar(EMCState *script) { +	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGlobalScriptVar(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); +	assert(stackPos(0) < 16); +	_globalScriptVars[stackPos(0)] = stackPos(1);  	return 1;  } @@ -1194,8 +1198,8 @@ void LoLEngine::setupOpcodeTable() {  	// 0x2C  	OpcodeUnImpl(); -	Opcode(olol_getUnkArrayVal); -	Opcode(olol_setUnkArrayVal); +	Opcode(olol_getGlobalScriptVar); +	Opcode(olol_setGlobalScriptVar);  	Opcode(olol_getGlobalVar);  	// 0x30 diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 47045c21cd..4b4439c1e3 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -115,21 +115,22 @@ int32 Sound::voicePlay(const char *file, uint8 volume, bool isSfx) {  	return audioStream->getTotalPlayTime();  } -void Sound::voicePlayFromList(Common::List<const char*> fileList) { +uint32 Sound::voicePlayFromList(Common::List<const char*> fileList) {  	int h = 0;  	while (_mixer->isSoundHandleActive(_soundChannels[h].channelHandle) && h < kNumChannelHandles)  		h++;  	if (h >= kNumChannelHandles) -		return; +		return 0;  	Audio::AppendableAudioStream *out = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED);  	for (Common::List<const char*>::iterator i = fileList.begin(); i != fileList.end(); i++) {  		Common::SeekableReadStream *file = _vm->resource()->createReadStream(*i); -		// TODO: Maybe output an warning like "file not found"? -		if (!file) +		if (!file) { +			warning("Couldn't load voice file: %s", *i);  			continue; +		}  		int size, rate;  		uint8 *data = Audio::loadVOCFromStream(*file, size, rate); @@ -151,6 +152,7 @@ void Sound::voicePlayFromList(Common::List<const char*> fileList) {  	_soundChannels[h].file = *fileList.begin();  	_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_soundChannels[h].channelHandle, out); +	return out->getTotalPlayTime();  }  void Sound::voiceStop(const char *file) { diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index 6f6a088b8b..7b7fba8e3a 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -203,7 +203,7 @@ public:  	 *  	 * @param fileList:	files to be played  	 */ -	virtual void voicePlayFromList(Common::List<const char*> fileList); +	virtual uint32 voicePlayFromList(Common::List<const char*> fileList);  	/**  	 * Checks if a voice is being played. diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index ac7d7c4a6c..5996712bd3 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -31,7 +31,7 @@  namespace Kyra {  TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen), -	_scriptParameter(0), _stringLength(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true), +	_scriptParameter(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true),  	_printFlag(false), _lineWidth(0), _numChars(0), _numCharsPrinted(0), _posX(0), _posY(0), _colour1(0), _colour2(0) {  	memset(_stringParameters, 0, 15 * sizeof(char*)); @@ -184,10 +184,10 @@ void TextDisplayer_LoL::printMessage(uint16 type, char *str, ...) {  	if (_vm->_updateFlags & 2) {  		_screen->setScreenDim(4); -		_screen->clearCurDim();		 +		clearCurDim();		  	} else {  		_screen->setScreenDim(3); -		_screen->clearCurDim(); +		clearCurDim();  		_screen->copyColour(192, col);  		_vm->enableTimer(11);  	} @@ -360,10 +360,7 @@ void TextDisplayer_LoL::displayText(char *str, ...) {  		switch (c - 1) {  			case 0:  				printLine(_currentLine); -				//if (!_dlgAnimCallback) -				//	break; - -				portraitAnimation2(); +				textPageBreak();  				_numCharsPrinted = 0;  				break; @@ -478,10 +475,8 @@ void TextDisplayer_LoL::printLine(char *str) {  	while (_posY >= lines) {  		if (lines <= _screen->_dimLineCount && _animFlag) {  			_screen->_dimLineCount = 0; -			//if (_dlgAnimCallback) { -				portraitAnimation2(); -				_numCharsPrinted = 0; -			//} +			textPageBreak(); +			_numCharsPrinted = 0;  		}  		int h1 = ((sd->h / fh) - 1) * fh; @@ -490,9 +485,9 @@ void TextDisplayer_LoL::printLine(char *str) {  		if (h2)  			_screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK); -		_screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _colour2); - -		_posY--; +		_screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _colour2);	 +		if (_posY) +			_posY--;  	}  	int x1 = (sd->sx << 3) + _posX; @@ -567,12 +562,122 @@ void TextDisplayer_LoL::printLine(char *str) {  	printLine(str);  } -/*void TextDisplayer_LoL::portraitAnimation1(const char *str, uint16 lineWidth, uint8 col1, uint8 col2, uint16 numCharsPrinted) { -	 -}*/ +void TextDisplayer_LoL::textPageBreak() { +	int cp = _screen->setCurPage(0); +	Screen::FontId cf = _screen->setFont(Screen::FID_6_FNT); + +	_vm->_timer->pauseSingleTimer(11, true); + +	_vm->_fadeText = false; +	int updateCharV3 = 0; +	int updatePortraitSpeechAnimDuration = 0; + +	if (_vm->_updateCharNum != -1)  { +		updateCharV3 = _vm->_updateCharV3; +		_vm->_updateCharV3 = 0; +		updatePortraitSpeechAnimDuration = _vm->_updatePortraitSpeechAnimDuration; +		if (_vm->_updatePortraitSpeechAnimDuration > 36) +			_vm->_updatePortraitSpeechAnimDuration = 36; +	} + +	uint32 speechPartTime = 0; +	if (_vm->_speechFlag && _vm->_activeVoiceFileTotalTime && _numChars) +		speechPartTime = _vm->_system->getMillis() + ((_numCharsPrinted * _vm->_activeVoiceFileTotalTime) / _numChars); + +	const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex()); + +	int x = ((dim->sx + dim->w) << 3) - 77; +	int y = 0; + +	if (_vm->_hideInventory && (_vm->_updateFlags & 2)) { +		if (_vm->_hideControls || !(_vm->_updateFlags & 2)) { +			y = dim->sy + dim->h - 5; +		} else { +			x += 6; +			y = dim->sy + dim->h - 2; +		}		 +	} else { +		y = dim->sy + dim->h - 10; +	} + +	_vm->gui_drawBox(x, y, 74, 9, 136, 251, -1); +	char *txt = _vm->getLangString(0x4073); +	_vm->_screen->printText(txt, x + 37 - (_vm->_screen->getTextWidth(txt) >> 1), y + 2, 144, 0); + +	_vm->removeInputTop(); + +	bool loop = true; +	bool target = false; + +	do { +		int inputFlag = _vm->checkInput(0, false) & 0xFF; +		_vm->removeInputTop(); + +		while (!inputFlag) { +			_vm->update(); +		 +			if (_vm->_speechFlag) { +				if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_characterSpeaking() != 2)) && speechPartTime) { +					loop = false; +					inputFlag = 43; +					break; +				} +			} + +			inputFlag = _vm->checkInput(0, false) & 0xFF; +			_vm->removeInputTop(); +		} + +		_vm->gui_notifyButtonListChanged(); + +		switch (inputFlag) { +			case 43: +			case 61: +				loop = false; +				break; + +			case 199: +			case 201: +				if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + 74, y + 9)) +					target = true; +				break; + +			case 200: +			case 202: +				if (target) +					loop = false; +				break; + +			default: +				break; +		} +	} while (loop); + +	_screen->fillRect(x, y, x + 74, y + 9, _colour2); +	clearCurDim(); + +	_vm->_timer->pauseSingleTimer(11, false); + +	if (_vm->_updateCharNum != -1) { +		_vm->_updateCharV3 = updateCharV3; +		if (updatePortraitSpeechAnimDuration > 36) +			updatePortraitSpeechAnimDuration -= 36; +		else +			updatePortraitSpeechAnimDuration >>= 1; + +		_vm->_updatePortraitSpeechAnimDuration = updatePortraitSpeechAnimDuration; +	} + +	_screen->setFont(cf); +	_screen->setCurPage(cp); +	_vm->removeInputTop(); +} -void TextDisplayer_LoL::portraitAnimation2() { -	// TODO +void TextDisplayer_LoL::clearCurDim() { +	const ScreenDim *tmp = _screen->getScreenDim(_screen->curDimIndex()); +	_screen->fillRect(tmp->sx << 3, tmp->sy, ((tmp->sx + tmp->w) << 3) - 1, (tmp->sy + tmp->h) - 1, _colour2); +	_screen->_dimLineCount = 0; +	_posX = _posY = 0;	  }  } // end of namespace Kyra diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h index 82eebd862d..9876bfbb56 100644 --- a/engines/kyra/text_lol.h +++ b/engines/kyra/text_lol.h @@ -55,12 +55,9 @@ private:  	void readNextPara();  	void printLine(char *str);  	void preprocessString(char *str, EMCState *script, const uint16 *paramList, int16 paramIndex); -	 -	//typedef void (LoLEngine::*DialogueAnimCallback)(const char *str, uint16 lineWidth, uint8 col1, uint8 col2); -	//DialogueAnimCallback _dlgAnimCallback; -	//void portraitAnimation1(const char *str); -	void portraitAnimation2(); -	 +	void textPageBreak();	 + +	void clearCurDim();  	char *_stringParameters[15];  	char *_buffer; @@ -71,7 +68,6 @@ private:  	char _ctrl[3];  	char _scriptParaString[11]; -	uint32 _stringLength;  	uint16 _lineWidth;  	uint32 _numChars;  | 
