diff options
| author | Gregory Montoir | 2008-11-15 02:32:05 +0000 | 
|---|---|---|
| committer | Gregory Montoir | 2008-11-15 02:32:05 +0000 | 
| commit | 8f230d735889bd5d52f517f657f8ffa6ee222394 (patch) | |
| tree | 64c1d53c2dc5e2b617b2f4e0690ce2d1d03ff599 | |
| parent | 48363b80fba5fd41fdfffdd1c551250ced15586d (diff) | |
| download | scummvm-rg350-8f230d735889bd5d52f517f657f8ffa6ee222394.tar.gz scummvm-rg350-8f230d735889bd5d52f517f657f8ffa6ee222394.tar.bz2 scummvm-rg350-8f230d735889bd5d52f517f657f8ffa6ee222394.zip  | |
added support for animation sequence
added support for non-interactive demo
fixed wrong end of demo screen when quitting the game using the inventory
svn-id: r35069
| -rw-r--r-- | engines/tucker/detection.cpp | 10 | ||||
| -rw-r--r-- | engines/tucker/graphics.h | 1 | ||||
| -rw-r--r-- | engines/tucker/resource.cpp | 57 | ||||
| -rw-r--r-- | engines/tucker/sequences.cpp | 638 | ||||
| -rw-r--r-- | engines/tucker/staticres.cpp | 370 | ||||
| -rw-r--r-- | engines/tucker/tucker.cpp | 214 | ||||
| -rw-r--r-- | engines/tucker/tucker.h | 118 | 
7 files changed, 1275 insertions, 133 deletions
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp index bf4063b11a..b3fa353b08 100644 --- a/engines/tucker/detection.cpp +++ b/engines/tucker/detection.cpp @@ -62,6 +62,14 @@ static const Common::ADGameDescription tuckerGameDescriptions[] = {  		Common::kPlatformPC,  		Common::ADGF_NO_FLAGS  	}, +	{ +		"tucker", +		"Demo", +		AD_ENTRY1s("sample.bnk", "0c58636237f90238cbfd49d76b3e5c1a", 10780), +		Common::EN_ANY, +		Common::kPlatformPC, +		Common::ADGF_DEMO +	},  	AD_TABLE_END_MARKER  }; @@ -91,7 +99,7 @@ public:  	virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {  		if (desc) { -			*engine = new Tucker::TuckerEngine(syst, desc->language); +			*engine = new Tucker::TuckerEngine(syst, desc->language, (desc->flags & Common::ADGF_DEMO) != 0);  		}  		return desc != 0;  	} diff --git a/engines/tucker/graphics.h b/engines/tucker/graphics.h index 4ca51c39ec..7ffabe3033 100644 --- a/engines/tucker/graphics.h +++ b/engines/tucker/graphics.h @@ -52,7 +52,6 @@ public:  	static void copyTo640(uint8 *dst, const uint8 *src, int w, int srcPitch, int h);  	static void drawStringChar(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src); -	static void drawStringChar2(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src);  	static const Charset _enCharset;  	static const Charset _frCharset; diff --git a/engines/tucker/resource.cpp b/engines/tucker/resource.cpp index 80ccb8f9a4..495637134e 100644 --- a/engines/tucker/resource.cpp +++ b/engines/tucker/resource.cpp @@ -173,6 +173,7 @@ uint8 *TuckerEngine::loadFile(uint8 *p) {  	}  	Common::File f;  	if (!f.open(_fileToLoad)) { +		warning("Unable to open '%s'", _fileToLoad);  		return 0;  	}  	const int sz = f.size(); @@ -208,13 +209,13 @@ void TuckerEngine::closeCompressedSoundFile() {  }  void TuckerEngine::loadImage(uint8 *dst, int type) { -	int count = 0;  	Common::File f;  	if (!f.open(_fileToLoad)) { +		warning("Unable to open '%s'", _fileToLoad);  		return;  	}  	f.seek(128, SEEK_SET); -	int size = 0; +	int size = 0, count = 0;  	while (size < 64000) {  		if (type == 2) {  			++count; @@ -765,46 +766,52 @@ void TuckerEngine::loadFx() {  	t.findIndex(_locationNum);  	t.findNextToken(kDataTokenDw);  	_locationSoundsCount = t.getNextInteger(); -	_locationSoundsTable[0].offset = 0;  	_currentFxSet = 0;  	for (int i = 0; i < _locationSoundsCount; ++i) { -		_locationSoundsTable[i].num = t.getNextInteger(); -		_locationSoundsTable[i].volume = t.getNextInteger(); -		_locationSoundsTable[i].type = t.getNextInteger(); -		if (_locationSoundsTable[i].type == 5) { +		LocationSound *s = &_locationSoundsTable[i]; +		s->offset = 0; +		s->num = t.getNextInteger(); +		s->volume = t.getNextInteger(); +		s->type = t.getNextInteger(); +		switch (s->type) { +		case 5:  			_currentFxSet = 1;  			_currentFxIndex = i; -			_currentFxVolume = _locationSoundsTable[i].volume; +			_currentFxVolume = s->volume;  			_currentFxDist = t.getNextInteger();  			_currentFxScale = t.getNextInteger(); -		} else if (_locationSoundsTable[i].type == 6 || _locationSoundsTable[i].type == 7 || _locationSoundsTable[i].type == 8) { -			_locationSoundsTable[i].startFxSpriteState = t.getNextInteger(); -			_locationSoundsTable[i].startFxSpriteNum = t.getNextInteger(); -			_locationSoundsTable[i].updateType = t.getNextInteger(); -			if (_locationSoundsTable[i].type == 7) { -				_locationSoundsTable[i].flagNum = t.getNextInteger(); -				_locationSoundsTable[i].flagValueStartFx = t.getNextInteger(); -				_locationSoundsTable[i].stopFxSpriteState = t.getNextInteger(); -				_locationSoundsTable[i].stopFxSpriteNum = t.getNextInteger(); -				_locationSoundsTable[i].flagValueStopFx = t.getNextInteger(); +			break; +		case 6: +		case 7: +		case 8: +			s->startFxSpriteState = t.getNextInteger(); +			s->startFxSpriteNum = t.getNextInteger(); +			s->updateType = t.getNextInteger(); +			if (s->type == 7) { +				s->flagNum = t.getNextInteger(); +				s->flagValueStartFx = t.getNextInteger(); +				s->stopFxSpriteState = t.getNextInteger(); +				s->stopFxSpriteNum = t.getNextInteger(); +				s->flagValueStopFx = t.getNextInteger();  			} +			break;  		} -		if (_locationSoundsTable[i].type == 8) { -			_locationSoundsTable[i].type = 6; +		if (s->type == 8) { +			s->type = 6;  		}  	}  	t.findNextToken(kDataTokenDw);  	int count = t.getNextInteger(); -	_locationMusicsTable[0].offset = _locationSoundsTable[_locationSoundsCount].offset;  	_locationMusicsCount = 0;  	for (int i = 0; i < count; ++i) {  		int flagNum = t.getNextInteger();  		int flagValue = t.getNextInteger();  		if (flagValue == _flagsTable[flagNum]) { -			_locationMusicsTable[_locationMusicsCount].num = t.getNextInteger(); -			_locationMusicsTable[_locationMusicsCount].volume = t.getNextInteger(); -			_locationMusicsTable[_locationMusicsCount].flag = t.getNextInteger(); -			++_locationMusicsCount; +			LocationMusic *m = &_locationMusicsTable[_locationMusicsCount++]; +			m->offset = 0; +			m->num = t.getNextInteger(); +			m->volume = t.getNextInteger(); +			m->flag = t.getNextInteger();  		} else {  			for (int j = 0; j < 3; ++j) {  				t.getNextInteger(); diff --git a/engines/tucker/sequences.cpp b/engines/tucker/sequences.cpp index 0a1faa4e52..7540312cd2 100644 --- a/engines/tucker/sequences.cpp +++ b/engines/tucker/sequences.cpp @@ -23,6 +23,11 @@   *   */ +#include "common/system.h" + +#include "sound/audiostream.h" +#include "sound/wave.h" +  #include "tucker/tucker.h"  #include "tucker/graphics.h" @@ -477,4 +482,637 @@ int TuckerEngine::handleSpecialObjectSelectionSequence() {  	return 1;  } +AnimationSequencePlayer::AnimationSequencePlayer(OSystem *system, Audio::Mixer *mixer, Common::EventManager *event, int num) +	: _system(system), _mixer(mixer), _event(event), _seqNum(num), _currentSeqNum(0) { +	_newSeq = false; +	memset(_animationPalette, 0, sizeof(_animationPalette)); +	memset(_paletteBuffer, 0, sizeof(_paletteBuffer)); +	memset(_flicPlayer, 0, sizeof(_flicPlayer)); +	_soundsListSeqData = 0; +	_soundsList1 = 0; +	_soundsList1Count = 0; +	_soundsList2 = 0; +	_soundsList2Count = 0; +	_musicVolume = 0; +	_offscreenBuffer = (uint8 *)malloc(kScreenWidth * kScreenHeight); +	_updateScreenWidth = 0; +	_updateScreenPicture = 0; +	_updateScreenOffset = 0; +	_frameCounter = 0; +	_frameTime = 1; +	_lastFrameTime = 0; +	_picBufPtr = _pic2BufPtr = 0; +} + +AnimationSequencePlayer::~AnimationSequencePlayer() { +	unloadAnimation(); +	free(_offscreenBuffer); +} + +void AnimationSequencePlayer::mainLoop() { +	do { +		if (_seqNum != _currentSeqNum) { +			unloadAnimation(); +			_currentSeqNum = _seqNum; +			_newSeq = true; +			_frameCounter = 0; +			_lastFrameTime = _system->getMillis(); +		} +		switch (_seqNum) { +		case 17: +			introSeq17_18(); +			break; +		case 19: +			introSeq19_20(); +			break; +		case 3: +			introSeq3_4(); +			break; +		case 9: +			introSeq9_10(); +			break; +		case 21: +			introSeq21_22(); +			break; +		case 13: +			introSeq13_14(); +			break; +		case 15: +			introSeq15_16(); +			break; +		case 27: +			introSeq27_28(); +			break; +		} +		_system->copyRectToScreen(_offscreenBuffer, 320, 0, 0, kScreenWidth, kScreenHeight); +		_system->setPalette(_animationPalette, 0, 256); +		_system->updateScreen(); +		syncTime(); +	} while (_seqNum != 1); +} + +void AnimationSequencePlayer::syncTime() { +	uint32 end = _lastFrameTime + kSequenceFrameTime * _frameTime; +	do { +		Common::Event ev; +		while (_event->pollEvent(ev)) { +			switch (ev.type) { +			case Common::EVENT_KEYDOWN: +				if (ev.kbd.keycode == Common::KEYCODE_ESCAPE) { +					_seqNum = 1; +				} +				break; +			case Common::EVENT_QUIT: +			case Common::EVENT_RTL: +				_seqNum = 1; +				break; +			default: +				break; +			} +		} +	} while (_system->getMillis() <= end); +	_lastFrameTime = _system->getMillis(); +} + +Audio::AudioStream *AnimationSequencePlayer::loadSoundFileAsStream(const char *name, AnimationSoundType type) { +	Audio::AudioStream *stream = 0; +	char fileName[64]; +	snprintf(fileName, sizeof(fileName), "audio/%s", name); +	Common::File f; +	if (f.open(fileName)) { +		uint8 *sampleData = 0; +		int size = 0, rate = 0; +		uint8 flags = 0; +		switch (type) { +		case kAnimationSoundType8BitsRAW: +		case kAnimationSoundType16BitsRAW: +			size = f.size(); +			rate = 22050; +			flags = Audio::Mixer::FLAG_UNSIGNED; +			if (type == kAnimationSoundType16BitsRAW) { +				flags = Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_16BITS; +			} +			break; +		case kAnimationSoundTypeWAV: +		case kAnimationSoundTypeLoopingWAV: +			Audio::loadWAVFromStream(f, size, rate, flags); +			if (type == kAnimationSoundTypeLoopingWAV) { +				flags |= Audio::Mixer::FLAG_LOOP; +			} +			break; +		} +		if (size != 0) { +			sampleData = (uint8 *)malloc(size); +			if (sampleData) { +				f.read(sampleData, size); +				flags |= Audio::Mixer::FLAG_AUTOFREE; +				stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0); +			} +		} +	} +	return stream; +} + +void AnimationSequencePlayer::loadSounds(int type, int num) { +	int index = 0; +	switch (type) { +	case 1: +		switch (num) { +		case 0: +			index = 1; +			_soundsList1Count = 14; +			_soundsList1 = _soundFilesList1; +			_soundsList2Count = 10; +			_soundsList2 = _soundFilesList2; +			_soundsListSeqData = _soundSeqData2; +			break; +		case 1: +			index = 1; +			_soundsList1Count = 14; +			_soundsList1 = _soundFilesList3; +			_soundsList2Count = 5; +			_soundsList2 = _soundFilesList4; +			_soundsListSeqData = _soundSeqData3; +			break; +		case 2: +			index = 1; +			_soundsList1Count = 14; +			_soundsList1 = _soundFilesList5; +			_soundsList2Count = 9; +			_soundsList2 = _soundFilesList6; +			_soundsListSeqData = _soundSeqData4; +			break; +		} +		_musicVolume = 0; +		break; +	case 3: +		switch (num) { +		case 0: +			index = 3; +			_soundsList1Count = 13; +			_soundsList1 = _soundFilesList7; +			_soundsList2Count = 0; +			_soundsListSeqData = _soundSeqData5; +			break; +		case 1: +			index = 6; +			_soundsList1Count = 14; +			_soundsList1 = _soundFilesList8; +			_soundsList2Count = 4; +			_soundsList2 = _soundFilesList9; +			_soundsListSeqData = _soundSeqData6; +			break; +		case 2: +			index = 7; +			_soundsList1Count = 13; +			_soundsList1 = _soundFilesList10; +			_soundsList2Count = 9; +			_soundsList2 = _soundFilesList11; +			_soundsListSeqData = _soundSeqData7; +			break; +		case 3: +			index = 10; +			_soundsList1Count = 11; +			_soundsList1 = _soundFilesList12; +			_soundsList2Count = 0; +			_soundsListSeqData = _soundSeqData8; +			break; +		} +		_musicVolume = 80; +		break; +	case 4: +		switch (num) { +		case 0: +			index = 4; +			_soundsList1Count = 6; +			_soundsList1 = _soundFilesList13; +			_soundsList2Count = 0; +			_soundsListSeqData = _soundSeqData9; +			break; +		case 1: +			index = 9; +			_soundsList1Count = 10; +			_soundsList1 = _soundFilesList14; +			_soundsList2Count = 0; +			_soundsListSeqData = _soundSeqData10; +			break; +		} +		_musicVolume = 80; +		break; +	case 5: +		index = 5; +		_soundsList1Count = 0; +		_soundsList2Count = 0; +		_soundsListSeqData = _soundSeqData1; +		_musicVolume = 100; +		break; +	case 9: +		index = 8; +		_soundsList1Count = 0; +		_soundsList2Count = 0; +		_soundsListSeqData = _soundSeqData1; +		_musicVolume = 100; +		break; +	case 10: +		index = 0; +		_soundsList1Count = 4; +		_soundsList1 = _soundFilesList15; +		_soundsList2Count = 0; +		_soundsListSeqData = _soundSeqData11; +		_musicVolume = 100; +		break; +	default: +		index = 0; +		_soundsList1Count = 0; +		_soundsList2Count = 0; +		_soundsListSeqData = _soundSeqData1; +		_musicVolume = 100; +		break; +	} +	if (_musicVolume != 0) { +		Audio::AudioStream *s; +		if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], (type == 5) ? kAnimationSoundType16BitsRAW : kAnimationSoundType8BitsRAW)) != 0) { +			_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); +		} +	} +} + +void AnimationSequencePlayer::updateSounds() { +	Audio::AudioStream *s = 0; +	int index; +	const int *p = _soundsListSeqData; +	while (p[0] != -1 && p[0] <= _frameCounter) { +		switch (p[2]) { +		case 0: +			if ((index = p[1]) < _soundsList1Count) { +				if ((s = loadSoundFileAsStream(_soundsList1[index], kAnimationSoundTypeWAV)) != 0) { +					_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); +				} +			} +			break; +		case 1: +			if ((index = p[1]) < _soundsList1Count) { +				if ((s = loadSoundFileAsStream(_soundsList1[index], kAnimationSoundTypeLoopingWAV)) != 0) { +					_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); +				} +			} +			break; +		case 2: +			if ((index = p[1]) < _soundsList1Count) { +				_mixer->stopHandle(_soundsHandle[index]); +			} +			break; +		case 3: +			_mixer->stopHandle(_musicHandle); +			break; +		case 4: +			_mixer->stopHandle(_musicHandle); +			index = p[1]; +			if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], kAnimationSoundType8BitsRAW)) != 0) { +				_musicVolume = p[3]; +				_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); +			} +			break; +		case 5: +			if ((index = p[1]) < _soundsList2Count) { +				if ((s = loadSoundFileAsStream(_soundsList2[index], kAnimationSoundTypeWAV)) != 0) { +					_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); +				} +			} +			break; +		case 6: +			_mixer->stopHandle(_musicHandle); +			index = p[1]; +			if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], kAnimationSoundType16BitsRAW)) != 0) { +				_musicVolume = p[3]; +				_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); +			} +			break; +		default: +			warning("Unhandled sound opcode %d (%d,%d)", p[2], _frameCounter, p[0]); +			break; +		} +		p += 4; +	} +	_soundsListSeqData = p; +} + +void AnimationSequencePlayer::fadeInPalette() { +	memset(_paletteBuffer, 0, sizeof(_paletteBuffer)); +	bool fadeColors = true; +	for (int step = 0; step < 64; ++step) { +		if (fadeColors) { +			fadeColors = false; +			for (int i = 0; i < 1024; ++i) { +				if ((i & 3) != 3 && _paletteBuffer[i] < _animationPalette[i]) { +					const int color = _paletteBuffer[i] + 4; +					_paletteBuffer[i] = MIN<int>(color, _animationPalette[i]); +					fadeColors = true; +				} +			} +			_system->setPalette(_paletteBuffer, 0, 256); +			_system->updateScreen(); +		} +		_system->delayMillis(1000 / 60); +	} +} + +void AnimationSequencePlayer::fadeOutPalette() { +	memcpy(_paletteBuffer, _animationPalette, 1024); +	bool fadeColors = true; +	for (int step = 0; step < 64; ++step) { +		if (fadeColors) { +			fadeColors = false; +			for (int i = 0; i < 1024; ++i) { +				if ((i & 3) != 3 && _paletteBuffer[i] > 0) { +					const int color = _paletteBuffer[i] - 4; +					_paletteBuffer[i] = MAX<int>(0, color); +					fadeColors = true; +				} +			} +			_system->setPalette(_paletteBuffer, 0, 256); +			_system->updateScreen(); +		} +		_system->delayMillis(1000 / 60); +	} +	_system->clearScreen(); +} + +void AnimationSequencePlayer::unloadAnimation() { +	_mixer->stopAll(); +	for (int i = 0; i < ARRAYSIZE(_flicPlayer); ++i) { +		delete _flicPlayer[i]; +		_flicPlayer[i] = 0; +	} +	free(_picBufPtr); +	_picBufPtr = 0; +	free(_pic2BufPtr); +	_pic2BufPtr = 0; +} + +uint8 *AnimationSequencePlayer::loadPicture(const char *fileName) { +	uint8 *p = 0; +	Common::File f; +	if (f.open(fileName)) { +		const int sz = f.size(); +		p = (uint8 *)malloc(sz); +		if (p) { +			f.read(p, sz); +		} +	} +	return p; +} + +void AnimationSequencePlayer::openAnimation(int index, const char *fileName) { +	_flicPlayer[index] = new ::Graphics::FlicPlayer(fileName); +	_flicPlayer[index]->decodeFrame(); +	if (index == 0) { +		memcpy(_animationPalette, _flicPlayer[index]->getPalette(), 1024); +		memcpy(_offscreenBuffer, _flicPlayer[index]->getOffscreen(), kScreenWidth * kScreenHeight); +	} +} + +void AnimationSequencePlayer::decodeNextAnimationFrame(int index) { +	_flicPlayer[index]->decodeFrame(); +	memcpy(_offscreenBuffer, _flicPlayer[index]->getOffscreen(), kScreenWidth * kScreenHeight); +	if (index == 0) { +		if (_flicPlayer[index]->isPaletteDirty()) { +			memcpy(_animationPalette, _flicPlayer[index]->getPalette(), 1024); +		} +	} +	if (_seqNum != 19) { +		++_frameCounter; +	} +} + +void AnimationSequencePlayer::introSeq17_18() { +	if (_newSeq) { +		loadSounds(9, 0); +		openAnimation(0, "graphics/merit.flc"); +		_frameTime = 1; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 19; +	} +	updateSounds(); +} + +void AnimationSequencePlayer::introSeq19_20() { +	if (_newSeq) { +		fadeOutPalette(); +		loadSounds(10, 1); +		openAnimation(0, "graphics/budttle2.flc"); +		openAnimation(1, "graphics/machine.flc"); +		_frameTime = 1; +		_newSeq = false; +	} +	if (_flicPlayer[0]->getCurFrame() >= 116) { +		_flicPlayer[1]->decodeFrame(); +		if (_flicPlayer[1]->getCurFrame() == _flicPlayer[1]->getFrameCount()) { +			_flicPlayer[1]->reset(); +		} +	} +	_flicPlayer[0]->decodeFrame(); +	const uint8 *t = _flicPlayer[1]->getOffscreen(); +	for (int i = 0; i < 64000; ++i) { +		const uint8 color = _flicPlayer[0]->getOffscreen()[i]; +		_offscreenBuffer[i] = color ? color : t[i]; +	} +	updateSounds(); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 3; +	} +} + +void AnimationSequencePlayer::displayLoadingScreen() { +	Common::File f; +	if (f.open("graphics/loading.pic")) { +		fadeOutPalette(); +		f.seek(32); +		for (int i = 0; i < 1024; i += 4) { +			f.read(_animationPalette + i, 3); +		} +		f.read(_offscreenBuffer, 64000); +		_system->copyRectToScreen(_offscreenBuffer, 320, 0, 0, kScreenWidth, kScreenHeight); +		fadeInPalette(); +	} +} + +void AnimationSequencePlayer::initPicPart4() { +	_updateScreenWidth = 320; +	_updateScreenPicture = 1; +	_updateScreenOffset = 0; +} + +void AnimationSequencePlayer::drawPicPart4() { +	static const uint8 offsetsTable[77] = { +		1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, +		5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +		6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, +		3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 +	}; +	_updateScreenWidth = _updateScreenWidth - offsetsTable[_updateScreenOffset]; +	++_updateScreenOffset; +	for (int y = 0; y < 200; ++y) { +		memcpy(_offscreenBuffer + y * 320, _picBufPtr + 800 + y * 640 + _updateScreenWidth, 320); +	} +	if (_updateScreenWidth == 0) { +		_updateScreenPicture = false; +	} +} + +void AnimationSequencePlayer::introSeq3_4() { +	if (_newSeq) { +		displayLoadingScreen(); +		loadSounds(1, 0); +		_picBufPtr = loadPicture("graphics/house.pic"); +		openAnimation(0, "graphics/intro1.flc"); +		_system->copyRectToScreen(_offscreenBuffer, 320, 0, 0, kScreenWidth, kScreenHeight); +		fadeInPalette(); +		_updateScreenPicture = false; +		_frameTime = 2; +		_newSeq = false; +	} +	if (!_updateScreenPicture) { +		decodeNextAnimationFrame(0); +		if (_flicPlayer[0]->getCurFrame() == 706) { +			initPicPart4(); +		} +		if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +			_seqNum = 9; +		} +	} else { +		drawPicPart4(); +	} +	updateSounds(); +} + +void AnimationSequencePlayer::drawPic2Part10() { +	for (int y = 0; y < 16; ++y) { +		for (int x = 0; x < 64; ++x) { +			const uint8 color = _pic2BufPtr[y * 64 + x]; +			if (color != 0) { +				_picBufPtr[89417 + y * 640 + x] = color; +			} +		} +	} +	for (int y = 0; y < 80; ++y) { +		for (int x = 0; x < 48; ++x) { +			const uint8 color = _pic2BufPtr[1024 + y * 48 + x]; +			if (color != 0) { +				_picBufPtr[63939 + y * 640 + x] = color; +			} +		} +	} +	for (int y = 0; y < 32; ++y) { +		for (int x = 0; x < 80; ++x) { +			const uint8 color = _pic2BufPtr[7424 + y * 80 + x]; +			if (color != 0) { +				_picBufPtr[33067 + y * 640 + x] = color; +			} +		} +	} +} + +void AnimationSequencePlayer::drawPic1Part10() { +	for (int y = 0; y < 200; ++y) { +		memcpy(_offscreenBuffer + y * 320, _picBufPtr + 800 + y * 640 + _updateScreenWidth, 320); +	} +	for (int i = 0; i < 64000; ++i) { +		const uint8 color = _flicPlayer[0]->getOffscreen()[i]; +		if (color) { +			_offscreenBuffer[i] = color; +		} +	} +} + +void AnimationSequencePlayer::introSeq9_10() { +	if (_newSeq) { +		loadSounds(1, 1); +		_pic2BufPtr = loadPicture("graphics/bits.pic"); +		_picBufPtr = loadPicture("graphics/lab.pic"); +		openAnimation(0, "graphics/intro2.flc"); +		_updateScreenWidth = 0; +		_frameTime = 2; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == 984) { +		drawPic2Part10(); +	} +	if (_flicPlayer[0]->getCurFrame() >= 264 && _flicPlayer[0]->getCurFrame() <= 295) { +		drawPic1Part10(); +		_updateScreenWidth += 6; +	} else if (_flicPlayer[0]->getCurFrame() >= 988 && _flicPlayer[0]->getCurFrame() <= 996) { +		drawPic1Part10(); +		_updateScreenWidth -= 25; +		if (_updateScreenWidth < 0) { +			_updateScreenWidth = 0; +		} +	} +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 21; +	} +	updateSounds(); +} + +void AnimationSequencePlayer::introSeq21_22() { +	if (_newSeq) { +		loadSounds(1, 2); +		openAnimation(0, "graphics/intro3.flc"); +		_frameTime = 2; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 1; +	} +	updateSounds(); +} + +void AnimationSequencePlayer::introSeq13_14() { +	if (_newSeq) { +		loadSounds(3, 1); +		openAnimation(0, "graphics/allseg02.flc"); +		_frameTime = 2; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 15; +	} +	updateSounds(); +} + +void AnimationSequencePlayer::introSeq15_16() { +	if (_newSeq) { +		loadSounds(3, 2); +		openAnimation(0, "graphics/allseg03.flc"); +		_frameTime = 2; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 27; +	} +	updateSounds(); +} + +void AnimationSequencePlayer::introSeq27_28() { +	if (_newSeq) { +		loadSounds(3, 3); +		openAnimation(0, "graphics/allseg04.flc"); +		_frameTime = 2; +		_newSeq = false; +	} +	decodeNextAnimationFrame(0); +	if (_flicPlayer[0]->getCurFrame() == _flicPlayer[0]->getFrameCount()) { +		_seqNum = 1; +	} +	updateSounds(); +} +  } // namespace Tucker diff --git a/engines/tucker/staticres.cpp b/engines/tucker/staticres.cpp index 9a2402039b..e5e41166df 100644 --- a/engines/tucker/staticres.cpp +++ b/engines/tucker/staticres.cpp @@ -242,4 +242,374 @@ const Graphics::Charset Graphics::_creditsCharset = { 19, 10, 16, 7 };  const Graphics::Charset *Graphics::_charset = 0; +// timestamp, index, opcode, volume + +const int AnimationSequencePlayer::_soundSeqData1[1] = { +	  -1, +}; + +const int AnimationSequencePlayer::_soundSeqData2[233] = { +	  16,    3,    1,  100,   18,    5,    1,  100,   26,    9,    5,  100,   74,    9,    0,  100, +	 118,   10,    0,  100,  139,    9,    0,  100,  140,   10,    2,  100,  144,    5,    2,  100, +	 146,    3,    2,  100,  147,    9,    2,  100,  148,    2,    1,  100,  156,    0,    1,   50, +	 158,    4,    5,  100,  188,    4,    5,  100,  212,    2,    2,  100,  223,    1,    0,  100, +	 230,    1,    2,  100,  234,    1,    0,  100,  251,    1,    0,  100,  265,   11,    6,   80, +	 293,    5,    1,   80,  295,   12,    6,   80,  343,   13,    6,  110,  373,   14,    6,   80, +	 429,    5,    2,  100,  431,   15,    6,   80,  456,    2,    1,  100,  457,    1,    5,  100, +	 463,    0,    5,  100,  482,    2,    2,  100,  483,    8,    1,  100,  494,    8,    5,  100, +	 507,    7,    5,  100,  511,    7,    5,  100,  522,   13,    1,  100,  547,    6,    5,  100, +	 548,   11,    0,  100,  556,   12,    0,  100,  557,    2,    5,  100,  599,    7,    1,  100, +	 639,    7,    2,  100,  641,   12,    0,  100,  642,    7,    5,  100,  718,   14,    2,  100, +	 719,    1,    2,  100,  720,    2,    2,  100,  721,    3,    2,  100,  722,    4,    2,  100, +	 723,    5,    2,  100,  724,    6,    2,  100,  725,    7,    2,  100,  726,    8,    2,  100, +	 727,    9,    2,  100,  728,   10,    2,  100,  729,   11,    2,  100,  730,   12,    2,  100, +	 731,    0,    2,  100,  732,   13,    2,  100,   -1, +}; + +const int AnimationSequencePlayer::_soundSeqData3[241] = { +	   2,    0,    3,  100,    3,    2,    0,  100,    3,    5,    1,   20,    6,   25,    6,   80, +	  22,    1,    5,  100,   37,   29,    6,   80,   59,   30,    6,   80,   69,   26,    6,   80, +	 124,   27,    6,   80,  163,   28,    6,   80,  197,   31,    6,   80,  224,   32,    6,   80, +	 306,   33,    6,   80,  350,   34,    6,   80,  388,    8,    0,  100,  389,    6,    1,  100, +	 390,    9,    1,  100,  395,   10,    0,  100,  398,    3,    0,  100,  408,    3,    0,  100, +	 413,    4,    0,  100,  418,    3,    0,  100,  426,    6,    2,  100,  427,    9,    2,  100, +	 430,   35,    6,   80,  472,   36,    6,   80,  514,    9,    1,  100,  515,    7,    0,  100, +	 516,    6,    1,  100,  517,    4,    0,  100,  520,   11,    0,  100,  523,    3,    0,  100, +	 531,    7,    2,  100,  532,    9,    2,  100,  533,    6,    2,  100,  534,    3,    0,  100, +	 535,   37,    6,   80,  553,   38,    6,   80,  569,   39,    6,   80,  588,   40,    6,   80, +	 662,   41,    6,   80,  777,   42,    6,   80,  978,    1,    0,  100, 1008,   12,    0,  100, +	1011,    4,    5,  100, 1022,   52,    6,   80, 1039,    3,    5,  100, 1045,    3,    5,  100, +	1051,    3,    5,  100, 1057,    3,    5,  100, 1063,    3,    5,  100, 1066,    3,    5,   40, +	1074,   43,    6,   80, 1256,   44,    6,   80, 1322,   45,    6,   80, 1373,   46,    6,   80, +	1419,   47,    6,   80, 1792,   13,    0,  100, 1793,    0,    5,  100, 1895,   51,    6,   80, +	  -1, +}; + +const int AnimationSequencePlayer::_soundSeqData4[193] = { +	   2,    0,    3,  100,    4,    3,    1,   40,    5,    7,    1,   20,    7,    3,    5,  100, +	  62,    3,    2,  100,   63,   48,    6,   80,  198,    7,    2,  100,  202,    5,    1,  100, +	 203,   16,    6,   80,  211,    1,    5,  100,  216,    0,    1,   40,  217,    5,    2,  100, +	 218,    6,    1,  100,  224,    2,    5,  100,  229,   17,    6,   80,  273,    6,    2,  100, +	 274,    4,    1,  100,  275,    4,    5,  100,  335,    1,    1,  100,  336,   13,    0,  100, +	 339,   11,    0,  100,  358,    0,    5,  100,  364,   24,    4,  100,  397,    7,    5,  100, +	 399,    6,    5,  100,  433,    5,    5,  100,  451,   13,    0,  100,  459,    1,    2,  100, +	 508,    4,    2,  100,  509,    1,    1,  100,  521,   11,    0,  100,  530,    8,    0,  100, +	 537,    9,    0,  100,  557,    8,    5,  100,  578,    5,    5,  100,  602,   13,    0,  100, +	 609,    1,    2,  100,  626,   12,    0,  100,  628,   10,    0,  100,  670,    6,    5,  100, +	 690,   10,    0,  100,  692,    3,    5,  100,  705,   11,    0,  100,  710,    2,    5,  100, +	 714,    9,    0,  100,  720,    9,    2,  100,  721,    7,    5,  100,  725,    0,    5,  100, +	  -1, +}; + +const int AnimationSequencePlayer::_soundSeqData5[77] = { +	   3,    8,    0,  100,   43,   11,    0,  100,   68,    5,    1,  100,  100,    5,    2,  100, +	 104,    6,    0,  100,  139,    7,    0,  100,  192,    3,    0,  100,  199,    4,    0,  100, +	 207,    4,    0,  100,  208,    2,    0,  100,  254,    0,    0,  100,  260,    0,    0,  100, +	 266,    0,    0,  100,  272,    0,    0,  100,  276,    0,    0,  100,  282,    1,    0,  100, +	 303,   10,    0,  100,  319,   12,    0,  100,  355,    9,    0,  100,   -1, +}; + +const int AnimationSequencePlayer::_soundSeqData6[101] = { +	   3,    0,    1,  100,   34,    0,    2,  100,   57,    0,    5,  100,   77,    0,    5,  100, +	  84,    9,    0,  100,  100,    9,    0,  100,  140,    3,    5,  100,  157,    2,    5,  100, +	 158,    1,    0,  100,  204,    1,    5,  100,  220,    2,    1,  100,  235,    7,    0,  100, +	 236,    2,    2,  100,  248,   12,    0,  100,  251,   13,    0,  100,  265,   11,    0,  100, +	 276,   11,    0,  100,  310,    5,    0,  100,  335,    6,    0,  100,  370,    4,    0,  100, +	 373,    8,    0,  100,  378,    8,    0,  100,  434,   10,    0,  100,  453,    3,    0,  100, +	 484,    3,    2,  100,   -1, +}; + +const int AnimationSequencePlayer::_soundSeqData7[173] = { +	   3,    4,    5,  100,   10,    5,    5,  100,   22,    6,    5,  100,   32,    7,    5,  100, +	  39,    6,    5,  100,   48,    7,    5,  100,   57,    6,    5,  100,   65,    3,    0,   50, +	 102,    4,    0,   50,  151,    2,    5,   50,  205,    3,    5,  100,  218,    0,    5,  100, +	 227,    0,    5,  100,  236,    0,    5,  100,  245,    0,    5,  100,  254,    0,    5,  100, +	 263,    0,    5,  100,  272,    0,    5,  100,  291,    1,    1,   40,  309,    8,    5,  100, +	 360,    8,    5,  100,  384,    2,    1,   60,  398,   10,    0,  100,  440,    2,    2,  100, +	 441,    1,    2,  100,  452,   11,    0,  100,  466,    1,    5,  100,  470,    8,    0,  100, +	 503,    6,    0,  100,  519,    7,    0,  100,  536,    8,    0,  100,  538,    4,    5,  100, +	 549,    5,    5,  100,  558,    4,    5,  100,  568,    5,    5,  100,  578,    4,    5,  100, +	 586,    5,    5,  100,  593,    4,    5,  100,  600,    5,    5,  100,  606,    4,    5,  100, +	 613,    5,    5,  100,  620,    9,    0,  100,  630,   12,    0,  100,   -1, +}; + +const int AnimationSequencePlayer::_soundSeqData8[45] = { +	  17,    2,    0,  100,   57,    8,    0,  100,   62,   10,    0,  100,   67,    9,    0,  100, +	  74,    3,    1,  100,   87,    3,    2,  100,   85,    0,    0,  100,  138,    5,    0,  100, +	 196,    7,    0,  100,  222,    6,    0,  100,  228,    1,    0,  100,   -1, +}; + +const int AnimationSequencePlayer::_soundSeqData9[49] = { +	  20,    4,    0,  100,  132,    0,    0,  100,  145,    0,    2,  100,  171,    1,    0,  100, +	 315,    2,    0,   50,  334,    3,    0,  100,  602,    5,    0,   50,  631,    5,    0,   50, +	 660,    5,    0,   50,  767,    5,    0,   50,  795,    5,    0,   50,  824,    5,    0,   50, +	  -1, +}; + +const int AnimationSequencePlayer::_soundSeqData10[97] = { +	   4,    8,    1,  100,    5,    6,    0,  100,   47,    8,    2,  100,  125,    8,    1,  100, +	 126,    6,    0,  100,  156,    8,    2,  100,  168,    2,    0,  100,  174,    2,    0,  100, +	 180,    2,    0,  100,  186,    2,    0,  100,  192,    2,    0,  100,  267,    2,    0,  100, +	 273,    2,    0,  100,  279,    2,    0,  100,  285,    2,    0,  100,  291,    2,    0,  100, +	 297,    2,    0,  100,  302,    0,    0,  100,  417,    1,    0,  100,  472,    5,    0,  100, +	 600,    5,    0,  100,  623,    3,    0,  100,  643,    9,    0,  100,  781,    4,    0,   80, +	  -1, +}; + +const int AnimationSequencePlayer::_soundSeqData11[29] = { +	   2,    0,    3,  100,    3,    0,    1,  100,   33,    0,    2,  100,   33,    1,    0,  100, +	  53,    2,    1,  100,   78,    2,    2,  100,   80,    0,    4,  100,   -1, +}; + +const char *AnimationSequencePlayer::_musicFileNamesTable[53] = { +	"DemoMenu.raw", +	"IntroduB.raw", +	"IntroduA.raw", +	"DemoRolA.raw", +	"DemoChA1.raw", +	"icrmusic.raw", +	"DemoRolC.raw", +	"DemoRolC.raw", +	"MeriLogo.raw", +	"DemoChA2.raw", +	"DemoRolC.raw", +	"int1.raw", +	"int2.raw", +	"int3.raw", +	"int4.raw", +	"int5.raw", +	"int6.raw", +	"int7.raw", +	"int8.raw", +	"int9.raw", +	"int10.raw", +	"int11.raw", +	"int12.raw", +	"int13.raw", +	"int14.raw", +	"int15.raw", +	"int16.raw", +	"int17.raw", +	"int18.raw", +	"int19.raw", +	"int20.raw", +	"int21.raw", +	"int22.raw", +	"int23.raw", +	"int24.raw", +	"int25.raw", +	"int26.raw", +	"int27.raw", +	"int28.raw", +	"int29.raw", +	"int30.raw", +	"int31.raw", +	"int32.raw", +	"int33.raw", +	"int34.raw", +	"int35.raw", +	"int36.raw", +	"int37.raw", +	"int38.raw", +	"int39.raw", +	"int40.raw", +	"int41.raw", +	"int42.raw" +}; + +const char *AnimationSequencePlayer::_soundFilesList1[14] = { +	"IntroduA.wav", +	"FX35.wav", +	"FX47.wav", +	"FX50.wav", +	"FX51.wav", +	"FX52.wav", +	"FX54.wav", +	"FX58.wav", +	"FX59.wav", +	"FX53.wav", +	"FX55.wav", +	"FX68.wav", +	"FX57.wav", +	"FX36.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList2[10] = { +	"FX33.wav", +	"FX34.wav", +	"FX38.wav", +	"FX39.wav", +	"FX48.wav", +	"FX49.wav", +	"FX69.wav", +	"FX32.wav", +	"FX56.wav", +	"FX117.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList3[14] = { +	"IntroduA.wav", +	"FX37.wav", +	"FX49.wav", +	"FX72.wav", +	"FX73.wav", +	"FX74.wav", +	"FX75.wav", +	"FX76.wav", +	"FX77.wav", +	"FX78.wav", +	"FX79.wav", +	"FX80.wav", +	"FX81.wav", +	"FX83.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList4[5] = { +	"FX70.wav", +	"FX33.wav", +	"RDFX12.wav", +	"FX86.wav", +	"FX116.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList5[14] = { +	"IntroduA.wav", +	"FX36.wav", +	"FX46.wav", +	"FX52.wav", +	"FX59.wav", +	"FX66.wav", +	"FX67.wav", +	"FX74.wav", +	"RDFX26.wav", +	"FX42.wav", +	"FX43.wav", +	"FX44.wav", +	"FX45.wav", +	"FX61.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList6[9] = { +	"FX40.wav", +	"FX60.wav", +	"FX62.wav", +	"FX71.wav", +	"FX63.wav", +	"FX64.wav", +	"FX68.wav", +	"FX69.wav", +	"RDFX12.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList7[13] = { +	"RDFX1.wav", +	"RDFX2.wav", +	"RDFX4.wav", +	"RDFX5.wav", +	"RDFX6.wav", +	"RDFX7.wav", +	"RDFX10.wav", +	"RDFX11.wav", +	"RDFX12.wav", +	"RDFX19.wav", +	"RDFX29.wav", +	"RDFX32.wav", +	"RDFX35.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList8[14] = { +	"RDFX8.wav", +	"RDFX9.wav", +	"RDFX13.wav", +	"RDFX14.wav", +	"RDFX33.wav", +	"RDFX16.wav", +	"RDFX18.wav", +	"RDFX20.wav", +	"RDFX38.wav", +	"FX39.wav", +	"RDFX28.wav", +	"RDFX25.wav", +	"RDFX26.wav", +	"RDFX27.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList9[4] = { +	"RDFX31.wav", +	"RDFX21.wav", +	"RDFX15.wav", +	"FX34.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList10[13] = { +	"FX96.wav", +	"FX74.wav", +	"FX75.wav", +	"FX97.wav", +	"FX98.wav", +	"FX106.wav", +	"FX107.wav", +	"FX108.wav", +	"FX109.wav", +	"FX110.wav", +	"FX93.wav", +	"FX83.wav", +	"FX111.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList11[9] = { +	"FX86.wav", +	"FX101.wav", +	"FX112.wav", +	"FX104.wav", +	"FX102.wav", +	"FX103.wav", +	"FX91.wav", +	"FX92.wav", +	"FX105.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList12[11] = { +	"RDFX3.wav", +	"RDFX9.wav", +	"RDFX17.wav", +	"RDFX22.wav", +	"RDFX23.wav", +	"RDFX24.wav", +	"RDFX30.wav", +	"RDFX36.wav", +	"RDFX1.wav", +	"RDFX16.wav", +	"RDFX37.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList13[6] = { +	"FX82.wav", +	"FX80.wav", +	"FX89.wav", +	"FX90.wav", +	"FX83.wav", +	"FX84.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList14[10] = { +	"RDFX2.wav", +	"FX85.wav", +	"FX86.wav", +	"FX87.wav", +	"FX88.wav", +	"FX99.wav", +	"FX98.wav", +	"FX97.wav", +	"FX96.wav", +	"FX100.wav" +}; + +const char *AnimationSequencePlayer::_soundFilesList15[4] = { +	"rdfx22.wav", +	"fx113.wav", +	"fx114.wav", +	"fx115.wav" +}; +  } // namespace Tucker diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp index 3e7a0be19b..f2b134ba3c 100644 --- a/engines/tucker/tucker.cpp +++ b/engines/tucker/tucker.cpp @@ -34,15 +34,15 @@  namespace Tucker { -TuckerEngine::TuckerEngine(OSystem *system, Common::Language language) -	: Engine(system), _lang(language) { +TuckerEngine::TuckerEngine(OSystem *system, Common::Language language, bool isDemo) +	: Engine(system), _lang(language), _isDemo(isDemo) {  }  TuckerEngine::~TuckerEngine() {  }  Common::Error TuckerEngine::init() { -	initGraphics(320, 200, false); +	initGraphics(kScreenWidth, kScreenHeight, false);  	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));  	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); @@ -55,7 +55,13 @@ bool TuckerEngine::hasFeature(EngineFeature f) const {  }  Common::Error TuckerEngine::go() { -	mainLoop(); +	const int firstSequence = _isDemo ? kFirstAnimationSequenceDemo : kFirstAnimationSequenceGame; +	AnimationSequencePlayer *player = new AnimationSequencePlayer(_system, _mixer, _eventMan, firstSequence); +	player->mainLoop(); +	delete player; +	if (!_isDemo && !shouldQuit()) { +		mainLoop(); +	}  	return Common::kNoError;  } @@ -111,7 +117,7 @@ void TuckerEngine::freeBuffers() {  }  void TuckerEngine::restart() { -	_quitGame = 0; +	_quitGame = false;  	_fastMode = false;  	_syncCounter = 0;  	_lastFrameTime = _system->getMillis(); @@ -123,7 +129,7 @@ void TuckerEngine::restart() {  	if (_nextLocationNum == 0) {  		_nextLocationNum = kStartupLocation;  	} -	_gamePaused = _gamePaused2 = 0; +	_gamePaused = _gamePaused2 = false;  	memset(_flagsTable, 0, sizeof(_flagsTable));  	_gameHintsIndex = 0; @@ -341,7 +347,7 @@ void TuckerEngine::mainLoop() {  	_spriteAnimationFrameIndex =  _spriteAnimationsTable[14].firstFrameIndex; -	while (1) { +	do {  		++_syncCounter;  		if (_flagsTable[137] != _flagsTable[138]) {  			loadBudSpr(0); @@ -426,7 +432,7 @@ void TuckerEngine::mainLoop() {  				} else {  					_fadedPanel = false;  					clearItemsGfx(); -					if (_gamePaused != 0) { +					if (_gamePaused) {  						drawPausedInfoBar();  					} else if (_gameHintsDisplayText == 1 && _mouseIdleCounter > 1000) {  						drawGameHintString(); @@ -462,7 +468,7 @@ void TuckerEngine::mainLoop() {  		drawData3();  		execData3PreUpdate();  		for (int i = 0; i < _spritesCount; ++i) { -			if (_spritesTable[i].disabled == 0) { +			if (!_spritesTable[i].disabled) {  				drawSprite(i);  			}  		} @@ -507,13 +513,13 @@ void TuckerEngine::mainLoop() {  			}  		}  		_lastKeyPressed = getLastKeyCode(); -		if (_gamePaused == 1 && _charSpeechSoundCounter == 0) { +		if (_gamePaused && _charSpeechSoundCounter == 0) {  			stopSounds(); -			_gamePaused2 = 1; +			_gamePaused2 = true;  			while (1) {  				if (_lastKeyPressed == Common::KEYCODE_p && _charSpeechSoundCounter <= 0) { // Paused  					playSounds(); -					_gamePaused = _gamePaused2 = 0; +					_gamePaused = _gamePaused2 = false;  					break;  				}  				_lastKeyPressed = getLastKeyCode(); @@ -529,7 +535,7 @@ void TuckerEngine::mainLoop() {  			}  		}  		if (_lastKeyPressed == Common::KEYCODE_p && _locationNum == 70) { -			_gamePaused = 1; +			_gamePaused = true;  		}  		if (_lastKeyPressed == Common::KEYCODE_F3 && _displayGameHints != 0 && _gameHintsDisplayText == 1) {  			_mouseButton2 = _gameHintsIndex + 1; @@ -540,13 +546,10 @@ void TuckerEngine::mainLoop() {  		}  		if (_flagsTable[236] > 70) {  			handleCreditsSequence(); -			_quitGame = 1; +			_quitGame = true;  		} -		if ((_lastKeyPressed == Common::KEYCODE_F4 && _data4FlagDebug != 0) || _quitGame == 1 || _flagsTable[100] != 0) { -			break; -		} -	} -	if (_flagsTable[100] != 1) { +	} while (!_quitGame && _flagsTable[100] == 0); +	if (_flagsTable[100] == 1) {  		handleCongratulationsSequence();  	}  	closeCompressedSoundFile(); @@ -602,9 +605,7 @@ void TuckerEngine::parseEvents() {  			break;  		}  	} -	if (shouldQuit()) { -		_flagsTable[100] = 1; -	} +	_quitGame = shouldQuit();  }  void TuckerEngine::updateCursorPos(int x, int y) { @@ -810,25 +811,26 @@ void TuckerEngine::updateCharPosition() {  	}  	int actionKey = _currentActionObj2Num * 1000000 + _currentInfoString2SourceType * 100000 + _updateCharPositionNewType * 10000 + _currentInfoString1SourceType * 1000 + _currentActionObj1Num;  	int skip = 0; -	int i; -	for (i = 0; i < _actionsCount && skip == 0; ) { -		if (_actionsTable[i].key == actionKey) { +	Action *action = 0; +	for (int i = 0; i < _actionsCount && skip == 0; ) { +		action = &_actionsTable[i]; +		if (action->key == actionKey) {  			skip = 1; -			if (_actionsTable[i].testFlag1Num != 0) { -				if (_actionsTable[i].testFlag1Num < 500) { -					if (_flagsTable[_actionsTable[i].testFlag1Num] != _actionsTable[i].testFlag1Value) { +			if (action->testFlag1Num != 0) { +				if (action->testFlag1Num < 500) { +					if (_flagsTable[action->testFlag1Num] != action->testFlag1Value) {  						skip = 0;  					} -				} else if (_inventoryItemsState[_actionsTable[i].testFlag1Num - 500] != _actionsTable[i].testFlag1Value) { +				} else if (_inventoryItemsState[action->testFlag1Num - 500] != action->testFlag1Value) {  					skip = 0;  				}  			} -			if (_actionsTable[i].testFlag2Num != 0) { -				if (_actionsTable[i].testFlag2Num < 500) { -					if (_flagsTable[_actionsTable[i].testFlag2Num] != _actionsTable[i].testFlag2Value) { +			if (action->testFlag2Num != 0) { +				if (action->testFlag2Num < 500) { +					if (_flagsTable[action->testFlag2Num] != action->testFlag2Value) {  						skip = 0;  					} -				} else if (_inventoryItemsState[_actionsTable[i].testFlag2Num - 500] != _actionsTable[i].testFlag2Value) { +				} else if (_inventoryItemsState[action->testFlag2Num - 500] != action->testFlag2Value) {  					skip = 0;  				}  			} @@ -842,25 +844,26 @@ void TuckerEngine::updateCharPosition() {  		_updateCharPositionNewType = 0;  		return;  	} -	if (_actionsTable[i].speech != 6) { -		if (_actionsTable[i].speech < 100) { -			_spriteAnimationFrameIndex = _spriteAnimationsTable[_actionsTable[i].speech].firstFrameIndex; -			_currentSpriteAnimationLength = _spriteAnimationsTable[_actionsTable[i].speech].numParts; -			_mirroredDrawing = _actionsTable[i].flipX; +	assert(action); +	if (action->speech != 6) { +		if (action->speech < 100) { +			_spriteAnimationFrameIndex = _spriteAnimationsTable[action->speech].firstFrameIndex; +			_currentSpriteAnimationLength = _spriteAnimationsTable[action->speech].numParts; +			_mirroredDrawing = action->flipX;  			_characterFacingDirection = 5;  			_mainLoopCounter2 = 0;  		} else { -			_backgroundSpriteCurrentAnimation = _actionsTable[i].speech - 100; +			_backgroundSpriteCurrentAnimation = action->speech - 100;  			_backgroundSpriteCurrentFrame = 0;  			_mirroredDrawing = 0;  		}  	} -	_pendingActionDelay = _actionsTable[i].delay; -	_charPositionFlagNum = _actionsTable[i].setFlagNum; -	_charPositionFlagValue = _actionsTable[i].setFlagValue; -	_pendingActionIndex = _actionsTable[i].index; -	_characterSoundFxDelayCounter = _actionsTable[i].fxDelay; -	_characterSoundFxNum = _actionsTable[i].fxNum; +	_pendingActionDelay = action->delay; +	_charPositionFlagNum = action->setFlagNum; +	_charPositionFlagValue = action->setFlagValue; +	_pendingActionIndex = action->index; +	_characterSoundFxDelayCounter = action->fxDelay; +	_characterSoundFxNum = action->fxNum;  	_updateCharPositionType = _updateCharPositionNewType;  	_updateCharPositionNewType = 0;  } @@ -1182,12 +1185,13 @@ void TuckerEngine::setSoundVolumeDistance() {  void TuckerEngine::updateData3DrawFlag() {  	for (int i = 0; i < _locationAnimationsCount; ++i) { -		if (_locationAnimationsTable[i].flagNum > 0 && _locationAnimationsTable[i].flagValue != _flagsTable[_locationAnimationsTable[i].flagNum]) { -			_locationAnimationsTable[i].drawFlag = 0; -		} else if (_locationAnimationsTable[i].getFlag == 0) { -			_locationAnimationsTable[i].drawFlag = 1; +		LocationAnimation *a = &_locationAnimationsTable[i]; +		if (a->flagNum > 0 && a->flagValue != _flagsTable[a->flagNum]) { +			a->drawFlag = 0; +		} else if (a->getFlag == 0) { +			a->drawFlag = 1;  		} else { -			_locationAnimationsTable[i].drawFlag = (_inventoryItemsState[_locationAnimationsTable[i].inventoryNum] == 0) ? 1 : 0; +			a->drawFlag = (_inventoryItemsState[a->inventoryNum] == 0) ? 1 : 0;  		}  	}  } @@ -1195,19 +1199,20 @@ void TuckerEngine::updateData3DrawFlag() {  void TuckerEngine::updateData3() {  	updateData3DrawFlag();  	for (int i = 0; i < _locationAnimationsCount; ++i) { -		if (_locationAnimationsTable[i].animLastCounter != 0 && _locationAnimationsTable[i].drawFlag != 0) { -			if (_locationAnimationsTable[i].animLastCounter == _locationAnimationsTable[i].animCurrentCounter) { -				_locationAnimationsTable[i].animCurrentCounter = _locationAnimationsTable[i].animInitCounter; +		LocationAnimation *a = &_locationAnimationsTable[i]; +		if (a->animLastCounter != 0 && a->drawFlag != 0) { +			if (a->animLastCounter == a->animCurrentCounter) { +				a->animCurrentCounter = a->animInitCounter;  			} else { -				++_locationAnimationsTable[i].animCurrentCounter; +				++a->animCurrentCounter;  			} -			const int index = _locationAnimationsTable[i].animCurrentCounter; +			const int index = a->animCurrentCounter;  			if (_staticData3Table[index] == 998) {  				_flagsTable[_staticData3Table[index + 1]] = _staticData3Table[index + 2]; -				_locationAnimationsTable[i].animCurrentCounter = _locationAnimationsTable[i].animInitCounter; -				_locationAnimationsTable[i].drawFlag = 0; +				a->animCurrentCounter = a->animInitCounter; +				a->drawFlag = 0;  			} -			_locationAnimationsTable[i].graphicNum = _staticData3Table[_locationAnimationsTable[i].animCurrentCounter]; +			a->graphicNum = _staticData3Table[a->animCurrentCounter];  		}  	}  	updateData3DrawFlag(); @@ -1215,16 +1220,17 @@ void TuckerEngine::updateData3() {  void TuckerEngine::updateSfxData3_1() {  	for (int i = 0; i < _locationSoundsCount; ++i) { -		if ((_locationSoundsTable[i].type == 6 || _locationSoundsTable[i].type == 7) && _locationSoundsTable[i].updateType == 1) { +		LocationSound *s = &_locationSoundsTable[i]; +		if ((s->type == 6 || s->type == 7) && s->updateType == 1) {  			for (int j = 0; j < _spritesCount; ++j) { -				if (_spritesTable[j].animationFrame == _locationSoundsTable[i].startFxSpriteNum && _spritesTable[j].state == _locationSoundsTable[i].startFxSpriteState) { -					if (_locationSoundsTable[i].type == 7) { -						_flagsTable[_locationSoundsTable[i].flagNum] = _locationSoundsTable[i].flagValueStartFx; +				if (_spritesTable[j].animationFrame == s->startFxSpriteNum && _spritesTable[j].state == s->startFxSpriteState) { +					if (s->type == 7) { +						_flagsTable[s->flagNum] = s->flagValueStartFx;  					} -					startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume); -				} else if (_locationSoundsTable[i].type == 7) { -					if (_spritesTable[j].animationFrame == _locationSoundsTable[i].stopFxSpriteNum && _spritesTable[j].state == _locationSoundsTable[i].stopFxSpriteState) { -						_flagsTable[_locationSoundsTable[i].flagNum] = _locationSoundsTable[i].flagValueStopFx; +					startSound(s->offset, i, s->volume); +				} else if (s->type == 7) { +					if (_spritesTable[j].animationFrame == s->stopFxSpriteNum && _spritesTable[j].state == s->stopFxSpriteState) { +						_flagsTable[s->flagNum] = s->flagValueStopFx;  						stopSound(i);  					}  				} @@ -1235,15 +1241,16 @@ void TuckerEngine::updateSfxData3_1() {  void TuckerEngine::updateSfxData3_2() {  	for (int i = 0; i < _locationSoundsCount; ++i) { -		if ((_locationSoundsTable[i].type == 6 || _locationSoundsTable[i].type == 7) && _locationSoundsTable[i].updateType == 0) { -			if (_locationSoundsTable[i].startFxSpriteNum == _backgroundSpriteCurrentFrame && _locationSoundsTable[i].startFxSpriteState == _backgroundSpriteCurrentAnimation) { -				if (_locationSoundsTable[i].type == 7) { -					_flagsTable[_locationSoundsTable[i].flagNum] = _locationSoundsTable[i].flagValueStartFx; +		LocationSound *s = &_locationSoundsTable[i]; +		if ((s->type == 6 || s->type == 7) && s->updateType == 0) { +			if (s->startFxSpriteNum == _backgroundSpriteCurrentFrame && s->startFxSpriteState == _backgroundSpriteCurrentAnimation) { +				if (s->type == 7) { +					_flagsTable[s->flagNum] = s->flagValueStartFx;  				} -				startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume); -			} else if (_locationSoundsTable[i].type == 7) { -				if (_locationSoundsTable[i].stopFxSpriteNum == _backgroundSpriteCurrentFrame && _locationSoundsTable[i].stopFxSpriteState == _backgroundSpriteCurrentAnimation) { -					_flagsTable[_locationSoundsTable[i].flagNum] = _locationSoundsTable[i].flagValueStopFx; +				startSound(s->offset, i, s->volume); +			} else if (s->type == 7) { +				if (s->stopFxSpriteNum == _backgroundSpriteCurrentFrame && s->stopFxSpriteState == _backgroundSpriteCurrentAnimation) { +					_flagsTable[s->flagNum] = s->flagValueStopFx;  					stopSound(i);  				}  			} @@ -1335,7 +1342,7 @@ void TuckerEngine::handleMouseOnPanel() {  			_panelState = 0;  			setCursorType(0);  		} else { -			_quitGame = 1; +			_quitGame = true;  		}  	}  } @@ -1811,32 +1818,35 @@ void TuckerEngine::redrawPanelItemsHelper() {  }  void TuckerEngine::drawSprite(int num) { -	if (_spritesTable[num].animationFrame <= _spritesTable[num].firstFrame && _spritesTable[num].animationFrame > 0) { -		if (_spritesTable[num].state != -1) { -			const uint8 *p = _spritesTable[num].animationData; -			if (!p) { -				return; -			} -			int frameOffset = READ_LE_UINT24(p + _spritesTable[num].animationFrame * 4); -			int srcW = READ_LE_UINT16(p + frameOffset); -			int srcH = READ_LE_UINT16(p + frameOffset + 2); -			int srcX = READ_LE_UINT16(p + frameOffset + 8); -			int srcY = READ_LE_UINT16(p + frameOffset + 10); -			int dstOffset = _spritesTable[num].gfxBackgroundOffset + srcX; -			if (dstOffset < 600 && (_scrollOffset + 320 < dstOffset || _scrollOffset - srcW > dstOffset)) { -				return; -			} -			_spritesTable[num].xSource = srcX; -			_spritesTable[num].gfxBackgroundOffset += _spritesTable[num].backgroundOffset; -			uint8 *dstPtr = _locationBackgroundGfxBuf + srcY * 640 + dstOffset; -			const uint8 *srcPtr = p + frameOffset + 12; -			if (_spritesTable[num].colorType == 0) { -				Graphics::decodeRLE(dstPtr, srcPtr, srcW, srcH); -			} else if (_spritesTable[num].colorType == 99) { -				Graphics::decodeRLE_224(dstPtr, srcPtr, srcW, srcH); -			} else { -				Graphics::decodeRLE_248(dstPtr, srcPtr, srcW, srcH, 0, _spritesTable[num].yMaxBackground, _spritesTable[num].flipX != 0); -			} +	Sprite *s = &_spritesTable[num]; +	if (s->animationFrame <= s->firstFrame && s->animationFrame > 0 && s->state != -1) { +		const uint8 *p = s->animationData; +		if (!p) { +			return; +		} +		int frameOffset = READ_LE_UINT24(p + s->animationFrame * 4); +		int srcW = READ_LE_UINT16(p + frameOffset); +		int srcH = READ_LE_UINT16(p + frameOffset + 2); +		int srcX = READ_LE_UINT16(p + frameOffset + 8); +		int srcY = READ_LE_UINT16(p + frameOffset + 10); +		int dstOffset = s->gfxBackgroundOffset + srcX; +		if (dstOffset < 600 && (_scrollOffset + 320 < dstOffset || _scrollOffset - srcW > dstOffset)) { +			return; +		} +		s->xSource = srcX; +		s->gfxBackgroundOffset += s->backgroundOffset; +		uint8 *dstPtr = _locationBackgroundGfxBuf + srcY * 640 + dstOffset; +		const uint8 *srcPtr = p + frameOffset + 12; +		switch (s->colorType) { +		case 0: +			Graphics::decodeRLE(dstPtr, srcPtr, srcW, srcH); +			break; +		case 99: +			Graphics::decodeRLE_224(dstPtr, srcPtr, srcW, srcH); +			break; +		default: +			Graphics::decodeRLE_248(dstPtr, srcPtr, srcW, srcH, 0, s->yMaxBackground, s->flipX != 0); +			break;  		}  	}  } @@ -2837,7 +2847,7 @@ void TuckerEngine::updateCharSpeechSound() {  		return;  	}  	static const int constEq0 = 0; // display text for speech -	if (constEq0 == 1 && _gamePaused2 == 0) { +	if (constEq0 == 1 && !_gamePaused2) {  		drawSpeechText(_actionPosX, _actionPosY, _characterSpeechDataPtr, _speechSoundNum, _actionTextColor);  	}  } diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h index 44f9c28185..17726ea570 100644 --- a/engines/tucker/tucker.h +++ b/engines/tucker/tucker.h @@ -32,6 +32,8 @@  #include "common/events.h"  #include "common/stream.h" +#include "graphics/flic_player.h" +  #include "sound/mixer.h"  #include "engines/engine.h" @@ -169,6 +171,8 @@ struct LocationMusic {  };  enum { +	kScreenWidth = 320, +	kScreenHeight = 200,  	kFadePaletteStep = 5,  	kStartupLocation = 1,  	kDefaultCharSpeechSoundCounter = 1, @@ -205,7 +209,7 @@ public:  		kMaxCharacters = 8  	}; -	TuckerEngine(OSystem *system, Common::Language language); +	TuckerEngine(OSystem *system, Common::Language language, bool isDemo);  	~TuckerEngine();  	virtual Common::Error init(); @@ -541,8 +545,9 @@ protected:  	Common::RandomSource _rnd;  	Common::Language _lang; +	bool _isDemo; -	int _quitGame; +	bool _quitGame;  	bool _fastMode;  	int _syncCounter;  	uint32 _lastFrameTime; @@ -555,8 +560,8 @@ protected:  	int _currentPartNum;  	int _locationNum;  	int _nextLocationNum; -	int _gamePaused; -	int _gamePaused2; +	bool _gamePaused; +	bool _gamePaused2;  	int _data4FlagDebug;  	int _displayGameHints;  	int _execData3Counter; @@ -801,6 +806,111 @@ protected:  	static const uint8 _charWidthCharset2[58];  }; +enum { +	kFirstAnimationSequenceGame = 17, +	kFirstAnimationSequenceDemo = 13 +}; + +enum AnimationSoundType { +	kAnimationSoundType8BitsRAW, +	kAnimationSoundType16BitsRAW, +	kAnimationSoundTypeWAV, +	kAnimationSoundTypeLoopingWAV +}; + +class AnimationSequencePlayer { +public: + +	enum { +		kSequenceFrameTime = 55 +	}; + +	AnimationSequencePlayer(OSystem *system, Audio::Mixer *mixer, Common::EventManager *event, int num); +	~AnimationSequencePlayer(); + +	void mainLoop(); + +private: + +	void syncTime(); +	void loadSounds(int type, int num); +	Audio::AudioStream *loadSoundFileAsStream(const char *name, AnimationSoundType type); +	void updateSounds(); +	void fadeInPalette(); +	void fadeOutPalette(); +	void unloadAnimation(); +	uint8 *loadPicture(const char *fileName); +	void openAnimation(int index, const char *fileName); +	void decodeNextAnimationFrame(int index); +	void introSeq17_18(); +	void introSeq19_20(); +	void displayLoadingScreen(); +	void initPicPart4(); +	void drawPicPart4(); +	void introSeq3_4(); +	void drawPic2Part10(); +	void drawPic1Part10(); +	void introSeq9_10(); +	void introSeq21_22(); +	void introSeq13_14(); +	void introSeq15_16(); +	void introSeq27_28(); + +	OSystem *_system; +	Audio::Mixer *_mixer; +	Common::EventManager *_event; + +	bool _newSeq; +	int _seqNum, _currentSeqNum; +	::Graphics::FlicPlayer *_flicPlayer[2]; +	uint8 _animationPalette[256 * 4], _paletteBuffer[256 * 4]; +	const int *_soundsListSeqData; +	const char **_soundsList1; +	int _soundsList1Count; +	const char **_soundsList2; +	int _soundsList2Count; +	int _musicVolume; +	uint8 *_offscreenBuffer; +	int _updateScreenWidth; +	int _updateScreenPicture; +	int _updateScreenOffset; +	int _frameCounter; +	int _frameTime; +	int _lastFrameTime; +	uint8 *_picBufPtr, *_pic2BufPtr; +	Audio::SoundHandle _soundsHandle[15]; +	Audio::SoundHandle _sfxHandle; +	Audio::SoundHandle _musicHandle; + +	static const int _soundSeqData1[1]; +	static const int _soundSeqData2[233]; +	static const int _soundSeqData3[241]; +	static const int _soundSeqData4[193]; +	static const int _soundSeqData5[77]; +	static const int _soundSeqData6[101]; +	static const int _soundSeqData7[173]; +	static const int _soundSeqData8[45]; +	static const int _soundSeqData9[49]; +	static const int _soundSeqData10[97]; +	static const int _soundSeqData11[29]; +	static const char *_musicFileNamesTable[53]; +	static const char *_soundFilesList1[14]; +	static const char *_soundFilesList2[10]; +	static const char *_soundFilesList3[14]; +	static const char *_soundFilesList4[5]; +	static const char *_soundFilesList5[14]; +	static const char *_soundFilesList6[9]; +	static const char *_soundFilesList7[13]; +	static const char *_soundFilesList8[14]; +	static const char *_soundFilesList9[4]; +	static const char *_soundFilesList10[13]; +	static const char *_soundFilesList11[9]; +	static const char *_soundFilesList12[11]; +	static const char *_soundFilesList13[6]; +	static const char *_soundFilesList14[10]; +	static const char *_soundFilesList15[4]; +}; +  } // namespace Tucker  #endif  | 
