aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/tucker/detection.cpp10
-rw-r--r--engines/tucker/graphics.h1
-rw-r--r--engines/tucker/resource.cpp57
-rw-r--r--engines/tucker/sequences.cpp638
-rw-r--r--engines/tucker/staticres.cpp370
-rw-r--r--engines/tucker/tucker.cpp214
-rw-r--r--engines/tucker/tucker.h118
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