aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/plugins.cpp3
-rwxr-xr-xconfigure1
-rw-r--r--engines/engines.mk5
-rw-r--r--engines/tucker/detection.cpp88
-rw-r--r--engines/tucker/graphics.cpp258
-rw-r--r--engines/tucker/graphics.h64
-rw-r--r--engines/tucker/locations.cpp3207
-rw-r--r--engines/tucker/module.mk19
-rw-r--r--engines/tucker/resource.cpp959
-rw-r--r--engines/tucker/saveload.cpp116
-rw-r--r--engines/tucker/sequences.cpp480
-rw-r--r--engines/tucker/staticres.cpp219
-rw-r--r--engines/tucker/tucker.cpp3778
-rw-r--r--engines/tucker/tucker.h802
14 files changed, 9999 insertions, 0 deletions
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 5429359658..cd91bed292 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -147,6 +147,9 @@ public:
#if PLUGIN_ENABLED_STATIC(TOUCHE)
LINK_PLUGIN(TOUCHE)
#endif
+ #if PLUGIN_ENABLED_STATIC(TUCKER)
+ LINK_PLUGIN(TUCKER)
+ #endif
// Music plugins
// TODO: Use defines to disable or enable each MIDI driver as a
diff --git a/configure b/configure
index c54a955deb..8a08e89138 100755
--- a/configure
+++ b/configure
@@ -102,6 +102,7 @@ add_engine sword1 "Broken Sword 1" yes
add_engine sword2 "Broken Sword 2" yes
add_engine tinsel "Tinsel" no
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
+add_engine tucker "Bud Tucker in Double Trouble" no
_endian=unknown
_need_memalign=no
diff --git a/engines/engines.mk b/engines/engines.mk
index 4dba913173..5115ac69aa 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -106,3 +106,8 @@ ifdef ENABLE_TOUCHE
DEFINES += -DENABLE_TOUCHE=$(ENABLE_TOUCHE)
MODULES += engines/touche
endif
+
+ifdef ENABLE_TUCKER
+DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
+MODULES += engines/tucker
+endif
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
new file mode 100644
index 0000000000..931e006fdb
--- /dev/null
+++ b/engines/tucker/detection.cpp
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/advancedDetector.h"
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "base/plugins.h"
+
+#include "tucker/tucker.h"
+
+static const PlainGameDescriptor tuckerGames[] = {
+ { "tucker", "Bud Tucker in Double Trouble" },
+ { 0, 0 }
+};
+
+static const Common::ADGameDescription tuckerGameDescriptions[] = {
+ {
+ "tucker",
+ "",
+ AD_ENTRY1s("infobar.txt", "f1e42a95972643462b9c3c2ea79d6683", 543),
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+ AD_TABLE_END_MARKER
+};
+
+static const Common::ADParams detectionParams = {
+ (const byte *)tuckerGameDescriptions,
+ sizeof(Common::ADGameDescription),
+ 512,
+ tuckerGames,
+ 0,
+ "tucker",
+ 0,
+ 0
+};
+
+class TuckerMetaEngine : public Common::AdvancedMetaEngine {
+public:
+ TuckerMetaEngine() : Common::AdvancedMetaEngine(detectionParams) {
+ }
+
+ virtual const char *getName() const {
+ return "Tucker Engine";
+ }
+
+ virtual const char *getCopyright() const {
+ return "Bud Tucker in Double Trouble (C) Merit Studios";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new Tucker::TuckerEngine(syst, desc->language);
+ }
+ return desc != 0;
+ }
+};
+
+#if PLUGIN_ENABLED_DYNAMIC(TUCKER)
+ REGISTER_PLUGIN_DYNAMIC(TUCKER, PLUGIN_TYPE_ENGINE, TuckerMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(TUCKER, PLUGIN_TYPE_ENGINE, TuckerMetaEngine);
+#endif
diff --git a/engines/tucker/graphics.cpp b/engines/tucker/graphics.cpp
new file mode 100644
index 0000000000..4498f553bb
--- /dev/null
+++ b/engines/tucker/graphics.cpp
@@ -0,0 +1,258 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tucker/graphics.h"
+
+namespace Tucker {
+
+int Graphics::encodeRLE(const uint8 *src, uint8 *dst, int w, int h) {
+ int count = 0;
+ int dstOffset = 0;
+ int code = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ code = src[x];
+ if (code == 0) {
+ ++count;
+ if (count > 200) {
+ dst[dstOffset++] = 0;
+ dst[dstOffset++] = count;
+ count = 0;
+ }
+ } else {
+ if (count > 0) {
+ dst[dstOffset++] = 0;
+ dst[dstOffset++] = count;
+ count = 0;
+ }
+ dst[dstOffset++] = code;
+ }
+ }
+ src += 320;
+ }
+ if (count > 0) {
+ dst[dstOffset++] = 0;
+ dst[dstOffset++] = count;
+ }
+ return dstOffset;
+}
+
+int Graphics::encodeRAW(const uint8 *src, uint8 *dst, int w, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(dst, src, w);
+ dst += w;
+ src += 320;
+ }
+ return w * h;
+}
+
+void Graphics::decodeRLE(uint8 *dst, const uint8 *src, int w, int h) {
+ int code = 0;
+ int offset = 0;
+ int color = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ if (code == 0) {
+ color = src[offset++];
+ if (color == 0) {
+ code = src[offset++];
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ } else {
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ if (color != 0) {
+ dst[x] = color;
+ }
+ }
+ dst += 640;
+ }
+}
+
+void Graphics::decodeRLE_224(uint8 *dst, const uint8 *src, int w, int h) {
+ int code = 0;
+ int offset = 0;
+ int color = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ if (code == 0) {
+ color = src[offset++];
+ if (color != 0) {
+ if (dst[x] < 0xE0) {
+ dst[x] = color;
+ }
+ } else {
+ code = src[offset++];
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ } else {
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ }
+ dst += 640;
+ }
+}
+
+void Graphics::decodeRLE_248(uint8 *dst, const uint8 *src, int w, int h, int y1, int y2, bool xflip) {
+ int code = 0;
+ int offset = 0;
+ int color = 0;
+ int dstOffset = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ dstOffset = xflip ? (w - 1 - x) : x;
+ if (code == 0) {
+ color = src[offset++];
+ if (color == 0) {
+ code = src[offset++];
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ } else {
+ --code;
+ if (x + code < w) {
+ x += code;
+ code = 0;
+ } else {
+ code -= w - 1 - x;
+ x = w - 1;
+ }
+ }
+ if (color != 0) {
+ if ((dst[dstOffset] < 0xE0 || y + y1 < y2) && dst[dstOffset] < 0xF8) {
+ dst[dstOffset] = color;
+ }
+ }
+ }
+ dst += 640;
+ }
+}
+
+void Graphics::decodeRLE_320(uint8 *dst, const uint8 *src, int w, int h) {
+ int code = 0;
+ int offset = 0;
+ int color = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ if (code == 0) {
+ color = src[offset++];
+ if (color == 0) {
+ code = src[offset++];
+ }
+ }
+ if (code == 0) {
+ dst[x] = color;
+ } else {
+ --code;
+ }
+ }
+ dst += 320;
+ }
+}
+
+void Graphics::copyFrom640(const uint8 *src, uint8 *dst, int w, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(dst, src, w);
+ dst += w;
+ src += 640;
+ }
+}
+
+void Graphics::copyTo640(uint8 *dst, const uint8 *src, int w, int srcPitch, int h) {
+ for (int y = 0; y < h; ++y) {
+ memcpy(dst, src, w);
+ dst += 640;
+ src += srcPitch;
+ }
+}
+
+void Graphics::drawStringChar(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src) {
+ if (chr < 32 || chr - 32 >= kCharSet1CharsCount) {
+ return;
+ }
+ int offset = (chr - 32) * kCharSet1CharSize;
+ for (int y = 0; y < kCharSet1CharH; ++y) {
+ for (int x = 0; x < kCharSet1CharW; ++x) {
+ const int color = src[offset++];
+ if (color != 0) {
+ dst[x] = (color == 128) ? color : chrColor;
+ }
+ }
+ dst += pitch;
+ }
+}
+
+void Graphics::drawStringChar2(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src) {
+ if (chr < 32 || chr - 32 >= kCharSet2CharsCount) {
+ return;
+ }
+ int offset = (chr - 32) * kCharSet2CharSize;
+ for (int y = 0; y < kCharSet2CharH; ++y) {
+ for (int x = 0; x < kCharSet2CharW; ++x) {
+ const int color = src[offset++];
+ if (color != 0) {
+ dst[x] = color;
+ }
+ }
+ dst += pitch;
+ }
+}
+
+
+} // namespace Tucker
diff --git a/engines/tucker/graphics.h b/engines/tucker/graphics.h
new file mode 100644
index 0000000000..c04ddc8b67
--- /dev/null
+++ b/engines/tucker/graphics.h
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TUCKER_GRAPHICS_H__
+#define TUCKER_GRAPHICS_H__
+
+#include "common/util.h"
+
+namespace Tucker {
+
+enum {
+ kCharSet1CharW = 10,
+ kCharSet1CharH = 10,
+ kCharSet1CharSize = kCharSet1CharW * kCharSet1CharH,
+ kCharSet1CharsCount = 32 * 7,
+ kCharSet2CharW = 19,
+ kCharSet2CharH = 10,
+ kCharSet2CharSize = kCharSet2CharW * kCharSet2CharH,
+ kCharSet2CharsCount = 16 * 6
+};
+
+class Graphics {
+public:
+
+ static int encodeRLE(const uint8 *src, uint8 *dst, int w, int h);
+ static int encodeRAW(const uint8 *src, uint8 *dst, int w, int h);
+
+ static void decodeRLE(uint8 *dst, const uint8 *src, int w, int h);
+ static void decodeRLE_224(uint8 *dst, const uint8 *src, int w, int h);
+ static void decodeRLE_248(uint8 *dst, const uint8 *src, int w, int h, int y1, int y2, bool xflip);
+ static void decodeRLE_320(uint8 *dst, const uint8 *src, int w, int h);
+
+ static void copyFrom640(const uint8 *src, uint8 *dst, int w, int h);
+ 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);
+};
+
+} // namespace Tucker
+
+#endif
diff --git a/engines/tucker/locations.cpp b/engines/tucker/locations.cpp
new file mode 100644
index 0000000000..92d4f68038
--- /dev/null
+++ b/engines/tucker/locations.cpp
@@ -0,0 +1,3207 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tucker/tucker.h"
+#include "tucker/graphics.h"
+
+namespace Tucker {
+
+static const int _data3UpdateLocation1_xTable[] = { 287, 120, 61 };
+static const int _data3UpdateLocation1_yTable[] = { 152, 8, 95 };
+
+void TuckerEngine::execData3PreUpdate_locationNum1() {
+ if (_flagsTable[1] == 1) {
+ _flagsTable[1] = 2;
+ _locationSoundsTable[3].type = 2;
+ startSound(_locationSoundsTable[3].offset, 3, _locationSoundsTable[3].volume);
+ }
+ _mapSequenceFlagsLocationTable[0] = (_flagsTable[1] > 0) ? 1 : 0;
+ if (_updateLocationCounter == 0) {
+ execData3PreUpdate_locationNum1Helper1();
+ execData3PreUpdate_locationNum1Helper2();
+ } else {
+ --_updateLocationCounter;
+ if (_updateLocationCounter == 0) {
+ ++_updateLocationPos;
+ if (_updateLocationPos > 1) {
+ _updateLocationPos = 0;
+ }
+ for (int i = 0; i < 5; ++i) {
+ _updateLocationXPosTable[i] = _data3UpdateLocation1_xTable[_updateLocationPos];
+ _updateLocationYPosTable[i] = _data3UpdateLocation1_yTable[_updateLocationPos];
+ _updateLocationFlagsTable[i] = 0;
+ }
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum1Helper1() {
+ int code = 0;
+ if (_updateLocationXPosTable[0] > 0 && _updateLocationYPosTable[0] > 0) {
+ for (int i = 4; i > 0; --i) {
+ _updateLocationXPosTable[i] = _updateLocationXPosTable[i - 1];
+ _updateLocationYPosTable[i] = _updateLocationYPosTable[i - 1];
+ _updateLocationFlagsTable[i] = _updateLocationFlagsTable[i - 1];
+ }
+ }
+ if (_updateLocationFlagsTable[0] == 1 && _updateLocationCounter == 0) {
+ setVolumeSound(12, _locationSoundsTable[12].volume);
+ } else {
+ setVolumeSound(12, 0);
+ }
+ static const int dxTable[] = { 0, -1, -1, -1, 0, 1, 1, 1 };
+ static const int dyTable[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
+ for (int i = 0; code == 0 && i < 8; ++i) {
+ code = execData3PreUpdate_locationNum1Helper3(dxTable[i], dyTable[i]);
+ }
+ _updateLocationFlagsTable[0] = code;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum1Helper2() {
+ static const int dxTable[] = { -95, 84, 110 };
+ static const int dyTable[] = { -50, 46, 0 };
+ int xPos = 0;
+ int yPos = 0;
+ for (int i = 0; i < 6; i += 2) {
+ if (_updateLocationFlagsTable[i] == 1) {
+ xPos = _updateLocationXPosTable[i] + dxTable[_updateLocationPos];
+ yPos = _updateLocationYPosTable[i] + dyTable[_updateLocationPos];
+ }
+ if (xPos > 319 || yPos > 199 || xPos < 0 || yPos < 0) {
+ xPos = 0;
+ yPos = 0;
+ }
+ _locationBackgroundGfxBuf[yPos * 640 + xPos] = 100;
+ }
+}
+
+int TuckerEngine::execData3PreUpdate_locationNum1Helper3(int dx, int dy) {
+ static const int counterTable[3] = { 30, 50, 70 };
+ const int xPos = _updateLocationXPosTable[0] + dx;
+ const int yPos = _updateLocationYPosTable[0] + dy;
+ static const int num[] = { 2, 3, 4, 1 };
+ for (int i = 0; i < 4; ++i) {
+ if (xPos == _updateLocationXPosTable[num[i]] && yPos == _updateLocationYPosTable[num[i]]) {
+ return 0;
+ }
+ }
+ const int code = (int8)_loadLocBufPtr[yPos * 320 + xPos];
+ if (code > 0) {
+ _updateLocationXPosTable[0] = xPos;
+ _updateLocationYPosTable[0] = yPos;
+ if (xPos == _data3UpdateLocation1_xTable[_updateLocationPos] && yPos == _data3UpdateLocation1_yTable[_updateLocationPos]) {
+ _updateLocationCounter = counterTable[_updateLocationPos];
+ }
+ }
+ return code;
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum1() {
+ if (_flagsTable[63] == 0) {
+ if (getRandomNumber() < 400) {
+ _flagsTable[63] = 1;
+ startSound(_locationSoundsTable[2].offset, 2, _locationSoundsTable[2].volume);
+ }
+ }
+ _locationHeightTable[1] = (_yPosCurrent > 104) ? 60 : 0;
+}
+
+void TuckerEngine::updateSprite_locationNum2() {
+ if (_flagsTable[9] == 2) {
+ _spritesTable[0].state = -1;
+ return;
+ }
+ if (_flagsTable[9] == 1) {
+ if (_flagsTable[10] == 1) {
+ _spritesTable[0].state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].state = 4;
+ _spritesTable[0].needUpdate = 1;
+ } else {
+ _spritesTable[0].needUpdate = 0;
+ _spritesTable[0].state = 5;
+ _flagsTable[10] = 1;
+ _spritesTable[0].gfxBackgroundOffset = 0;
+ }
+ return;
+ }
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].state = 3;
+ _spritesTable[0].needUpdate = 1;
+ return;
+ }
+ if (_csDataHandled != 0) {
+ _spritesTable[0].needUpdate = 0;
+ if (_flagsTable[199] == 0) {
+ _flagsTable[199] = 1;
+ setCharacterAnimation(0, 0);
+ } else if (getRandomNumber() > 20000) {
+ _spritesTable[0].state = 6;
+ } else {
+ _spritesTable[0].state = 3;
+ _spritesTable[0].updateDelay = 5;
+ }
+ } else {
+ if (_flagsTable[199] == 0) {
+ _flagsTable[199] = 1;
+ setCharacterAnimation(1, 0);
+ } else if (getRandomNumber() < 20000) {
+ _spritesTable[0].state = 1;
+ _spritesTable[0].updateDelay = 5;
+ } else {
+ _spritesTable[0].state = 1;
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum2() {
+ static const int xPosTable[] = { 110, 117, 127, 146, 160, 183, 195, 210 };
+ static const int yPosTable[] = { 50, 60, 60, 60, 50, 55, 50, 50 };
+ static const int yMaxTable[] = { 100, 97, 94, 91, 89, 86, 83, 80 };
+ if (_execData3Counter == 0) {
+ _execData3Counter = 1;
+ for (int i = 0; i < 3; ++i) {
+ _updateLocationYPosTable2[i] = 0;
+ }
+ if (_flagsTable[10] == 0) {
+ strcpy(_fileToLoad, "path02b.pcx");
+ copyLocBitmap(0, 1);
+ }
+ for (int i = 0; i < 3; ++i) {
+ if (_updateLocationYPosTable2[i] > 0) {
+ for (int j = 0; j < 2; ++j) {
+ const int offset = (_updateLocationYPosTable2[i] + j) * 640 + _updateLocationXPosTable2[i];
+ _locationBackgroundGfxBuf[offset] = 142 + j * 2;
+ }
+ _updateLocationYPosTable2[i] += 2;
+ if (_updateLocationYPosTable2[i] > _updateLocationYMaxTable[i]) {
+ _updateLocationYPosTable2[i] = 0;
+ const int num = (getRandomNumber() < 16000) ? 2 : 3;
+ startSound(_locationSoundsTable[num].offset, num, _locationSoundsTable[num].volume);
+ }
+ } else if (getRandomNumber() > 32000) {
+ const int num = getRandomNumber() / 8192;
+ _updateLocationXPosTable2[i] = xPosTable[num];
+ _updateLocationYPosTable2[i] = yPosTable[num];
+ _updateLocationYMaxTable[i] = yMaxTable[num];
+ }
+ }
+ }
+ execData3PreUpdate_locationNum2Helper();
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum2Helper() {
+ if (_fadePaletteCounter != 16) {
+ return;
+ }
+ int start, end;
+ if (_locationNum == 2) {
+ start = 116;
+ end = 125;
+ } else {
+ start = 215;
+ end = 223;
+ }
+ ++_updateLocationFadePaletteCounter;
+ if (_updateLocationFadePaletteCounter > 10 || _updateLocationFadePaletteCounter < 0) {
+ _updateLocationFadePaletteCounter = 0;
+ }
+ int step;
+ if (_updateLocationFadePaletteCounter < 6) {
+ step = _updateLocationFadePaletteCounter;
+ } else {
+ step = 10 - _updateLocationFadePaletteCounter;
+ }
+ for (int i = start; i < end; ++i) {
+ fadePaletteColor(i, step);
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum3_0(int i) {
+ int num;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ num = 5;
+ _spritesTable[i].needUpdate = 1;
+ } else if (_spritesTable[i].prevState == 5 && _spritesTable[i].animationFrame == 1) {
+ _spritesTable[i].needUpdate = 0;
+ int r = getRandomNumber();
+ if (r < 12000) {
+ num = 3;
+ } else if (r < 24000) {
+ num = 1;
+ } else {
+ num = 2;
+ }
+ } else {
+ num = 5;
+ _spritesTable[i].animationFrame = 1;
+ _spritesTable[i].updateDelay = 10;
+ }
+ _spritesTable[i].state = num;
+ _spritesTable[i].prevAnimationFrame = 1;
+}
+
+void TuckerEngine::updateSprite_locationNum3_1(int i) {
+ int num;
+ if (_flagsTable[207] == 1) {
+ num = -1;
+ } else if (_flagsTable[203] == 1) {
+ _spritesTable[i].needUpdate = 1;
+ num = 20;
+ _flagsTable[203] = 2;
+ } else if (_flagsTable[203] == 2) {
+ num = 12;
+ } else if (_flagsTable[203] == 3) {
+ _spritesTable[i].needUpdate = 0;
+ num = 19;
+ _flagsTable[203] = 0;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ if (_flagsTable[21] == 0) {
+ num = 7;
+ } else {
+ num = 8;
+ }
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_csDataHandled != 0) {
+ num = 6;
+ if (getRandomNumber() < 32000) {
+ _spritesTable[i].updateDelay = 5;
+ }
+ } else if (_spritesTable[i].state == 6 && _spritesTable[i].animationFrame == 1) {
+ if (getRandomNumber() < 20000) {
+ num = 11;
+ _spritesTable[i].defaultUpdateDelay = 5;
+ } else {
+ num = 10;
+ }
+ } else {
+ num = 6;
+ _spritesTable[i].animationFrame = 1;
+ _spritesTable[i].updateDelay = 10;
+ }
+ }
+ _spritesTable[i].state = num;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum3_2(int i) {
+ int num;
+ if (_flagsTable[205] == 1) {
+ _flagsTable[205] = 0;
+ num = 18;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ num = 17;
+ } else if (_flagsTable[45] == 1) {
+ _flagsTable[45] = 2;
+ num = 16;
+ } else if (_flagsTable[45] == 2) {
+ num = 17;
+ _spritesTable[i].updateDelay = 5;
+ _spritesTable[i].needUpdate = 0;
+ } else if (_flagsTable[45] == 3) {
+ _flagsTable[45] = 0;
+ num = 16;
+ _updateSpriteFlag2 = 1;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ ++_spritesTable[i].counter;
+ if (_spritesTable[i].counter <= 5) {
+ num = 14;
+ } else {
+ if (_spritesTable[i].counter > 8) {
+ _spritesTable[i].counter = 0;
+ }
+ num = 15;
+ }
+ }
+ _spritesTable[i].state = num;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum3() {
+ execData3PreUpdate_locationNum2Helper();
+ if (_flagsTable[7] == 0) {
+ _flagsTable[7] = 1;
+ }
+ if (_flagsTable[20] == 1 && _inventoryItemsState[7] == 1) {
+ _flagsTable[20] = 2;
+ }
+ if (_inventoryItemsState[19] == 1 && _flagsTable[54] == 1) {
+ _flagsTable[43] = 1;
+ } else {
+ _flagsTable[43] = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum4(int i) {
+ int flag = -1;
+ if (_flagsTable[9] == 2) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ flag = 1;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ flag = 2;
+ _spritesTable[i].needUpdate = 0;
+ }
+ }
+ _spritesTable[i].state = -1;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum4() {
+ if (_flagsTable[6] == 0) {
+ setVolumeSound(0, 0);
+ } else {
+ setVolumeSound(0, _locationSoundsTable[0].volume);
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum5_0() {
+ ++_spritesTable[0].counter;
+ if (_spritesTable[0].counter > 100) {
+ _spritesTable[0].counter = 0;
+ _spritesTable[0].state = 1;
+ _locationSoundsTable[1].type = 2;
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ } else if (_spritesTable[0].counter == 50) {
+ _locationSoundsTable[1].type = 2;
+ _spritesTable[0].state = 2;
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ } else {
+ _spritesTable[0].state = -1;
+ if (isSoundPlaying(1)) {
+ stopSound(1);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum5_1(int i) {
+ _spritesTable[i].state = 3;
+}
+
+void TuckerEngine::updateSprite_locationNum6_0(int i) {
+ int state;
+ if (_flagsTable[184] == 1) {
+ state = -1;
+ } else if (_flagsTable[26] > 0 && _flagsTable[26] < 4 && _flagsTable[27] > 0) {
+ state = 14;
+ } else if (_flagsTable[26] == 4 || _flagsTable[26] == 5) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ state = 3;
+ _spritesTable[0].counter = 0;
+ } else if (_xPosCurrent < 370 && _flagsTable[26] == 4) {
+ state = 2;
+ } else if (_spritesTable[0].counter == 0) {
+ setCharacterAnimation(0, 0);
+ _updateSpriteFlag1 = 1;
+ ++_spritesTable[0].counter;
+ return;
+ } else {
+ state = 1;
+ _spritesTable[0].updateDelay = 2;
+ ++_spritesTable[0].counter;
+ if (_spritesTable[0].counter > 100) {
+ _spritesTable[0].counter = 0;
+ }
+ }
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum6_1(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ if (_flagsTable[209] == 1) {
+ state = 9;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ _spritesTable[i].needUpdate = 1;
+ state = 10;
+ }
+ } else {
+ if (getRandomNumber() < 30000 || (_csDataHandled && _xPosCurrent == 248)) {
+ _spritesTable[i].needUpdate = 0;
+ state = 7;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 7;
+ _soundsMapTable[0] = 3;
+ _miscSoundFxDelayCounter[0] = 70;
+// _miscSoundFxDelayCounter[-1] = 4;
+ _miscSoundFxDelayCounter[1] = 25;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum6_2(int i) {
+ int state;
+ if (_flagsTable[26] < 5 || _flagsTable[207] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 12;
+ } else {
+ state = 12;
+ _spritesTable[i].updateDelay = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum6() {
+ if (_flagsTable[26] > 3) {
+ execData3PreUpdate_locationNum6Helper1();
+ }
+ if (_flagsTable[26] == 2) {
+ _currentSpriteAnimationLength = 2;
+ _currentSpriteAnimationFrame = 112;
+ if (_spritesTable[0].xSource < 45) {
+ _currentSpriteAnimationFrame2 = 144;
+ } else if (_spritesTable[0].xSource > 80) {
+ _currentSpriteAnimationFrame2 = 147;
+ } else if (_spritesTable[0].xSource < 60) {
+ _currentSpriteAnimationFrame2 = 145;
+ } else {
+ _currentSpriteAnimationFrame2 = 146;
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum6Helper1() {
+ if (_mainLoopCounter1 < 2) {
+ if (_flagsTable[26] == 1) {
+ if (_flagsTable[27] < 15) {
+ if (_flagsTable[27] == 0) {
+ startSound(_locationSoundsTable[2].offset, 2, _locationSoundsTable[2].volume);
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ }
+ ++_flagsTable[27];
+ setVolumeSound(0, _locationSoundsTable[0].volume - _flagsTable[27] * 5);
+ setVolumeMusic(0, _locationMusicsTable[0].volume - _flagsTable[27] * 5);
+ }
+ } else if (_flagsTable[26] == 3) {
+ if (_flagsTable[27] > 0) {
+ if (_flagsTable[27] == 15) {
+ startSound(_locationSoundsTable[2].offset, 2, _locationSoundsTable[2].volume);
+ }
+ --_flagsTable[27];
+ setVolumeSound(0, _locationSoundsTable[0].volume - _flagsTable[27] * 5);
+ setVolumeMusic(0, _locationMusicsTable[0].volume - _flagsTable[27] * 5);
+ int volume = _flagsTable[27];
+ if (volume < _locationSoundsTable[1].volume) {
+ volume = _locationSoundsTable[1].volume;
+ }
+ setVolumeSound(1, volume);
+ }
+ }
+ }
+ int x1, x2;
+ switch (_flagsTable[27]) {
+ case 0:
+ x1 = 8;
+ x2 = 0;
+ break;
+ case 15:
+ x1 = 1;
+ x2 = 0;
+ break;
+ case 8:
+ x1 = _flagsTable[27];
+ x2 = _flagsTable[27];
+ break;
+ default:
+ x1 = 1;
+ x2 = 15 - _flagsTable[27];
+ break;
+ }
+ for (int i = 0; i < x1; ++i) {
+ execData3PreUpdate_locationNum6Helper2(_locationBackgroundGfxBuf + 13125 + i * 8, _data3GfxBuf + _dataTable[238].sourceOffset);
+ execData3PreUpdate_locationNum6Helper2(_locationBackgroundGfxBuf + 13245 - i * 8, _data3GfxBuf + _dataTable[238].sourceOffset);
+ }
+ for (int i = 0; i < x2; ++i) {
+ execData3PreUpdate_locationNum6Helper2(_locationBackgroundGfxBuf + 13125 + x1 * 8 + i * 2, _data3GfxBuf + _dataTable[238].sourceOffset);
+ execData3PreUpdate_locationNum6Helper2(_locationBackgroundGfxBuf + 13249 - x1 * 8 - i * 2, _data3GfxBuf + _dataTable[238].sourceOffset);
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum6Helper2(uint8 *dst, const uint8 *src) {
+ for (int j = 0; j < 46; ++j) {
+ memcpy(dst + j * 640, src + j * 8, 8);
+ }
+ for (int j = 46; j < 51; ++j) {
+ for (int i = 0; i < 8; ++i) {
+ const int offset = j * 640 + i;
+ uint8 color = dst[offset];
+ if (color < 224) {
+ dst[offset] = src[j * 8 + i];
+ }
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum6Helper3(uint8 *dst, const uint8 *src) {
+ for (int j = 0; j < 51; ++j) {
+ for (int i = 0; i < 4; ++i) {
+ const int offset = j * 640 + i;
+ uint8 color = dst[offset];
+ if (color < 224) {
+ dst[offset] = src[j * 8 + i * 2];
+ }
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum7_0(int i) {
+ int state;
+ ++_spritesTable[i].counter;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 4;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_spritesTable[i].counter > 0) {
+ state = 2;
+ _spritesTable[i].counter = 0;
+ } else {
+ state = 1;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum7_1(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 5;
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum8_0(int i) {
+ _spritesTable[i].state = (_flagsTable[28] < 20) ? -1 : 7;
+}
+
+void TuckerEngine::updateSprite_locationNum8_1(int i) {
+ int state;
+ if (_flagsTable[207] == 1) {
+ state = -1;
+ } else if (_flagsTable[28] == 18) {
+ state = 6;
+ _spritesTable[i].needUpdate = 0;
+ } else if (_flagsTable[29] == 0) {
+ state = 1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 1) {
+ _spritesTable[i].needUpdate = 1;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 3;
+ }
+ if (_flagsTable[28] == 19) {
+ _flagsTable[28] = 20;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum8() {
+ if (_execData3Counter == 0) {
+ _updateLocationYPosTable2[0] = 0;
+ }
+ if (_updateLocationYPosTable2[0] == 0) {
+ ++_execData3Counter;
+ if (_execData3Counter > 30) {
+ _updateLocationYPosTable2[0] = 16;
+ _updateLocationXPosTable2[0] = 264;
+
+ }
+ }
+ if (_updateLocationYPosTable2[0] > 0) {
+ const int offset = _updateLocationYPosTable2[0] * 640 + _updateLocationXPosTable2[0];
+ _locationBackgroundGfxBuf[offset] = 142;
+ _locationBackgroundGfxBuf[offset + 0x27F] = 143;
+ _locationBackgroundGfxBuf[offset + 0x280] = 143;
+ _locationBackgroundGfxBuf[offset + 0x281] = 144;
+ _locationBackgroundGfxBuf[offset + 0x4FF] = 144;
+ _locationBackgroundGfxBuf[offset + 0x500] = 144;
+ _locationBackgroundGfxBuf[offset + 0x501] = 145;
+ _locationBackgroundGfxBuf[offset + 0x77F] = 147;
+ _locationBackgroundGfxBuf[offset + 0x780] = 143;
+ _locationBackgroundGfxBuf[offset + 0x781] = 147;
+ _updateLocationYPosTable2[0] += 2;
+ if (_updateLocationYPosTable2[0] > 120) {
+ _updateLocationYPosTable2[0] = 0;
+ startSound(_locationSoundsTable[2].offset, 2, _locationSoundsTable[2].volume);
+ }
+ }
+ if (_flagsTable[28] > 1 && _flagsTable[28] < 5) {
+ _locationHeightTable[8] = 60;
+ } else {
+ _locationHeightTable[8] = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum9_0(int i) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ _spritesTable[i].state = 3;
+ } else if (_updateLocationCounter2 > 0 || getRandomNumber() > 30000) {
+ _spritesTable[i].state = 1;
+ if (_updateLocationCounter2 == 0) {
+ _updateLocationCounter2 = 6;
+ }
+ } else if (getRandomNumber() > 30000) {
+ _spritesTable[i].state = 2;
+ _spritesTable[i].defaultUpdateDelay = 5;
+ } else {
+ _spritesTable[i].state = 1;
+ _spritesTable[i].animationFrame = 1;
+ _spritesTable[i].updateDelay = 10;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum9_1(int i) {
+ ++_spritesTable[i].counter;
+ if (_spritesTable[i].counter > 10) {
+ _spritesTable[i].counter = 0;
+ _spritesTable[i].state = 5;
+ _spritesTable[i].defaultUpdateDelay = 5;
+ } else {
+ _spritesTable[i].state = 4;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum9_2(int i) {
+ _spritesTable[i].state = 6;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum9() {
+ if (_flagsTable[7] < 2) {
+ _flagsTable[7] = 2;
+ }
+ if (_flagsTable[8] == 0 && _locationMusicsTable[0].volume != 0) {
+ _locationMusicsTable[0].volume = 0;
+ } else {
+ _locationMusicsTable[0].volume = _xPosCurrent / 40;
+ }
+ setVolumeMusic(0, _locationMusicsTable[0].volume);
+ if (!isSoundPlaying(1) && getRandomNumber() > 32000) {
+ int i = getRandomNumber() / 5500 + 3;
+ assert(i >= 0 && i < kLocationSoundsTableSize);
+ startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume);
+ }
+ if (_flagsTable[8] == 2 && _locationMaskType == 0) {
+ _flagsTable[8] = 0;
+ startSound(_locationSoundsTable[7].offset, 7, _locationSoundsTable[7].volume);
+ }
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum9() {
+ if (_spritesTable[1].state == 4) {
+ if (_spritesTable[1].flipX == 1) {
+ --_updateLocationXPosTable2[0];
+ if (_updateLocationXPosTable2[0] < -50) {
+ _spritesTable[1].flipX = 0;
+ _updateLocationXPosTable2[0] = -50;
+ }
+ } else {
+ ++_updateLocationXPosTable2[0];
+ if (_updateLocationXPosTable2[0] > 500) {
+ _spritesTable[1].flipX = 1;
+ _updateLocationXPosTable2[0] = 500;
+ }
+ }
+ }
+ _spritesTable[1].gfxBackgroundOffset = _updateLocationXPosTable2[0] + 8320;
+ for (int i = 1; i < 3; ++i) {
+ _spritesTable[i].colorType = 1;
+ _spritesTable[i].yMaxBackground = 60;
+ drawSprite(i);
+ _spritesTable[i].colorType = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum10() {
+ int state;
+ const int r = getRandomNumber();
+ if (_flagsTable[99] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ if (r < 26000) {
+ state = 1;
+ } else if (r < 29000) {
+ state = 2;
+ } else {
+ state = 3;
+ }
+ } else if (_csDataHandled) {
+ state = 2;
+ _spritesTable[0].updateDelay = 4;
+ } else {
+ _spritesTable[0].needUpdate = 0;
+ if (r > 26000) {
+ state = 5;
+ _spritesTable[0].prevAnimationFrame = 1;
+ } else if (r > 24000) {
+ state = 6;
+ _miscSoundFxDelayCounter[0] = 120;
+ _soundsMapTable[0] = 0;
+ } else {
+ setCharacterAnimation(0, 0);
+ }
+ }
+ _spritesTable[0].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum10() {
+ if (_execData3Counter == 0) {
+ _execData3Counter = 1;
+ ++_flagsTable[68];
+ if (_flagsTable[68] > 2) {
+ _flagsTable[68] = 0;
+ }
+ }
+ if (_flagsTable[47] == 1 && _inventoryItemsState[26] == 1) {
+ _flagsTable[47] = 2;
+ }
+ if (_spritesTable[0].state == 6 && _spritesTable[0].animationFrame == 18 && !isSoundPlaying(0)) {
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ }
+ if (_flagsTable[230] == 1 && getRandomNumber() > 32000) {
+ _flagsTable[230] = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum11_0(int i) {
+ const int r = getRandomNumber();
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ _spritesTable[i].state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (r > 28000) {
+ _spritesTable[i].state = 3;
+ } else if (r > 20000) {
+ _spritesTable[i].state = 4;
+ } else {
+ _spritesTable[i].state = 3;
+ _spritesTable[i].animationFrame = 1;
+ _spritesTable[i].updateDelay = 5;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum11_1(int i) {
+ if (getRandomNumber() > 20000) {
+ _spritesTable[i].state = 5;
+ } else {
+ _spritesTable[i].animationFrame = 14;
+ _updateSpriteFlag1 = 1;
+ _spritesTable[i].state = 5;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum11_2(int i) {
+ if (getRandomNumber() > 20000) {
+ _spritesTable[i].state = 6;
+ } else {
+ _spritesTable[i].animationFrame = 17;
+ _spritesTable[i].state = 6;
+ _updateSpriteFlag1 = 1;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum11_3(int i) {
+ _spritesTable[i].state = 7;
+}
+
+void TuckerEngine::updateSprite_locationNum11_4(int i) {
+ if (getRandomNumber() > 30000 && _flagsTable[55] < 2) {
+ _spritesTable[i].state = 1;
+ startSound(_locationSoundsTable[6].offset, 6, _locationSoundsTable[6].volume);
+ } else {
+ _spritesTable[i].state = -1;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum12_0(int i) {
+ ++_updateLocationCounter2;
+ if (_updateLocationCounter2 > 11) {
+ _updateLocationCounter2 = 0;
+ }
+ int state;
+ if (_flagsTable[207] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_updateLocationCounter2 < 4) {
+ state = 1;
+ } else if (_updateLocationCounter2 < 8) {
+ state = 2;
+ } else {
+ state = 4;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum12_1(int i) {
+ int state;
+ const int r = getRandomNumber();
+ if (r > 22000) {
+ state = 6;
+ } else if (r > 10000) {
+ state = 7;
+ } else {
+ state = 8;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum12() {
+ if (_inventoryItemsState[12] == 1 && _flagsTable[38] == 0) {
+ _flagsTable[38] = 1;
+ }
+ if (_flagsTable[41] == 0) {
+ if (_locationMusicsTable[0].volume != 100) {
+ _locationMusicsTable[0].volume = 100;
+ setVolumeMusic(0, 100);
+ }
+ } else {
+ if (_locationMusicsTable[0].volume != 20) {
+ _locationMusicsTable[0].volume = 20;
+ setVolumeMusic(0, 20);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum13(int i) {
+ int state;
+ if (_csDataHandled) {
+ if (_flagsTable[202] == 0) {
+ _flagsTable[202] = 1;
+ state = 3;
+ _spritesTable[i].stateIndex = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 4;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 5;
+ }
+ } else if (_flagsTable[202] == 1) {
+ _spritesTable[i].needUpdate = 0;
+ _flagsTable[202] = 0;
+ state = 6;
+ } else {
+ setCharacterAnimation(0, 0);
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum13() {
+ if (_flagsTable[69] == 0) {
+ if (getRandomNumber() > 31000) {
+ _flagsTable[69] = 1;
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ } else if (isSoundPlaying(1)) {
+ stopSound(1);
+ }
+ }
+ _flagsTable[8] = 2;
+ if (_spritesTable[0].state == 1) {
+ if (_spritesTable[0].animationFrame > 10 && _spritesTable[0].animationFrame < 20) {
+ if (!isSoundPlaying(0)) {
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ }
+ }
+ }
+ if (isSoundPlaying(0)) {
+ if (_spritesTable[0].animationFrame > 10 && _spritesTable[0].animationFrame < 20) {
+ stopSound(0);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum14(int i) {
+ int state = 2;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = (getRandomNumber() < 12000) ? 1 : 3;
+ } else if (getRandomNumber() < 26000) {
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum14() {
+ if (!isSoundPlaying(0)) {
+ int num = -1;
+ const int i = getRandomNumber();
+ if (i > 32000) {
+ num = 0;
+ } else if (i > 31800) {
+ num = 3;
+ } else if (i > 31600) {
+ num = 4;
+ } else if (i > 31400) {
+ num = 7;
+ }
+ if (num != -1) {
+ startSound(_locationSoundsTable[num].offset, num, _locationSoundsTable[num].volume);
+ }
+ }
+ _locationHeightTable[14] = (_xPosCurrent < 100) ? 0 : 60;
+ if (_updateLocationFadePaletteCounter == 0) {
+ for (int i = 0; i < 10; ++i) {
+ _updateLocation14ObjNum[i] = 0;
+ }
+ }
+ ++_updateLocationFadePaletteCounter;
+ if (_updateLocationFadePaletteCounter > 4) {
+ _updateLocationFadePaletteCounter = 1;
+ }
+ for (int i = 0; i < 10; ++i) {
+ execData3PreUpdate_locationNum14Helper1(i);
+ if (_updateLocationFadePaletteCounter == 1 && _updateLocation14ObjNum[i] > 0) {
+ execData3PreUpdate_locationNum14Helper2(i);
+ }
+ const int num = _updateLocation14ObjNum[i];
+ if (num > 0) {
+ const int w = _dataTable[num].xSize;
+ const int h = _dataTable[num].ySize;
+ const int dstOffset = (_updateLocationYPosTable2[i] / 16 - h / 2) * 640 + (_updateLocationXPosTable2[i] - w / 2);
+ Graphics::decodeRLE_248(_locationBackgroundGfxBuf + dstOffset, _data3GfxBuf + _dataTable[num].sourceOffset, w, h, 0, 0, false);
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum14Helper1(int i) {
+ const int y = 1872; // XXX bug, 187/182 ?
+ if (_updateLocation14ObjNum[i] == 0) {
+ if (getRandomNumber() <= 30000) {
+ return;
+ }
+ _updateLocationXPosTable2[i] = 155;
+ _updateLocationYPosTable2[i] = y;
+ _updateLocation14Step[i] = -55 - getRandomNumber() / 512;
+ _updateLocation14ObjNum[i] = 231;
+ _updateLocation14Delay[i] = 16 + getRandomNumber() / 2048;
+ // XXX bug, missing return ?
+ }
+ _updateLocation14Step[i] = 4;
+ _updateLocationYPosTable2[i] += _updateLocation14Step[i];
+ if (_updateLocationYPosTable2[i] > y) {
+ _updateLocationYPosTable2[i] = y;
+ _updateLocation14Step[i] = (-(getRandomNumber() + 32000) * _updateLocation14Step[i]) / 65536;
+ }
+ --_updateLocationXPosTable2[i];
+ if (_updateLocationXPosTable2[i] == 0) {
+ _updateLocation14ObjNum[i] = 0;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum14Helper2(int i) {
+ --_updateLocation14Delay[i];
+ if (_updateLocation14Delay[i] == 0) {
+ _updateLocation14ObjNum[i] = 236;
+ } else {
+ ++_updateLocation14ObjNum[i];
+ if (_updateLocation14ObjNum[i] > 237) {
+ _updateLocation14ObjNum[i] = 0;
+ } else if (_updateLocation14ObjNum[i] == 235) {
+ _updateLocation14ObjNum[i] = 231;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum15_0(int i) {
+ _spritesTable[i].state = -1;
+}
+
+void TuckerEngine::updateSprite_locationNum15_1(int i) {
+ int state;
+ int r = getRandomNumber();
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 6;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (r < 26000) {
+ state = 5;
+ } else if (r < 29000) {
+ state = 2;
+ _spritesTable[i].prevAnimationFrame = 1;
+ } else {
+ state = 4;
+ _spritesTable[4].counter = 1;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum15_2(int i) {
+ _spritesTable[i].state = 3;
+ if (_spritesTable[4].counter > 0) {
+ ++_spritesTable[4].counter;
+ if (_spritesTable[4].counter > 6) {
+ _spritesTable[4].counter = 0;
+ } else {
+ _spritesTable[i].updateDelay = 2;
+ }
+ } else {
+ _spritesTable[i].updateDelay = 2;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum15() {
+ ++_updateLocationFadePaletteCounter;
+ if (_updateLocationFadePaletteCounter > 500) {
+ if (!isSoundPlaying(1) && getRandomNumber() > 31000) {
+ const int i = getRandomNumber() / 4714;
+ startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume);
+ _updateLocationFadePaletteCounter = 0;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum16_0(int i) {
+ int state;
+ int r = getRandomNumber();
+ if (_flagsTable[210] > 0) {
+ state = -1;
+ } else if (_flagsTable[82] == 1) {
+ state = 2;
+ _flagsTable[82] = 2;
+ } else if (_flagsTable[82] == 2) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ if (_spritesTable[0].needUpdate == 0) {
+ _spritesTable[0].needUpdate = 1;
+ state = 1;
+ } else {
+ state = 1;
+ _spritesTable[0].animationFrame = 2;
+ _updateSpriteFlag1 = 1;
+ }
+ } else if (_csDataHandled) {
+ _spritesTable[0].needUpdate = 0;
+ if (r < 30000) {
+ state = 4;
+ _spritesTable[0].updateDelay = 5;
+ } else if (r < 31000) {
+ state = 4;
+ if (_xPosCurrent < 300) {
+ _miscSoundFxDelayCounter[0] = 2;
+ _soundsMapTable[0] = 9;
+ }
+ } else if (r < 32000) {
+ state = 5;
+ } else {
+ state = 6;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum16_1(int i) {
+ int state;
+ if (_flagsTable[61] == 0) {
+ state = -1;
+ if (isSoundPlaying(0)) {
+ stopSound(0);
+ } else if (isSoundPlaying(1)) {
+ stopSound(1);
+ }
+ } else if (_flagsTable[60] == 0) {
+ state = 10;
+ if (isSoundPlaying(1)) {
+ _locationSoundsTable[1].type = 2;
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ }
+ } else {
+ state = 9;
+ if (isSoundPlaying(0)) {
+ _locationSoundsTable[0].type = 2;
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ }
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum16_2(int i) {
+ int state = -1;
+ if (_flagsTable[78] == 0) {
+ if (_flagsTable[60] == 1 && _flagsTable[61] == 1) {
+ _flagsTable[78] = 1;
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ state = 7;
+ }
+ } else if (_flagsTable[78] == 1) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 8;
+ } else {
+ if (getRandomNumber() > 32000) {
+ state = 7;
+ } else if (getRandomNumber() > 10000) {
+ state = 13;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ state = 13;
+ }
+ _spritesTable[i].needUpdate = 1;
+ }
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum16() {
+ _locationHeightTable[16] = (_xPosCurrent < 320) ? 60 : 0;
+}
+
+void TuckerEngine::updateSprite_locationNum17() {
+ int state;
+ if (_flagsTable[76] > 0) {
+ state = -1;
+ _disableCharactersPath = false;
+ } else if (_flagsTable[82] == 2) {
+ _flagsTable[82] = 3;
+ _disableCharactersPath = true;
+ _spritesTable[0].gfxBackgroundOffset = 100;
+ state = 1;
+ _spritesTable[0].backgroundOffset = -1;
+ } else if (_spritesTable[0].gfxBackgroundOffset < -160) {
+ state = -1;
+ } else {
+ state = 1;
+ _spritesTable[0].yMaxBackground = 0;
+ _spritesTable[0].colorType = 1;
+ }
+ _spritesTable[0].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum18() {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[0].needUpdate = 0;
+ state = 1;
+ const int r = getRandomNumber();
+ if (r > 31000) {
+ state = 3;
+ } else if (r > 30000) {
+ state = 4;
+ }
+ }
+ _spritesTable[0].gfxBackgroundOffset = 0;
+ _spritesTable[0].backgroundOffset = 0;
+ _spritesTable[0].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum19_0(int i) {
+ int state;
+ if (_flagsTable[206] == 1) {
+ state = 7;
+ _spritesTable[i].needUpdate = 0;
+ _flagsTable[206] = 0;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ ++_spritesTable[i].counter;
+ _spritesTable[i].needUpdate = 1;
+ if (_spritesTable[i].counter > 10) {
+ _spritesTable[i].counter = 0;
+ state = 2;
+ } else {
+ state = 1;
+ }
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_spritesTable[i].counter > 10) {
+ _spritesTable[i].counter = 0;
+ }
+ if (_spritesTable[i].counter == 2) {
+ state = 4;
+ _spritesTable[i].prevAnimationFrame = 1;
+ } else if (_spritesTable[i].counter == 5) {
+ state = 5;
+ _spritesTable[i].prevAnimationFrame = 1;
+ } else {
+ state = 5;
+ _spritesTable[i].updateDelay = 6;
+ }
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].prevAnimationFrame = 1;
+}
+
+void TuckerEngine::updateSprite_locationNum19_1(int i) {
+ _spritesTable[i].state = 9;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum19_2(int i) {
+ _spritesTable[i].gfxBackgroundOffset = 320;
+ _spritesTable[i].state = -1;
+}
+
+void TuckerEngine::updateSprite_locationNum19_3(int i) {
+ setCharacterAnimation(0, i);
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum19() {
+ _locationHeightTable[19] = (_locationMaskType == 0) ? 0 : 60;
+}
+
+void TuckerEngine::updateSprite_locationNum21() {
+ int state;
+ if (_flagsTable[58] == 2) {
+ state = 5;
+ _flagsTable[58] = 3;
+ setVolumeSound(2, 0);
+ } else if (_flagsTable[58] == 3) {
+ state = 6;
+ _flagsTable[58] = 4;
+ _locationSoundsTable[0].volume = 60;
+ _locationSoundsTable[5].volume = 60;
+ } else if (_flagsTable[58] == 4) {
+ state = 7;
+ _locationSoundsTable[4].volume = 60;
+ } else if (_flagsTable[59] == 4) {
+ _spritesTable[0].needUpdate = 1;
+ _flagsTable[59] = 2;
+ state = 2;
+ setVolumeSound(2, 0);
+ } else if (_flagsTable[59] == 3) {
+ _flagsTable[59] = 0;
+ state = 4;
+ setVolumeSound(2, _locationSoundsTable[2].volume);
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ state = 3;
+ } else if (_flagsTable[59] == 2) {
+ _spritesTable[0].needUpdate = 0;
+ state = 3;
+ _spritesTable[0].updateDelay = 5;
+ } else if (_flagsTable[15] == 1) {
+ state = 3;
+ _spritesTable[0].updateDelay = 5;
+ } else {
+ _spritesTable[0].needUpdate = 0;
+ state = 1;
+ }
+ _spritesTable[0].state = state;
+ _spritesTable[0].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum22() {
+ if (_flagsTable[207] == 1) {
+ _spritesTable[0].state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ _spritesTable[0].needUpdate = 1;
+ _spritesTable[0].state = 2;
+ } else {
+ _spritesTable[0].needUpdate = 0;
+ _spritesTable[0].state = 1;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum21() {
+ if (_xPosCurrent > 460 && _flagsTable[58] == 0 && _nextAction == 0) {
+ _updateCharPositionNewType = 0;
+ _pendingActionDelay = 0;
+ _flagsTable[59] = 1;
+ _nextAction = 2;
+ _csDataLoaded = 0;
+ }
+ if (_flagsTable[58] > 0 && !isSoundPlaying(0)) {
+ const int r = getRandomNumber();
+ if (r > 10000) {
+ int num;
+ if (r > 25000) {
+ num = 0;
+ } else if (r > 17000) {
+ num = 4;
+ } else {
+ num = 5;
+ }
+ startSound(_locationSoundsTable[num].offset, num, _locationSoundsTable[num].volume);
+ }
+ }
+ if (_spritesTable[0].state == 6) {
+ if (_spritesTable[0].animationFrame < 18) {
+ _spritesTable[0].gfxBackgroundOffset = 320 + _spritesTable[0].animationFrame * 638;
+ } else {
+ _spritesTable[0].gfxBackgroundOffset = 11840 - _spritesTable[0].animationFrame * 2;
+ }
+ } else {
+ _spritesTable[0].gfxBackgroundOffset = 320;
+ }
+ if (_inventoryItemsState[19] > 0) {
+ _flagsTable[43] = 1;
+ }
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum21() {
+ if (_flagsTable[58] > 3) {
+ drawSprite(0);
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum22() {
+ if (_flagsTable[53] > 1 && _flagsTable[53] != 4) {
+ if (_inventoryItemsState[5] > 0 && _inventoryItemsState[20] <= 0 && _inventoryItemsState[16] > 0 && _inventoryItemsState[27] > 0) {
+ _flagsTable[53] = 3;
+ }
+ if (_inventoryItemsState[5] > 0 || _inventoryItemsState[20] > 0 || _inventoryItemsState[16] > 0 || _inventoryItemsState[27] > 0) {
+ _flagsTable[53] = 5;
+ }
+ }
+ if (_flagsTable[210] < 2 && _csDataHandled == 0 && _flagsTable[54] == 1) {
+ _nextAction = 25;
+ _csDataLoaded = 0;
+ _flagsTable[210] = 2;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum23_0(int i) {
+ int state;
+ if (_flagsTable[210] == 3) {
+ state = 12;
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum23_1(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 14;
+ } else if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 25;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 13;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum23_2(int i) {
+ int state;
+ if (_flagsTable[210] == 0) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 6;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = (getRandomNumber() < 25000) ? 4 : 5;
+ }
+ } else if (_flagsTable[210] == 1) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ if (_flagsTable[211] == 10) {
+ state = 34;
+ } else if (_flagsTable[211] == 0) {
+ state = 30;
+ _flagsTable[211] = 1;
+ } else {
+ state = 31;
+ }
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_flagsTable[211] == 1) {
+ state = 32;
+ _flagsTable[211] = 0;
+ } else {
+ state = (getRandomNumber() < 25000) ? 10 : 11;
+ }
+ }
+ } else if (_flagsTable[210] == 2) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 33;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_flagsTable[212] == 0) {
+ state = 3;
+ _flagsTable[212] = 1;
+ } else if (_flagsTable[212] == 2) {
+ state = 29;
+ _flagsTable[212] = 3;
+ } else {
+ state = (getRandomNumber() < 25000) ? 22 : 23;
+ }
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum23_3(int i) {
+ int state;
+ if (_flagsTable[210] == 0 || _flagsTable[210] == 2) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 8;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 9;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum24_0(int i) {
+ int state;
+ if (_flagsTable[103] == 4) {
+ _flagsTable[103] = 3;
+ state = 5;
+ } else if (_flagsTable[103] == 0) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 1;
+ state = 1;
+ if (getRandomNumber() < 30000) {
+ _spritesTable[i].updateDelay = 5;
+ }
+ }
+ } else if (_flagsTable[103] == 1 || _flagsTable[103] == 3) {
+ state = -1;
+ } else {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 4;
+ } else {
+ if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 6;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 6;
+ }
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum24_1(int i) {
+ if (_flagsTable[103] > 1) {
+ _spritesTable[i].state = 3;
+ } else {
+ _spritesTable[i].state = -1;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum24_2(int i) {
+ int state;
+ if (_flagsTable[214] > 1) {
+ state = -1;
+ } else if (_flagsTable[214] == 1) {
+ _spritesTable[i].needUpdate = 0;
+ _flagsTable[214] = 2;
+ state = 9;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ if (_flagsTable[213] == 1) {
+ state = 10;
+ } else if (_flagsTable[213] == 2) {
+ state = 14;
+ } else {
+ state = 8;
+ }
+ } else {
+ _spritesTable[i].needUpdate = 1;
+ state = 7;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum24_3(int i) {
+ int state;
+ if (_flagsTable[239] == 1) {
+ state = -1;
+ } else if (_flagsTable[214] == 2) {
+ _flagsTable[239] = 1;
+ state = 13;
+ } else if (getRandomNumber() > 32000) {
+ state = 12;
+ } else {
+ state = 11;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum24() {
+ _characterPrevBackFrontFacing = 0;
+ if (_flagsTable[112] == 0) {
+ _yPosCurrent = 132;
+ _xPosCurrent = 112;
+ } else if (_inventoryItemsState[2] == 1 && _inventoryItemsState[11] == 1 && _flagsTable[156] == 1 && _flagsTable[145] == 3) {
+ _flagsTable[156] = 2;
+ _nextAction = 61;
+ _csDataLoaded = 0;
+ }
+ if (_flagsTable[103] > 0 && (_inventoryItemsState[2] > 0 || _inventoryItemsState[11] > 0 || _flagsTable[156] > 0 || _flagsTable[145] == 3) && _flagsTable[217] == 0) {
+ _flagsTable[217] = 1;
+ }
+ _locationHeightTable[24] = (_yPosCurrent < 125) ? 60 : 0;
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum24() {
+ if (_yPosCurrent < 132) {
+ drawSprite(1);
+ drawSprite(0);
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum25() {
+ _backgroundSprOffset = _xPosCurrent - 160;
+}
+
+void TuckerEngine::updateSprite_locationNum26_0(int i) {
+ if (_flagsTable[125] > 0 && _flagsTable[125] < 300) {
+ _flagsTable[126] = 1;
+ }
+ _spritesTable[i].gfxBackgroundOffset = _flagsTable[125];
+ _spritesTable[i].state = 1;
+ _spritesTable[i].colorType = 99;
+}
+
+void TuckerEngine::updateSprite_locationNum26_1(int i) {
+ int state;
+ if (_flagsTable[125] == 0) {
+ state = -1;
+ } else if (_flagsTable[125] > 299) {
+ state = 2;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ state = 2;
+ }
+ _spritesTable[i].gfxBackgroundOffset = _flagsTable[125];
+ _spritesTable[i].colorType = 1;
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum26() {
+ _characterPrevBackFrontFacing = 1;
+ _spritesTable[1].gfxBackgroundOffset = _flagsTable[125];
+ _spritesTable[0].gfxBackgroundOffset = _flagsTable[125];
+ if (_flagsTable[125] > 0 && _flagsTable[125] < 300) {
+ if (!isSoundPlaying(5)) {
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ startSound(_locationSoundsTable[6].offset, 6, _locationSoundsTable[6].volume);
+ }
+ ++_flagsTable[125];
+ _flagsTable[126] = 1;
+ } else {
+ if (isSoundPlaying(5)) {
+ stopSound(5);
+ stopSound(6);
+ }
+ }
+ if (_panelLockedFlag == 0) {
+ if (_xPosCurrent > 207 && _xPosCurrent < 256) {
+ _objectKeysLocationTable[26] = 0;
+ _objectKeysPosXTable[26] = 260;
+ } else {
+ _objectKeysLocationTable[26] = 1;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum27(int i) {
+ int state;
+ if (_flagsTable[155] < 3 || _flagsTable[125] == 5) {
+ state = -1;
+ } else if (_flagsTable[155] == 3) {
+ state = 1;
+ _flagsTable[155] = 4;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 3;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 3;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum27() {
+ _characterPrevBackFrontFacing = 0;
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum27() {
+ if (_flagsTable[155] == 4 && _yPosCurrent < 125) {
+ drawSprite(0);
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum28_0(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 4;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ ++_spritesTable[i].counter;
+ if (_spritesTable[i].counter > 30) {
+ _spritesTable[i].counter = 0;
+ }
+ if (_flagsTable[86] == 1) {
+ if (_spritesTable[i].counter == 16 || _spritesTable[i].counter == 27) {
+ state = 3;
+ } else {
+ state = 3;
+ _spritesTable[i].updateDelay = 5;
+ }
+ } else {
+ if (_spritesTable[i].counter == 5 || _spritesTable[i].counter == 11) {
+ state = 5;
+ } else if (_spritesTable[i].counter == 16 || _spritesTable[i].counter == 27) {
+ state = 6;
+ } else {
+ state = 6;
+ _spritesTable[i].updateDelay = 5;
+ }
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum28_1(int i) {
+ _spritesTable[i].state = (_flagsTable[86] == 1) ? 1 : -1;
+}
+
+void TuckerEngine::updateSprite_locationNum28_2(int i) {
+ int state;
+ if (_flagsTable[155] == 1) {
+ state = 8;
+ _flagsTable[155] = 2;
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum28() {
+ if (_flagsTable[86] == 0 && _xPosCurrent > 265 && _nextAction == 0) {
+ _panelLockedFlag = 0;
+ _nextAction = 21;
+ _csDataLoaded = 0;
+ _pendingActionDelay = 0;
+ _pendingActionIndex = 0;
+ _updateCharPositionNewType = 0;
+ }
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum28() {
+ if (_yPosCurrent < 135) {
+ drawSprite(1);
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum29_0(int i) {
+ _spritesTable[i].state = (getRandomNumber() < 32000) ? -1 : 2;
+}
+
+void TuckerEngine::updateSprite_locationNum29_1(int i) {
+ int state = -1;
+ if (getRandomNumber() >= 32000) {
+ state = 1;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum29_2(int i) {
+ _spritesTable[i].state = 3;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum29() {
+ static const uint8 r[] = { 0x0D, 0x0E, 0x0E, 0x0E, 0x0D, 0x0E, 0x0D, 0x0E, 0x0E, 0x0E, 0x0D };
+ static const uint8 g[] = { 0x0E, 0x14, 0x1B, 0x14, 0x0E, 0x0D, 0x0E, 0x14, 0x1B, 0x14, 0x0E };
+ static const uint8 b[] = { 0x2C, 0x34, 0x3B, 0x34, 0x2C, 0x24, 0x2C, 0x34, 0x3B, 0x34, 0x2C };
+ if (_fadePaletteCounter == 16) {
+ ++_updateLocationFadePaletteCounter;
+ if (_updateLocationFadePaletteCounter > 10) {
+ _updateLocationFadePaletteCounter = 0;
+ }
+ int d = _updateLocationFadePaletteCounter / 2;
+ for (int i = 0; i < 5; ++i) {
+ setPaletteColor(118 + i, r[i] + d, g[i] + d, b[i] + d);
+ }
+ if (_flagsTable[143] == 1) {
+ _locationObjectsTable[2].xPos = 999;
+ _locationObjectsTable[3].xPos = 187;
+ } else {
+ _locationObjectsTable[2].xPos = 187;
+ _locationObjectsTable[3].xPos = 999;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum30_34(int i) {
+ _spritesTable[i].state = i + 1;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum30() {
+ if (!isSoundPlaying(1) && getRandomNumber() > 32500) {
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum31() {
+ execData3PreUpdate_locationNum31Helper(32000, 110);
+ execData3PreUpdate_locationNum31Helper(31000, 111);
+ if (_xPosCurrent < 112 && _flagsTable[104] == 0) {
+ _flagsTable[104] = 1;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum31Helper(int r, int flag) {
+ if (getRandomNumber() > r && _flagsTable[flag] == 0) {
+ _flagsTable[flag] = 1;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum32() {
+ if (_spritesTable[0].state == 12 && _spritesTable[0].animationFrame < 22) {
+ _flagsTable[113] = 1;
+ } else {
+ _flagsTable[113] = 0;
+ }
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum32() {
+ if (_yPosCurrent < 120) {
+ drawSprite(0);
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum31_0(int i) {
+ _spritesTable[i].state = (getRandomNumber() < 32000) ? 3 : 1;
+}
+
+void TuckerEngine::updateSprite_locationNum31_1(int i) {
+ _spritesTable[i].state = (_flagsTable[86] == 1) ? 2 : -1;
+}
+
+void TuckerEngine::updateSprite_locationNum32_0(int i) {
+ static const uint8 stateTable[] = { 12, 1, 11, 1, 11, 2, 1, 5, 5, 11, 1, 5, 5, 5 };
+ ++_spritesTable[i].counter;
+ if (_flagsTable[123] == 2) {
+ _flagsTable[123] = 0;
+ }
+ int state;
+ if (_flagsTable[222] == 1) {
+ state = 19;
+ _flagsTable[222] = 2;
+ } else if (_flagsTable[222] == 2) {
+ state = 19;
+ _spritesTable[i].animationFrame = 23;
+ _updateSpriteFlag1 = 1;
+ } else if (_flagsTable[123] == 1) {
+ state = 17;
+ _flagsTable[123] = 2;
+ } else if (_flagsTable[222] == 3) {
+ state = 18;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 4;
+ } else if (_csDataHandled) {
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (_spritesTable[i].counter > 13) {
+ _spritesTable[i].counter = 0;
+ }
+ state = stateTable[_spritesTable[i].counter];
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum33_0(int i) {
+ int state = 5;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 7;
+ } else if (_flagsTable[87] == 1) {
+ state = 8;
+ } else if (_flagsTable[222] == 5) {
+ state = 4;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = (getRandomNumber() < 30000) ? 5 : 6;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum33_1(int i) {
+ int state;
+ if (_flagsTable[87] == 1) {
+ state = 3;
+ } else if (_flagsTable[222] == 5) {
+ state = 2;
+ } else {
+ state = 1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum33_2(int i) {
+ int state;
+ if (_flagsTable[87] == 1) {
+ state = 11;
+ } else if (_flagsTable[222] == 5) {
+ state = 10;
+ } else {
+ state = 9;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum33() {
+ if (_xPosCurrent < 90) {
+ if (_flagsTable[105] == 0) {
+ _flagsTable[105] = 3;
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ }
+ } else {
+ if (_flagsTable[105] == 1) {
+ _flagsTable[105] = 2;
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ }
+ }
+ if (_xPosCurrent > 230) {
+ if (_flagsTable[106] == 0) {
+ _flagsTable[106] = 3;
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ }
+ } else {
+ if (_flagsTable[106] == 1) {
+ _flagsTable[106] = 2;
+ startSound(_locationSoundsTable[5].offset, 5, _locationSoundsTable[5].volume);
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum34() {
+ if (_flagsTable[143] == 1) {
+ _locationObjectsTable[0].xPos = 0;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum35() {
+ if (_flagsTable[250] > 0) {
+ _currentFxVolume = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum36(int i) {
+ _spritesTable[i].state = (getRandomNumber() < 32000) ? 1 : 2;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum36() {
+ if (_execData3Counter == 0) {
+ _execData3Counter = 1;
+ _flagsTable[107] = 1;
+ } else if (_flagsTable[107] == 0 && _locationMaskType == 1 && _execData3Counter == 1) {
+ _execData3Counter = 2;
+ _flagsTable[107] = 1;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum37(int i, int j, int offset) {
+ ++_spritesTable[i].counter;
+ if (_spritesTable[i].counter > offset) {
+ _spritesTable[i].state = j;
+ _spritesTable[i].counter = 0;
+ } else {
+ _spritesTable[i].state = -1;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum38() {
+ if (_flagsTable[117] == 0 && _flagsTable[116] == 1) {
+ _flagsTable[116] = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum41(int i) {
+ int state;
+ if (_flagsTable[223] > 1) {
+ state = -1;
+ } else if (_flagsTable[223] == 1) {
+ state = 1;
+ _flagsTable[158] = 2;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 3;
+ } else if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 4;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum41() {
+ if (_backgroundSpriteCurrentAnimation == 4) {
+ if (_backgroundSpriteCurrentFrame == 8) {
+ _flagsTable[77] = 2;
+ } else if (_backgroundSpriteCurrentFrame == 7) {
+ _flagsTable[77] = 0;
+ }
+ if (_changeBackgroundSprite == 0) {
+ if (_backgroundSpriteCurrentFrame == 16 && !isSoundPlaying(4)) {
+ _locationSoundsTable[4].type = 2;
+ startSound(_locationSoundsTable[4].offset, 4, _locationSoundsTable[4].volume);
+ } else {
+ if (_backgroundSpriteCurrentFrame == 28) {
+ stopSound(4);
+ }
+ }
+ } else {
+ if (_backgroundSpriteCurrentFrame == 28 && !isSoundPlaying(4)) {
+ _locationSoundsTable[4].type = 2;
+ startSound(_locationSoundsTable[4].offset, 4, _locationSoundsTable[4].volume);
+ } else {
+ if (_backgroundSpriteCurrentFrame == 18) {
+ stopSound(4);
+ }
+ }
+ }
+ }
+ if (_panelLockedFlag == 1 && _yPosCurrent > 130 && _selectedObject.yPos > 135 && _nextAction == 0 && _flagsTable[223] == 0) {
+ _panelLockedFlag = 0;
+ _csDataLoaded = false;
+ _nextLocationNum = 0;
+ _selectedObject.locationObject_locationNum = 0;
+ _locationMaskType = 0;
+ _nextAction = _flagsTable[163] + 32;
+ ++_flagsTable[163];
+ if (_flagsTable[163] > 2) {
+ _flagsTable[163] = 0;
+ }
+ if (_flagsTable[223] > 0 && _mapSequenceFlagsLocationTable[40] == 0) {
+ for (int i = 41; i < 53; ++i) {
+ _mapSequenceFlagsLocationTable[i - 1] = 1;
+ }
+ }
+ if (_flagsTable[77] == 0) {
+ _locationObjectsTable[3].xPos = 230;
+ } else {
+ _locationObjectsTable[3].xPos = 930;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum42(int i) {
+ int state;
+ if (_flagsTable[223] == 0 || _flagsTable[223] > 3) {
+ state = -1;
+ } else if (_flagsTable[223] == 1) {
+ state = 1;
+ _flagsTable[223] = 2;
+ } else if (_flagsTable[223] == 2) {
+ state = 5;
+ _flagsTable[223] = 3;
+ } else if (_flagsTable[223] == 3) {
+ state = 5;
+ _spritesTable[i].updateDelay = 5;
+ _spritesTable[i].state = _spritesTable[i].firstFrame - 1; // XXX bug, fxNum ?
+ _updateSpriteFlag1 = 1;
+ } else {
+ state = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum42() {
+ _flagsTable[167] = 1;
+}
+
+void TuckerEngine::updateSprite_locationNum43_2(int i) {
+ int state;
+ if (_flagsTable[237] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 5;
+ } else if (_csDataHandled || _spritesTable[i].counter == 2) {
+ _spritesTable[i].needUpdate = 0;
+ state = 6;
+ } else if (_spritesTable[i].counter == 0) {
+ state = 3;
+ } else {
+ state = 4;
+ _spritesTable[i].counter = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum43_3(int i) {
+ int state;
+ if (_flagsTable[236] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 7;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ state = 8;
+ _spritesTable[i].needUpdate = 0;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum43_4(int i) {
+ int state;
+ if (_flagsTable[236] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 9;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ state = 10;
+ _spritesTable[i].needUpdate = 0;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum43_5(int i) {
+ _spritesTable[i].state = (_flagsTable[236] < 4) ? -1 : 11;
+}
+
+void TuckerEngine::updateSprite_locationNum43_6(int i) {
+ _spritesTable[i].state = (_flagsTable[236] < 4) ? -1 : 12;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum43() {
+ if (_panelLockedFlag == 1 && _xPosCurrent > 67 && _selectedObject.xPos > 68 && _locationMaskType == 0) {
+ _panelLockedFlag = 0;
+ _csDataLoaded = 0;
+ _nextAction = 5;
+ }
+ if (_xPosCurrent > 55 && _spritesTable[2].counter == 0) {
+ _spritesTable[2].counter = 1;
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum44() {
+ if (_backgroundSpriteCurrentAnimation == 1) {
+ if (!isSoundPlaying(3) && _backgroundSpriteCurrentFrame == 1) {
+ _locationSoundsTable[3].type = 2;
+ startSound(_locationSoundsTable[3].offset, 3, _locationSoundsTable[3].volume);
+ }
+ if (_backgroundSpriteCurrentFrame == 21) {
+ _flagsTable[77] = 1;
+ } else if (_backgroundSpriteCurrentFrame == 20) {
+ _flagsTable[77] = 2;
+ stopSound(3);
+ }
+ } else if (_backgroundSpriteCurrentAnimation == 4) {
+ if (_backgroundSpriteCurrentFrame == 20 && !isSoundPlaying(3)) {
+ startSound(_locationSoundsTable[3].offset, 3, _locationSoundsTable[3].volume);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum48(int i) {
+ int state;
+ if (_flagsTable[160] == 0 || _flagsTable[160] > 2 || _flagsTable[207] > 0) {
+ state = -1;
+ } else if (_flagsTable[160] == 2) {
+ _flagsTable[160] = 3;
+ state = 3;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum49(int i) {
+ if (_flagsTable[136] == 1 && _flagsTable[207] == 0) {
+ _flagsTable[207] = 2;
+ }
+ if (_flagsTable[185] == 0 && _yPosCurrent < 125) {
+ _flagsTable[185] = 1;
+ } else if (_flagsTable[185] == 2 && (_yPosCurrent > 130 || _flagsTable[236] == 4)) {
+ _flagsTable[185] = 3;
+ }
+ int state;
+ if (_flagsTable[185] == 0 || _flagsTable[160] < 3) {
+ state = -1;
+ } else if (_flagsTable[185] == 1) {
+ _flagsTable[185] = 2;
+ state = 1;
+ } else if (_flagsTable[185] == 3) {
+ _flagsTable[185] = 0;
+ state = 4;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (getRandomNumber() < 30000 || _backgroundSpriteCurrentAnimation <= -1) {
+ state = 3;
+ _spritesTable[i].updateDelay = 1;
+ } else if (getRandomNumber() < 16000) {
+ state = 5;
+ } else {
+ state = 6;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum49() {
+ _flagsTable[132] = 0;
+ if (_execData3Counter == 0) {
+ _execData3Counter = 1;
+ if (_flagsTable[181] == 2) {
+ _flagsTable[181] = 3;
+ }
+ }
+ static const int items[] = { 15, 44, 25, 27, 19, 21, 24, 13, 20, 29, 35, 23, 3 };
+ for (int i = 0; i < 13; ++i) {
+ if (_inventoryItemsState[items[i]] == 1) {
+ _flagsTable[168 + i] = 1;
+ }
+ }
+ int counter = 0;
+ for (int i = 168; i < 181; ++i) {
+ if (_flagsTable[i] == 2) {
+ ++counter;
+ }
+ }
+ if (_nextAction == 0) {
+ if (counter == 2 && _flagsTable[236] == 0) {
+ _nextAction = 56;
+ _csDataLoaded = false;
+ } else if (counter == 6 && _flagsTable[236] == 1) {
+ _nextAction = 59;
+ _csDataLoaded = false;
+ } else if (counter == 10 && _flagsTable[236] == 2) {
+ _nextAction = 62;
+ _csDataLoaded = false;
+ } else if (counter == 13 && _flagsTable[236] == 3) {
+ _nextAction = 65;
+ _csDataLoaded = false;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum50(int i) {
+ int state;
+ if (_flagsTable[240] == 0) {
+ state = i + 1;
+ if (i == 5) {
+ _flagsTable[240] = 1;
+ }
+ } else {
+ _spritesTable[i].animationFrame = _spritesTable[i].firstFrame - 1;
+ _spritesTable[i].updateDelay = 5;
+ _updateSpriteFlag1 = 1;
+ state = i + 1;
+ }
+ state = i + 1; // XXX bug ?
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum51_0(int i) {
+ static const int stateTable[] = { 3, 3, 4, 5, 3, 3, 5, 4, 3, 3, 4, 5, 4, 4 };
+ ++_spritesTable[i].counter;
+ if (_spritesTable[i].counter > 13) {
+ _spritesTable[i].counter = 0;
+ }
+ _spritesTable[i].state = stateTable[_spritesTable[i].counter];
+ _spritesTable[i].colorType = 1;
+ _spritesTable[i].yMaxBackground = 0;
+}
+
+void TuckerEngine::updateSprite_locationNum51_1(int i) {
+ _spritesTable[i].state = 6;
+ _spritesTable[i].colorType = 1;
+ _spritesTable[i].yMaxBackground = 0;
+}
+
+void TuckerEngine::updateSprite_locationNum51_2(int i) {
+ _spritesTable[i].state = 1;
+ _spritesTable[i].colorType = 1;
+ _spritesTable[i].yMaxBackground = 0;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum52() {
+ if (_selectedObject.xPos > 108 && _panelLockedFlag > 0 && _nextAction == 0 && _locationMaskType == 0) {
+ _nextAction = 1;
+ _csDataLoaded = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum53_0(int i) {
+ if (_flagsTable[197] == 2) {
+ _flagsTable[197] = 3;
+ }
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 1;
+ } else if (_flagsTable[197] == 1) {
+ state = 3;
+ _spritesTable[i].needUpdate = 0;
+ _flagsTable[197] = 2;
+ } else if (_flagsTable[192] == 1) {
+ _spritesTable[i].needUpdate = 0;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 5;
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum53_1(int i) {
+ int state;
+ if (_flagsTable[197] == 3) {
+ state = 6;
+ } else if (_flagsTable[197] == 4) {
+ state = 7;
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum53() {
+ if (_flagsTable[192] == 0 && _xPosCurrent < 200 && _nextAction == 0) {
+ _panelLockedFlag = 0;
+ _nextAction = 14;
+ _csDataLoaded = 0;
+ _pendingActionDelay = 0;
+ _pendingActionIndex = 0;
+ _updateCharPositionNewType = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum54(int i) {
+ int state = 3;
+ if (_flagsTable[141] == 2) {
+ _spritesTable[i].needUpdate = 0;
+ setCharacterAnimation(0, i);
+ _flagsTable[141] = 1;
+ _spritesTable[i].counter = 0;
+ } else if (_flagsTable[141] == 1 && _spritesTable[i].counter < 40) {
+ setCharacterAnimation(1, i);
+ ++_spritesTable[i].counter;
+ } else if (_flagsTable[141] == 1) {
+ setCharacterAnimation(2, i);
+ _flagsTable[141] = 3;
+ } else {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 2;
+ state = (getRandomNumber() < 12000) ? 2 : 4;
+ } else if (_flagsTable[141] == 3) {
+ state = 3;
+ _flagsTable[141] = 0;
+ _flagsTable[224] = 1;
+ _spritesTable[i].counter = 0;
+ if (_panelLockedFlag == 0 && _xPosCurrent > 130 && _inventoryItemsState[17] == 0) {
+ _nextAction = 18;
+ _csDataLoaded = false;
+ }
+ } else if (getRandomNumber() < 26000) {
+ state = 3;
+ _spritesTable[i].needUpdate = 0;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ state = 3;
+ _spritesTable[i].needUpdate = 0;
+ }
+ if (_inventoryItemsState[17] == 1) {
+ _flagsTable[224] = 2;
+ }
+ _spritesTable[i].state = state;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum55(int i) {
+ if (_flagsTable[193] > 0 && _flagsTable[193] < 14) {
+ setCharacterAnimation(_flagsTable[193] - 1, i);
+ _updateSpriteFlag1 = 1;
+ if (_flagsTable[193] == 1 || _flagsTable[193] == 3 || _flagsTable[193] == 5 || _flagsTable[193] == 7 || _flagsTable[193] == 11 || _flagsTable[193] == 13) {
+ ++_flagsTable[193];
+ }
+ } else {
+ _spritesTable[i].state = -1;
+ if (_flagsTable[193] == 14) {
+ _flagsTable[193] = 15;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum56(int i) {
+ int state;
+ ++_spritesTable[i].counter;
+ if (_flagsTable[153] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum57_0(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (getRandomNumber() < 30000) {
+ state = 1;
+ } else if (getRandomNumber() < 16000) {
+ state = 4;
+ } else {
+ state = 2;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum57_1(int i) {
+ int state = 6;
+ if (getRandomNumber() < 30000) {
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum57() {
+ if (_flagsTable[137] == 2 && _xPosCurrent < 42 && _yPosCurrent == 135) {
+ _flagsTable[137] = 0;
+ _backgroundSpriteCurrentAnimation = 2;
+ _backgroundSpriteCurrentFrame = 0;
+ _backgroundSprOffset = 0;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum58(int i) {
+ int state;
+ if (_flagsTable[190] == 0) {
+ state = 1;
+ } else if (_flagsTable[190] == 1) {
+ state = 2;
+ _flagsTable[190] = 2;
+ } else {
+ state = 3;
+ if (_flagsTable[190] == 2) {
+ _flagsTable[190] = 3;
+ }
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum58() {
+ if (_flagsTable[190] < 3 && _xPosCurrent > 310) {
+ _xPosCurrent = 310;
+ _panelLockedFlag = 0;
+ }
+ if (_flagsTable[190] > 0 && _locationSoundsTable[0].volume > 0) {
+ _locationSoundsTable[0].volume = 0;
+ _locationSoundsTable[4].volume = 0;
+ _locationSoundsTable[5].volume = 0;
+ if (isSoundPlaying(0)) {
+ stopSound(0);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum59(int i) {
+ int state;
+ if (_flagsTable[207] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 3;
+ _spritesTable[i].needUpdate = 1;
+ } else if (_csDataHandled) {
+ _spritesTable[i].needUpdate = 0;
+ if (_flagsTable[199] == 0) {
+ _flagsTable[199] = 1;
+ setCharacterAnimation(0, 0);
+ return;
+ }
+ _spritesTable[i].needUpdate = 0;
+ state = 3;
+ _spritesTable[i].updateDelay = 5;
+ } else if (_flagsTable[199] == 1) {
+ _flagsTable[199] = 0;
+ _spritesTable[i].needUpdate = 0;
+ setCharacterAnimation(1, 0);
+ return;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum60_0(int i) {
+ int state;
+ if (_flagsTable[186] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 9;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = (getRandomNumber() > 32000) ? 8 : 7;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum60_1(int i) {
+ int state;
+ if (_flagsTable[186] == 1) {
+ _flagsTable[186] = 2;
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ } else if (_flagsTable[186] == 2) {
+ state = 6;
+ _flagsTable[187] = 1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 1;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = (getRandomNumber() > 32000) ? 5 : 4;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum60() {
+ drawSprite(0);
+}
+
+void TuckerEngine::updateSprite_locationNum61_0(int i) {
+ int state;
+ const int r = getRandomNumber();
+ if (_flagsTable[88] == 1) {
+ state = 3;
+ _flagsTable[88] = 2;
+ } else if (_flagsTable[88] == 2) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 0) {
+ if (_spritesTable[i].needUpdate == 0) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ state = 2;
+ _spritesTable[0].animationFrame = 2;
+ _updateSpriteFlag1 = 1;
+ }
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ if (r < 30000) {
+ state = 7;
+ _spritesTable[i].updateDelay = 5;
+ } else if (r < 31000) {
+ state = 7;
+ } else if (r < 32000) {
+ state = 5;
+ } else {
+ state = 6;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum61_1(int i) {
+ int state;
+ if (_flagsTable[151] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 14;
+ } else if (_csDataHandled || getRandomNumber() < 29000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 12;
+ _spritesTable[i].updateDelay = 5;
+ } else if (getRandomNumber() < 20000) {
+ state = 12;
+ } else {
+ state = 13;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum61_2(int i) {
+ int state;
+ const int r = getRandomNumber();
+ _flagsTable[150] = 1;
+ if (_flagsTable[198] == 2) {
+ _flagsTable[150] = 2;
+ state = 16;
+ } else if (_flagsTable[198] == 1) {
+ if (_flagsTable[150] == 2) {
+ state = 10;
+ } else {
+ state = 18;
+ }
+ _flagsTable[198] = 2;
+ _flagsTable[150] = 0;
+ } else if (r < 32000) {
+ state = 15;
+ } else if (r < 32100) {
+ state = 1;
+ if (_xPosCurrent < 340 || _xPosCurrent > 380) {
+ _flagsTable[150] = 0;
+ if (_flagsTable[136] == 0) {
+ state = 17;
+ }
+ } else {
+ state = 15;
+ }
+ } else if (r < 32200) {
+ state = 4;
+ } else if (r < 32300) {
+ state = 8;
+ } else {
+ state = 9;
+ }
+ _flagsTable[248] = _flagsTable[150];
+ if (_flagsTable[136] != 2) {
+ _flagsTable[150] = 0;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum61() {
+ if (_inventoryItemsState[36] == 1) {
+ _flagsTable[93] = (_inventoryItemsState[6] == 1) ? 3 : 1;
+ } else {
+ _flagsTable[93] = (_inventoryItemsState[6] == 1) ? 2 : 0;
+ }
+ _flagsTable[154] = _inventoryItemsState[16];
+ if (_inventoryItemsState[16] == 2 && _inventoryItemsState[36] == 2) {
+ if (!_csDataHandled && _flagsTable[88] == 0) {
+ _flagsTable[88] = 1;
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum63_0(int i) {
+ int state;
+ if (_flagsTable[136] > 0 && _flagsTable[132] == 2) {
+ state = 12;
+ } else if (_flagsTable[132] != 2 || _flagsTable[133] != 1 || _flagsTable[136] > 0) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 6;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum63_1(int i) {
+ int state = -1;
+ if (_flagsTable[132] == 2 && _flagsTable[133] == 1 && _flagsTable[136] > 0) {
+ state = -1;
+ } else if (getRandomNumber() > 30000) {
+ state = 5;
+ } else if (getRandomNumber() > 30000) {
+ state = 8;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum63_2(int i) {
+ ++_spritesTable[i].counter;
+ int state = -1;
+ if (_flagsTable[132] == 2 && _flagsTable[133] == 1 && _flagsTable[136] > 0) {
+ if (_flagsTable[226] == 0) {
+ state = 9;
+ _spritesTable[i].updateDelay = 5;
+ } else if (_flagsTable[226] == 1) {
+ state = 9;
+ _flagsTable[226] = 2;
+ } else if (_flagsTable[226] == 2) {
+ state = 3;
+ } else {
+ _flagsTable[226] = 0;
+ state = 10;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum63_3(int i) {
+ ++_spritesTable[i].counter;
+ int state = -1;
+ if (_flagsTable[133] == 1 && _flagsTable[132] == 2 && _flagsTable[136] > 0) {
+ if (_spritesTable[i].counter > 80) {
+ state = 7;
+ _spritesTable[i].counter = 0;
+ } else if (getRandomNumber() > 32000) {
+ state = 2;
+ } else if (getRandomNumber() > 32000) {
+ state = 4;
+ } else if (getRandomNumber() > 28000) {
+ state = 8;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum63_4(int i) {
+ int state = -1;
+ if (_flagsTable[132] == 2 && _flagsTable[133] == 1 && _flagsTable[136] == 0) {
+ state = 1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum63() {
+ _currentGfxBackgroundCounter = 20 - _flagsTable[132] * 10;
+ if (_flagsTable[132] != _execData3Counter) {
+ _execData3Counter = _flagsTable[132];
+ }
+ if (_flagsTable[133] == 0) {
+ _currentGfxBackgroundCounter = 30;
+ }
+ if (_flagsTable[136] > 0 && _flagsTable[132] == 2) {
+ _currentGfxBackgroundCounter = 20;
+ }
+ if (_flagsTable[133] == 0) {
+ for (int i = 0; i < 3; ++i) {
+ if (isSoundPlaying(i)) {
+ stopSound(i);
+ }
+ }
+ } else {
+ if (_flagsTable[132] == 0 || _flagsTable[132] == 2 || _flagsTable[136] > 0) {
+ if (!isSoundPlaying(1)) {
+ _locationSoundsTable[1].type = 2;
+ startSound(_locationSoundsTable[1].offset, 1, _locationSoundsTable[1].volume);
+ }
+ } else {
+ if (isSoundPlaying(1)) {
+ stopSound(1);
+ }
+ }
+ if (_flagsTable[132] == 1) {
+ if (!isSoundPlaying(0)) {
+ _locationSoundsTable[0].type = 2;
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ }
+ } else {
+ if (isSoundPlaying(1)) {
+ stopSound(1);
+ }
+ }
+ if (_flagsTable[132] == 2 && _flagsTable[136] == 0) {
+ if (!isSoundPlaying(2)) {
+ startSound(_locationSoundsTable[2].offset, 2, _locationSoundsTable[2].volume);
+ }
+ } else {
+ if (isSoundPlaying(2)) {
+ stopSound(2);
+ }
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum64() {
+ if (_currentGfxBackgroundCounter < 30) {
+ _locationHeightTable[64] = 48 - (_currentGfxBackgroundCounter / 10);
+ } else {
+ _locationHeightTable[64] = 47;
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum65(int i) {
+ int state;
+ if (_flagsTable[188] == 1) {
+ _flagsTable[188] = 2;
+ state = 1;
+ _spritesTable[i].gfxBackgroundOffset = 100;
+ } else if (_flagsTable[188] > 0 && _flagsTable[189] > 0) {
+ state = -1;
+ if (_xPosCurrent < 150 || _yPosCurrent > 240) {
+ _flagsTable[189] = 0;
+ }
+ } else {
+ if (_xPosCurrent >= 150 && _yPosCurrent < 240) { // XXX bug
+ if (getRandomNumber() > 32000) {
+ state = 2;
+ _flagsTable[189] = 1;
+ } else {
+ state = -1;
+ }
+ } else {
+ state = -1;
+ _flagsTable[189] = 0;
+ }
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum65() {
+ _flagsTable[137]= 0;
+}
+
+void TuckerEngine::updateSprite_locationNum66_0(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ _spritesTable[i].updateDelay = 5;
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum66_1(int i) {
+ int state;
+ if (_flagsTable[191] == 0 && _xPosCurrent > 568) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 8;
+ } else if (getRandomNumber() > 30000) {
+ state = 10;
+ _spritesTable[i].needUpdate = 0;
+ } else {
+ state = 10;
+ _spritesTable[i].needUpdate = 0;
+ }
+ } else {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 9;
+ } else if (getRandomNumber() > 30000) {
+ state = 6;
+ _spritesTable[i].needUpdate = 0;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 7;
+ _spritesTable[i].updateDelay = 5;
+ }
+ }
+ _spritesTable[i].state = state;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::updateSprite_locationNum66_2(int i) {
+ _spritesTable[i].disabled = 1;
+ _spritesTable[i].state = 3;
+}
+
+void TuckerEngine::updateSprite_locationNum66_3(int i) {
+ _spritesTable[i].state = 4;
+}
+
+void TuckerEngine::updateSprite_locationNum66_4(int i) {
+ _spritesTable[i].state = 5;
+ _spritesTable[i].gfxBackgroundOffset = 320;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum66() {
+ _flagsTable[137]= 0;
+ if (_xPosCurrent > 583 && _flagsTable[191] == 0 && _nextAction == 0 && _locationMaskType == 0) {
+ _panelLockedFlag = 0;
+ _csDataLoaded = 0;
+ _nextLocationNum = 0;
+ _selectedObject.locationObject_locationNum = 0;
+ if (_flagsTable[131] == 0) {
+ _nextAction = 13;
+ } else if (_flagsTable[130] == 0) {
+ _nextAction = 14;
+ } else {
+ _nextAction = 35;
+ }
+ }
+}
+
+void TuckerEngine::execData3PostUpdate_locationNum66() {
+ if (_spritesTable[2].flipX == 1) {
+ --_updateLocationXPosTable2[0];
+ if (_updateLocationXPosTable2[0] < -50) {
+ _updateLocationXPosTable2[0] = 0;
+ _updateLocationXPosTable2[0] = -50;
+ }
+ } else {
+ ++_updateLocationXPosTable2[0];
+ if (_updateLocationXPosTable2[0] > 500) {
+ _updateLocationXPosTable2[0] = 1;
+ _updateLocationXPosTable2[0] = 500;
+ }
+ }
+ _spritesTable[2].gfxBackgroundOffset = _updateLocationXPosTable2[0] + 8320;
+ const int spr = 2;
+ _spritesTable[spr].colorType = 1;
+ _spritesTable[spr].yMaxBackground = 0;
+ drawSprite(spr);
+ _spritesTable[spr].colorType = 0;
+}
+
+void TuckerEngine::updateSprite_locationNum69_1(int i) {
+ int state;
+ if (_flagsTable[236] == 1) {
+ state = 4;
+ } else if (_flagsTable[236] == 2) {
+ state = 3;
+ } else if (_flagsTable[236] == 3) {
+ state = 2;
+ } else if (_flagsTable[236] == 4) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 9;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ state = 14;
+ _spritesTable[i].needUpdate = 0;
+ }
+ } else if (_flagsTable[236] == 5) {
+ state = 7;
+ _flagsTable[236] = 6;
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum69_2(int i) {
+ if (_flagsTable[237] == 2) {
+ _flagsTable[237] = 3;
+ }
+ int state;
+ if (_flagsTable[236] < 4 || _flagsTable[237] == 0) {
+ state = -1;
+ } else if (_flagsTable[237] == 1) {
+ state = 5;
+ _flagsTable[237] = 2;
+ } else if (_flagsTable[237] == 4 || _flagsTable[237] == 2 || _flagsTable[237] == 3 || _flagsTable[237] == 7) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 10;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ state = 12;
+ _spritesTable[i].needUpdate = 0;
+ }
+ } else if (_flagsTable[237] == 5) {
+ state = 16;
+ _flagsTable[237] = 6;
+ } else if (_flagsTable[237] == 6) {
+ state = 15;
+ _flagsTable[237] = 7;
+ } else if (_flagsTable[237] == 8) {
+ state = 6;
+ _flagsTable[237] = 9;
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum69_3(int i) {
+ int state;
+ if (_flagsTable[236] > 4) {
+ state = -1;
+ } else if (_flagsTable[237] == 3) {
+ state = 8;
+ _flagsTable[237] = 4;
+ } else if (_flagsTable[237] > 2 && _flagsTable[237] < 9) {
+ _flagsTable[238] = 1;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ state = 11;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ state = 13;
+ _spritesTable[i].needUpdate = 0;
+ }
+ } else {
+ state = -1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum70() {
+ const uint8 color = 103;
+ if (_execData3Counter == 0) {
+ startSound(_locationSoundsTable[6].offset, 6, _locationSoundsTable[6].volume);
+ _execData3Counter = 1;
+ _flagsTable[143] = 0;
+ _updateLocation70StringLen = 0;
+ _forceRedrawPanelItems = 1;
+ _panelState = 1;
+ setCursorType(2);
+ }
+ _forceRedrawPanelItems = 1;
+ _panelState = 1;
+ setCursorType(2);
+ int pos = getPositionForLine(22, _infoBarBuf);
+ int offset = (_flagsTable[143] == 0) ? 57688 : 46168;
+ drawStringAlt(_locationBackgroundGfxBuf + offset, color, &_infoBarBuf[pos]);
+ Graphics::drawStringChar(_locationBackgroundGfxBuf + offset + 5760, 62, 640, color, _charsetGfxBuf);
+ if (_flagsTable[143] != 0) {
+ pos = getPositionForLine(_flagsTable[143] * 2 + 23, _infoBarBuf);
+ drawStringAlt(_locationBackgroundGfxBuf + offset + 11520, color, &_infoBarBuf[pos]);
+ pos = getPositionForLine(_flagsTable[143] * 2 + 24, _infoBarBuf);
+ drawStringAlt(_locationBackgroundGfxBuf + offset + 17280, color, &_infoBarBuf[pos]);
+ }
+ execData3PreUpdate_locationNum70Helper();
+ drawStringAlt(_locationBackgroundGfxBuf + offset + 5768, color, _updateLocation70String, _updateLocation70StringLen);
+}
+
+void TuckerEngine::execData3PreUpdate_locationNum70Helper() {
+ if (_lastKeyPressed != 0 && _flagsTable[143] <= 0) {
+ if (_lastKeyPressed == Common::KEYCODE_BACKSPACE || _lastKeyPressed == Common::KEYCODE_DELETE) {
+ if (_updateLocation70StringLen > 0) {
+ --_updateLocation70StringLen;
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ }
+ } else if (_lastKeyPressed == Common::KEYCODE_RETURN) {
+ _flagsTable[143] = 1;
+ _nextAction = 1;
+ _csDataLoaded = false;
+ const int pos = getPositionForLine(23, _infoBarBuf);
+ if (memcmp(&_infoBarBuf[pos + 3], _updateLocation70String, 16) != 0) {
+ _flagsTable[143] = 2;
+ }
+ const int num = (_flagsTable[143] == 1) ? 4 : 5;
+ startSound(_locationSoundsTable[num].offset, num, _locationSoundsTable[num].volume);
+ } else if (_updateLocation70StringLen < 19) {
+ uint8 chr = 0;
+ switch (_lastKeyPressed) {
+ case Common::KEYCODE_SPACE:
+ chr = 32;
+ break;
+ case Common::KEYCODE_BACKQUOTE:
+ chr = 35;
+ break;
+ case Common::KEYCODE_LEFTPAREN:
+ chr = 40;
+ break;
+ case Common::KEYCODE_RIGHTPAREN:
+ chr = 41;
+ break;
+ case Common::KEYCODE_LESS:
+ chr = 44;
+ break;
+ case Common::KEYCODE_GREATER:
+ chr = 46;
+ break;
+ case Common::KEYCODE_COLON:
+ chr = 56;
+ break;
+ case Common::KEYCODE_QUESTION:
+ chr = 92;
+ break;
+ case Common::KEYCODE_QUOTE:
+ chr = 96;
+ break;
+ default:
+ if (_lastKeyPressed >= Common::KEYCODE_a && _lastKeyPressed >= Common::KEYCODE_z) {
+ chr = 'A' + (_lastKeyPressed - Common::KEYCODE_a);
+ }
+ break;
+ }
+ startSound(_locationSoundsTable[0].offset, 0, _locationSoundsTable[0].volume);
+ if (chr > 0) {
+ _updateLocation70String[_updateLocation70StringLen] = chr;
+ ++_updateLocation70StringLen;
+ }
+ }
+ }
+}
+
+void TuckerEngine::updateSprite_locationNum71(int i) {
+ int state;
+ if (_flagsTable[155] != 6 || _flagsTable[207] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 1;
+ } else if (getRandomNumber() < 30000) {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ _spritesTable[i].updateDelay = 5;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum72(int i) {
+ int state;
+ if (_flagsTable[155] != 7 || _flagsTable[207] == 1) {
+ state = -1;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 2;
+ } else {
+ _spritesTable[i].needUpdate = 0;
+ state = 1;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum74(int i) {
+ static const uint8 stateTable[] = { 1, 3, 5, 5, 10, 16, 16 };
+ int num = _flagsTable[236] - 74;
+ if (stateTable[num] + i == 21) {
+ if (_updateLocationFlag == 0) {
+ _updateLocationFlag = 1;
+ } else {
+ _spritesTable[i].animationFrame = _spritesTable[i].firstFrame - 1;
+ _spritesTable[i].updateDelay = 5;
+ _updateSpriteFlag1 = 1;
+ }
+ }
+ _spritesTable[i].state = stateTable[num] + i;
+}
+
+void TuckerEngine::updateSprite_locationNum79(int i) {
+ int state;
+ if (_flagsTable[227] == 0) {
+ state = 1;
+ _flagsTable[227] = 1;
+ } else if (_flagsTable[227] == 1 && _charSpeechSoundCounter > 0) {
+ state = 2;
+ _spritesTable[i].needUpdate = 1;
+ } else if (_flagsTable[227] == 2) {
+ state = 3;
+ _flagsTable[227] = 3;
+ _spritesTable[i].needUpdate = 1;
+ } else {
+ _spritesTable[i].animationFrame = _spritesTable[i].firstFrame - 1;
+ _spritesTable[i].updateDelay = 5;
+ _updateSpriteFlag1 = 1;
+ state = 3;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum81_0(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == i) {
+ _spritesTable[i].needUpdate = 1;
+ state = 3;
+ _flagsTable[288] = 1;
+ } else if (_flagsTable[288] < 2) {
+ _spritesTable[i].needUpdate = 0;
+ state = 2;
+ if (_flagsTable[288] == 1) {
+ _flagsTable[288] = 2;
+ }
+ } else {
+ _spritesTable[i].animationFrame = _spritesTable[i].firstFrame - 1;
+ _spritesTable[i].updateDelay = 5;
+ _updateSpriteFlag1 = 1;
+ state = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+void TuckerEngine::updateSprite_locationNum81_1(int i) {
+ _spritesTable[i].state = 1;
+}
+
+void TuckerEngine::updateSprite_locationNum82(int i) {
+ int state;
+ if (_charSpeechSoundCounter > 0) {
+ state = 1;
+ _flagsTable[229] = 1;
+ _spritesTable[i].needUpdate = 1;
+ } else if (_flagsTable[229] == 0) {
+ state = 1;
+ } else if (_flagsTable[229] == 1) {
+ state = 2;
+ _flagsTable[229] = 2;
+ _spritesTable[i].needUpdate = 0;
+ } else {
+ _spritesTable[i].animationFrame = _spritesTable[i].firstFrame - 1;
+ _spritesTable[i].updateDelay = 5;
+ _updateSpriteFlag1 = 1;
+ state = 2;
+ }
+ _spritesTable[i].state = state;
+}
+
+} // namespace Tucker
diff --git a/engines/tucker/module.mk b/engines/tucker/module.mk
new file mode 100644
index 0000000000..4847fdc3ec
--- /dev/null
+++ b/engines/tucker/module.mk
@@ -0,0 +1,19 @@
+MODULE := engines/tucker
+
+MODULE_OBJS := \
+ detection.o \
+ graphics.o \
+ locations.o \
+ resource.o \
+ saveload.o \
+ sequences.o \
+ staticres.o \
+ tucker.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_TUCKER), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/tucker/resource.cpp b/engines/tucker/resource.cpp
new file mode 100644
index 0000000000..eb12741b4b
--- /dev/null
+++ b/engines/tucker/resource.cpp
@@ -0,0 +1,959 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/file.h"
+
+#include "sound/audiostream.h"
+#include "sound/flac.h"
+#include "sound/mp3.h"
+#include "sound/vorbis.h"
+#include "sound/wave.h"
+
+#include "tucker/tucker.h"
+#include "tucker/graphics.h"
+
+namespace Tucker {
+
+enum {
+ kCurrentCompressedSoundDataVersion = 1,
+ kCompressedSoundDataFileHeaderSize = 4
+};
+
+struct CompressedSoundFile {
+ const char *filename;
+ Audio::AudioStream *(*makeStream)(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 startTime, uint32 duration, uint numLoops);
+};
+
+static const CompressedSoundFile compressedSoundFilesTable[] = {
+#ifdef USE_FLAC
+ { "TUCKER.SOF", Audio::makeFlacStream },
+#endif
+#ifdef USE_VORBIS
+ { "TUCKER.SOG", Audio::makeVorbisStream },
+#endif
+#ifdef USE_MAD
+ { "TUCKER.SO3", Audio::makeMP3Stream },
+#endif
+ { 0, 0 }
+};
+
+static void decodeData(uint8 *data, int dataSize) {
+ for (int i = 0; i < dataSize; ++i) {
+ data[i] -= 0x80;
+ }
+}
+
+static void stripData(uint8 *data, int dataSize) {
+ bool clearChr = false;
+ for (int i = 0; i < dataSize; ++i) {
+ if (!clearChr && data[i] == '/') {
+ clearChr = true;
+ }
+ if (clearChr) {
+ if (data[i] == '\n') {
+ clearChr = false;
+ }
+ data[i] = ' ';
+ }
+ }
+}
+
+enum DataToken {
+ kDataTokenDw,
+ kDataTokenEx
+};
+
+class DataTokenizer {
+public:
+
+ DataTokenizer(uint8 *data, int dataSize, bool stripComments = false)
+ : _data(data), _dataSize(dataSize), _pos(0) {
+ if (stripComments) {
+ stripData(_data, _dataSize);
+ }
+ }
+
+ int getNextInteger() {
+ bool negate = false;
+ int state = 0;
+ int num = 0;
+ while (_pos < _dataSize && state != 2) {
+ switch (state) {
+ case 0:
+ if (_data[_pos] == '-') {
+ state = 1;
+ negate = true;
+ } else if (_data[_pos] >= '0' && _data[_pos] <= '9') {
+ state = 1;
+ num = _data[_pos] - '0';
+ }
+ break;
+ case 1:
+ if (_data[_pos] >= '0' && _data[_pos] <= '9') {
+ num *= 10;
+ num += _data[_pos] - '0';
+ } else {
+ state = 2;
+ }
+ break;
+ }
+ ++_pos;
+ }
+ return negate ? -num : num;
+ }
+
+ bool findNextToken(DataToken t) {
+ const char *token = 0;
+ switch (t) {
+ case kDataTokenDw:
+ token = "dw";
+ break;
+ case kDataTokenEx:
+ token = "!!";
+ break;
+ }
+ int tokenLen = strlen(token);
+ while (_pos < _dataSize - tokenLen) {
+ if (memcmp(_data + _pos, token, tokenLen) == 0) {
+ _pos += tokenLen;
+ return true;
+ }
+ ++_pos;
+ }
+ return false;
+ }
+
+ bool findIndex(int num) {
+ int i = -1;
+ while (findNextToken(kDataTokenEx)) {
+ i = getNextInteger();
+ if (i >= num) {
+ break;
+ }
+ }
+ return i == num;
+ }
+
+ uint8 *_data;
+ int _dataSize;
+ int _pos;
+};
+
+uint8 *TuckerEngine::loadFile(uint8 *p) {
+ _fileLoadSize = 0;
+ if (_useEnc) {
+ char *ext = strrchr(_fileToLoad, '.');
+ if (ext && strcmp(ext + 1, "c") == 0) {
+ strcpy(ext + 1, "enc");
+ }
+ }
+ Common::File f;
+ if (!f.open(_fileToLoad)) {
+ return 0;
+ }
+ const int sz = f.size();
+ if (!p) {
+ p = (uint8 *)malloc(sz);
+ }
+ if (p) {
+ f.read(p, sz);
+ if (_useEnc) {
+ decodeData(p, sz);
+ }
+ _fileLoadSize = sz;
+ }
+ return p;
+}
+
+void TuckerEngine::openCompressedSoundFile() {
+ _compressedSoundType = -1;
+ for (int i = 0; compressedSoundFilesTable[i].filename; ++i) {
+ if (_fCompressedSound.open(compressedSoundFilesTable[i].filename)) {
+ int version = _fCompressedSound.readUint16LE();
+ if (version == kCurrentCompressedSoundDataVersion) {
+ _compressedSoundType = i;
+ return;
+ }
+ warning("Unhandled version %d for compressed sound file '%s'", version, compressedSoundFilesTable[i].filename);
+ }
+ }
+ _fCompressedSound.readUint32LE();
+}
+
+void TuckerEngine::loadImage(uint8 *dst, int type) {
+ int count = 0;
+ Common::File f;
+ if (!f.open(_fileToLoad)) {
+ return;
+ }
+ f.seek(128, SEEK_SET);
+ int size = 0;
+ while (size < 64000) {
+ if (type == 2) {
+ ++count;
+ if (count > 500) {
+ count = 0;
+ isSpeechSoundPlaying();
+ }
+ }
+ int code = f.readByte();
+ if (code >= 0xC0) {
+ const int sz = code - 0xC0;
+ code = f.readByte();
+ memset(dst + size, code, sz);
+ size += sz;
+ } else {
+ dst[size++] = code;
+ }
+ }
+ if (type != 0) {
+ f.seek(-768, SEEK_END);
+ for (int i = 0; i < 256; ++i) {
+ if (type == 2) {
+ isSpeechSoundPlaying();
+ }
+ for (int c = 0; c < 3; ++c) {
+ _currentPalette[3 * i + c] = f.readByte();
+ }
+ }
+ setBlackPalette();
+ }
+}
+
+void TuckerEngine::loadCursor() {
+ strcpy(_fileToLoad, "pointer.pcx");
+ loadImage(_loadTempBuf, 0);
+ for (int cursor = 0; cursor < 7; ++cursor) {
+ Graphics::encodeRAW(_loadTempBuf + cursor * 320 * 16, _cursorGfxBuf + cursor * 256, 16, 16);
+ }
+}
+
+void TuckerEngine::loadCharset() {
+ strcpy(_fileToLoad, "charset.pcx");
+ loadImage(_loadTempBuf, 0);
+ loadCharsetHelper(kCharSet1CharW, kCharSet1CharH, 32, 7);
+}
+
+void TuckerEngine::loadCharset2() {
+ _charWidthTable[58] = 7;
+ _charWidthTable[32] = 15;
+ for (int i = 0; i < 58; ++i) {
+ _charWidthTable[65 + i] = _charWidthCharset2[i];
+ }
+ strcpy(_fileToLoad, "char2.pcx");
+ loadImage(_loadTempBuf, 0);
+ loadCharsetHelper(kCharSet2CharW, kCharSet2CharH, 16, 6);
+}
+
+void TuckerEngine::loadCharsetHelper(int charW, int charH, int xSize, int ySize) {
+ int offset = 0;
+ for (int y = 0; y < ySize; ++y) {
+ for (int x = 0; x < xSize; ++x) {
+ offset += Graphics::encodeRAW(_loadTempBuf + (y * 320) * charH + x * charW, _charsetGfxBuf + offset, charW, charH);
+ }
+ }
+}
+
+void TuckerEngine::loadCharSizeDta() {
+ strcpy(_fileToLoad, "charsize.dta");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize, true);
+ for (int i = 0; i < 256; ++i) {
+ _charWidthTable[i] = t.getNextInteger();
+ }
+ _charWidthTable[225] = 0;
+}
+
+void TuckerEngine::loadPanel() {
+ strcpy(_fileToLoad, (_panelNum == 0) ? "panel1.pcx" : "panel2.pcx");
+ loadImage(_panelGfxBuf, 0);
+}
+
+void TuckerEngine::loadBudSpr(int startOffset) {
+ int endOffset;
+ loadCTable01(0, startOffset, endOffset);
+ loadCTable02(0);
+ int frame = 0;
+ int spriteOffset = 0;
+ for (int i = startOffset; i < endOffset; ++i) {
+ if (_ctable01Table_sprite[frame] == i) {
+ switch (_flagsTable[137]) {
+ case 0:
+ sprintf(_fileToLoad, "bud_%d.pcx", frame + 1);
+ break;
+ case 1:
+ sprintf(_fileToLoad, "peg_%d.pcx", frame + 1);
+ break;
+ default:
+ sprintf(_fileToLoad, "mac_%d.pcx", frame + 1);
+ break;
+ }
+ loadImage(_loadTempBuf, 0);
+ ++frame;
+ }
+ int sz = Graphics::encodeRLE(_loadTempBuf + _spriteFramesTable[i].sourceOffset, _spritesGfxBuf + spriteOffset, _spriteFramesTable[i].xSize, _spriteFramesTable[i].ySize);
+ _spriteFramesTable[i].sourceOffset = spriteOffset;
+ spriteOffset += sz;
+ }
+}
+
+void TuckerEngine::loadCTable01(int locationNum, int firstSpriteNum, int &lastSpriteNum) {
+ strcpy(_fileToLoad, "ctable01.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ lastSpriteNum = firstSpriteNum;
+ int count = 0;
+ if (t.findIndex(_locationNum)) {
+ while (t.findNextToken(kDataTokenDw)) {
+ const int x = t.getNextInteger();
+ if (x < 0) {
+ break;
+ } else if (x == 999) {
+ _ctable01Table_sprite[count] = lastSpriteNum;
+ ++count;
+ continue;
+ }
+ const int y = t.getNextInteger();
+ SpriteFrame *c = &_spriteFramesTable[lastSpriteNum++];
+ c->sourceOffset = y * 320 + x;
+ c->xSize = t.getNextInteger();
+ c->ySize = t.getNextInteger();
+ c->xOffset = t.getNextInteger();
+ if (c->xOffset > 300) {
+ c->xOffset -= 500;
+ }
+ c->yOffset = t.getNextInteger();
+ if (c->yOffset > 300) {
+ c->yOffset -= 500;
+ }
+ }
+ }
+ _ctable01Table_sprite[count] = -1;
+}
+
+void TuckerEngine::loadCTable02(int fl) {
+ assert(fl == 0);
+ int entry = 0;
+ int i = 0;
+ strcpy(_fileToLoad, "ctable02.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ while (t.findNextToken(kDataTokenDw)) {
+ _spriteAnimationsTable[entry].numParts = t.getNextInteger();
+ if (_spriteAnimationsTable[entry].numParts < 1) {
+ return;
+ }
+ _spriteAnimationsTable[entry].rotateFlag = t.getNextInteger();
+ int num = t.getNextInteger();
+ if (num != fl) {
+ continue;
+ }
+ int start = 0;
+ _spriteAnimationsTable[entry].firstFrameIndex = i;
+ while (start != 999) {
+ start = t.getNextInteger();
+ _spriteAnimationFramesTable[i] = start;
+ ++i;
+ }
+ ++entry;
+ }
+}
+
+void TuckerEngine::loadLoc() {
+ int i = _locationWidthTable[_locationNum];
+ _locationHeight = (_locationNum < 73) ? 140 : 200;
+ strcpy(_fileToLoad, (i == 1) ? "loc00.pcx" : "loc00a.pcx");
+ copyLocBitmap(0, 0);
+ Graphics::copyFrom640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf, 320, _locationHeight);
+ if (_locationHeight == 200) {
+ return;
+ }
+ strcpy(_fileToLoad, (i != 2) ? "path00.pcx" : "path00a.pcx");
+ copyLocBitmap(0, 1);
+ if (i > 1) {
+ strcpy(_fileToLoad, "loc00b.pcx");
+ copyLocBitmap(320, 0);
+ Graphics::copyFrom640(_locationBackgroundGfxBuf + 320, _quadBackgroundGfxBuf + 44800, 320, 140);
+ if (i == 2) {
+ strcpy(_fileToLoad, "path00b.pcx");
+ copyLocBitmap(320, 1);
+ }
+ }
+ if (i > 2) {
+ strcpy(_fileToLoad, "loc00c.pcx");
+ copyLocBitmap(0, 0);
+ Graphics::copyFrom640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf + 89600, 320, 140);
+ }
+ if (_locationNum == 1) {
+ strcpy(_fileToLoad, "rochpath.pcx");
+ _loadLocBufPtr = _quadBackgroundGfxBuf + 89600;
+ loadImage(_loadLocBufPtr, 0);
+ }
+ if (i > 3) {
+ strcpy(_fileToLoad, "loc00d.pcx");
+ copyLocBitmap(0, 0);
+ Graphics::copyFrom640(_locationBackgroundGfxBuf + 320, _quadBackgroundGfxBuf + 134400, 320, 140);
+ }
+}
+
+void TuckerEngine::loadObj() {
+ if (_locationNum == 99) {
+ return;
+ }
+ if (_locationNum < 24) {
+ _partNum = 1;
+ _speechSoundBaseNum = 2639;
+ } else if (_locationNum < 41 || (_locationNum >= 69 && _locationNum < 73) || (_locationNum > 79 && _locationNum < 83)) {
+ _partNum = 2;
+ _speechSoundBaseNum = 2679;
+ } else {
+ _partNum = 3;
+ _speechSoundBaseNum = 2719;
+ }
+ if (_partNum == _currentPartNum) {
+ return;
+ }
+ handleNewPartSequence();
+ _currentPartNum = _partNum;
+
+ sprintf(_fileToLoad, "objtxt%d.c", _partNum);
+ free(_objTxtBuf);
+ _objTxtBuf = loadFile();
+ sprintf(_fileToLoad, "pt%dtext.c", _partNum);
+ free(_ptTextBuf);
+ _ptTextBuf = loadFile();
+
+ loadData();
+ loadPanObj();
+}
+
+void TuckerEngine::loadData() {
+ int flag = 0;
+ int objNum = _partNum * 10;
+ strcpy(_fileToLoad, "data.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ _dataCount = 0;
+ int count = 0;
+ int maxCount = 0;
+ while (flag < 2) {
+ flag = 0;
+ if (!t.findIndex(objNum)) {
+ flag = 2;
+ }
+ while (flag == 0) {
+ if (!t.findNextToken(kDataTokenDw)) {
+ flag = 1;
+ continue;
+ }
+ _dataCount = t.getNextInteger();
+ if (_dataCount < 0) {
+ flag = 1;
+ continue;
+ }
+ if (_dataCount > maxCount) {
+ maxCount = _dataCount;
+ }
+ const int x = t.getNextInteger();
+ const int y = t.getNextInteger();
+ _dataTable[_dataCount].sourceOffset = y * 320 + x;
+ _dataTable[_dataCount].xSize = t.getNextInteger();
+ _dataTable[_dataCount].ySize = t.getNextInteger();
+ _dataTable[_dataCount].xDest = t.getNextInteger();
+ _dataTable[_dataCount].yDest = t.getNextInteger();
+ _dataTable[_dataCount].index = count;
+ }
+ if (flag < 2) {
+ ++objNum;
+ ++count;
+ }
+ }
+ _dataCount = maxCount;
+ int offset = 0;
+ for (int i = 0; i < count; ++i) {
+ sprintf(_fileToLoad, "scrobj%d%d.pcx", _partNum, i);
+ loadImage(_loadTempBuf, 0);
+ offset = loadDataHelper(offset, i);
+ }
+}
+
+int TuckerEngine::loadDataHelper(int offset, int index) {
+ for (int i = 0; i < _dataCount + 1; ++i) {
+ if (_dataTable[i].index == index) {
+ int sz = Graphics::encodeRLE(_loadTempBuf + _dataTable[i].sourceOffset, _data3GfxBuf + offset, _dataTable[i].xSize, _dataTable[i].ySize);
+ _dataTable[i].sourceOffset = offset;
+ offset += sz;
+ }
+ }
+ return offset;
+}
+
+void TuckerEngine::loadPanObj() {
+ sprintf(_fileToLoad, "panobjs%d.pcx", _partNum);
+ loadImage(_loadTempBuf, 0);
+ int offset = 0;
+ for (int y = 0; y < 5; ++y) {
+ for (int x = 0; x < 10; ++x) {
+ const int i = y * 10 + x;
+ _panelObjectsOffsetTable[i] = offset;
+ offset += Graphics::encodeRLE(_loadTempBuf + (y * 240 + x) * 32, _panelObjectsGfxBuf + offset, 32, 24);
+ }
+ }
+}
+
+void TuckerEngine::loadData3() {
+ strcpy(_fileToLoad, "data3.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ _locationAnimationsCount = 0;
+ if (t.findIndex(_locationNum)) {
+ while (t.findNextToken(kDataTokenDw)) {
+ int num = t.getNextInteger();
+ if (num < 0) {
+ break;
+ }
+ assert(_locationAnimationsCount < kLocationAnimationsTableSize);
+ LocationAnimation *d = &_locationAnimationsTable[_locationAnimationsCount++];
+ d->graphicNum = num;
+ const int seqNum = t.getNextInteger();
+ int i = 0;
+ int j = 1;
+ if (seqNum > 0) {
+ while (j < seqNum) {
+ while (_staticData3Table[i] != 999) {
+ ++i;
+ }
+ ++i;
+ ++j;
+ }
+ d->animCurrentCounter = d->animInitCounter = i;
+ while (_staticData3Table[i + 1] != 999) {
+ ++i;
+ }
+ d->animLastCounter = i;
+ } else {
+ d->animLastCounter = 0;
+ }
+ d->getFlag = t.getNextInteger();
+ d->inventoryNum = t.getNextInteger();
+ d->flagNum = t.getNextInteger();
+ d->flagValue = t.getNextInteger();
+ d->selectable = t.getNextInteger();
+ d->standX = t.getNextInteger();
+ d->standY = t.getNextInteger();
+ d->drawFlag = 0;
+ }
+ }
+}
+
+void TuckerEngine::loadData4() {
+ strcpy(_fileToLoad,"data4.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ t.findNextToken(kDataTokenDw);
+ _data4FlagDebug = t.getNextInteger();
+ _displayGameHints = t.getNextInteger();
+ // forces game hints feature
+// _displayGameHints = 1;
+ _locationObjectsCount = 0;
+ if (t.findIndex(_locationNum)) {
+ while (t.findNextToken(kDataTokenDw)) {
+ int i = t.getNextInteger();
+ if (i < 0) {
+ break;
+ }
+ assert(_locationObjectsCount < kLocationObjectsTableSize);
+ LocationObject *d = &_locationObjectsTable[_locationObjectsCount++];
+ d->xPos = i;
+ d->yPos = t.getNextInteger();
+ d->xSize = t.getNextInteger();
+ d->ySize = t.getNextInteger();
+ d->standX = t.getNextInteger();
+ d->standY = t.getNextInteger();
+ d->textNum = t.getNextInteger();
+ d->cursorNum = t.getNextInteger();
+ d->locationNum = t.getNextInteger();
+ if (d->locationNum > 0) {
+ d->toX = t.getNextInteger();
+ d->toY = t.getNextInteger();
+ d->toX2 = t.getNextInteger();
+ d->toY2 = t.getNextInteger();
+ d->toWalkX2 = t.getNextInteger();
+ d->toWalkY2 = t.getNextInteger();
+ }
+ }
+ }
+}
+
+void TuckerEngine::loadActionFile() {
+ switch (_partNum) {
+ case 1:
+ strcpy(_fileToLoad, "action1.c");
+ break;
+ case 2:
+ strcpy(_fileToLoad, "action2.c");
+ break;
+ default:
+ strcpy(_fileToLoad, "action3.c");
+ break;
+ }
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ _actionsCount = 0;
+ if (t.findIndex(_locationNum)) {
+ while (t.findNextToken(kDataTokenDw)) {
+ int keyA = t.getNextInteger();
+ if (keyA < 0) {
+ break;
+ }
+ int keyB = t.getNextInteger();
+ int keyC = t.getNextInteger();
+ int keyD = t.getNextInteger();
+ int keyE = t.getNextInteger();
+ Action *action = &_actionsTable[_actionsCount++];
+ action->key = keyE * 1000000 + keyD * 100000 + keyA * 10000 + keyB * 1000 + keyC;
+ action->testFlag1Num = t.getNextInteger();
+ action->testFlag1Value = t.getNextInteger();
+ action->testFlag2Num = t.getNextInteger();
+ action->testFlag2Value = t.getNextInteger();
+ action->speech = t.getNextInteger();
+ action->flipX = t.getNextInteger();
+ action->index = t.getNextInteger();
+ action->delay = t.getNextInteger();
+ action->setFlagNum = t.getNextInteger();
+ action->setFlagValue = t.getNextInteger();
+ action->fxNum = t.getNextInteger();
+ action->fxDelay = t.getNextInteger();
+ }
+ }
+}
+
+void TuckerEngine::loadCharPos() {
+ strcpy(_fileToLoad, "charpos.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ _charPosCount = 0;
+ if (t.findIndex(_locationNum)) {
+ while (t.findNextToken(kDataTokenDw)) {
+ const int i = t.getNextInteger();
+ if (i < 0) {
+ break;
+ }
+ assert(_charPosCount < 4);
+ CharPos *charPos = &_charPosTable[_charPosCount++];
+ charPos->xPos = i;
+ charPos->yPos = t.getNextInteger();
+ charPos->xSize = t.getNextInteger();
+ charPos->ySize = t.getNextInteger();
+ charPos->xWalkTo = t.getNextInteger();
+ charPos->yWalkTo = t.getNextInteger();
+ charPos->flagNum = t.getNextInteger();
+ charPos->flagValue = t.getNextInteger();
+ charPos->direction = t.getNextInteger();
+ charPos->name = t.getNextInteger();
+ charPos->description = t.getNextInteger();
+ }
+ }
+ int quitLoop = 0;
+ size_t count = 0;
+ while (quitLoop == 0) {
+ t.findNextToken(kDataTokenDw);
+ int num = 0;
+ while (num != 99) {
+ num = t.getNextInteger();
+ assert(count < ARRAYSIZE(_characterAnimationsTable));
+ _characterAnimationsTable[count] = num;
+ if (num < 0) {
+ quitLoop = 1;
+ break;
+ }
+ ++count;
+ }
+ }
+ quitLoop = 0;
+ count = 0;
+ while (quitLoop == 0) {
+ t.findNextToken(kDataTokenDw);
+ int num = 0;
+ while (num < 98) {
+ num = t.getNextInteger();
+ assert(count < ARRAYSIZE(_characterStateTable));
+ _characterStateTable[count] = num;
+ if (num == 98) {
+ --count;
+ }
+ if (num < 0) {
+ quitLoop = 1;
+ break;
+ }
+ ++count;
+ }
+ }
+}
+
+void TuckerEngine::loadSprA02_01() {
+ for (int i = 1; i < kSprA02TableSize; ++i) {
+ free(_sprA02Table[i]);
+ _sprA02Table[i] = 0;
+ }
+ const int count = _sprA02LookupTable[_locationNum];
+ for (int i = 1; i < count + 1; ++i) {
+ sprintf(_fileToLoad, "sprites/a%02d_%02d.spr", _locationNum, i);
+ _sprA02Table[i] = loadFile();
+ }
+ _sprA02Table[0] = _sprA02Table[1];
+}
+
+void TuckerEngine::loadSprC02_01() {
+ for (int i = 1; i < kSprC02TableSize; ++i) {
+ free(_sprC02Table[i]);
+ _sprC02Table[i] = 0;
+ }
+ const int count = _sprC02LookupTable[_locationNum];
+ for (int i = 1; i < count + 1; ++i) {
+ sprintf(_fileToLoad, "sprites/c%02d_%02d.spr", _locationNum, i);
+ _sprC02Table[i] = loadFile();
+ }
+ _sprC02Table[0] = _sprC02Table[1];
+ _spritesCount = _sprC02LookupTable2[_locationNum];
+ for (int i = 0; i < kMaxCharacters; ++i) {
+ memset(&_spritesTable[i], 0, sizeof(Sprite));
+ _spritesTable[i].state = -1;
+ _spritesTable[i].stateIndex = -1;
+ }
+}
+
+void TuckerEngine::loadFx() {
+ strcpy(_fileToLoad, "fx.c");
+ loadFile(_loadTempBuf);
+ DataTokenizer t(_loadTempBuf, _fileLoadSize);
+ 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) {
+ _currentFxSet = 1;
+ _currentFxIndex = i;
+ _currentFxVolume = _locationSoundsTable[i].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();
+ }
+ }
+ if (_locationSoundsTable[i].type == 8) {
+ _locationSoundsTable[i].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;
+ } else {
+ for (int j = 0; j < 3; ++j) {
+ t.getNextInteger();
+ }
+ }
+ }
+}
+
+void TuckerEngine::loadSound(Audio::Mixer::SoundType type, int num, int volume, bool loop, Audio::SoundHandle *handle) {
+ Audio::AudioStream *stream = 0;
+ if (_compressedSoundType < 0) {
+ const char *fmt = 0;
+ switch (type) {
+ case Audio::Mixer::kSFXSoundType:
+ fmt = "fx/fx%d.wav";
+ break;
+ case Audio::Mixer::kMusicSoundType:
+ fmt = "music/mus%d.wav";
+ break;
+ case Audio::Mixer::kSpeechSoundType:
+ fmt = "speech/sam%04d.wav";
+ break;
+ default:
+ return;
+ }
+ char fileName[64];
+ snprintf(fileName, sizeof(fileName), fmt, num);
+ Common::File f;
+ if (f.open(fileName)) {
+ int size, rate;
+ uint8 flags = 0;
+ if (Audio::loadWAVFromStream(f, size, rate, flags)) {
+ uint8 *data = (uint8 *)malloc(size);
+ if (data) {
+ f.read(data, size);
+ flags |= Audio::Mixer::FLAG_AUTOFREE;
+ if (loop) {
+ flags |= Audio::Mixer::FLAG_LOOP;
+ }
+ stream = Audio::makeLinearInputStream(data, size, rate, flags, 0, 0);
+ }
+ }
+ }
+ } else {
+ int offset = 0;
+ switch (type) {
+ case Audio::Mixer::kSFXSoundType:
+ offset = kCompressedSoundDataFileHeaderSize;
+ break;
+ case Audio::Mixer::kMusicSoundType:
+ offset = kCompressedSoundDataFileHeaderSize + 8;
+ break;
+ case Audio::Mixer::kSpeechSoundType:
+ offset = kCompressedSoundDataFileHeaderSize + 16;
+ break;
+ default:
+ return;
+ }
+ _fCompressedSound.seek(offset);
+ int dirOffset = _fCompressedSound.readUint32LE();
+ int dirSize = _fCompressedSound.readUint32LE();
+ if (num < dirSize) {
+ dirOffset += kCompressedSoundDataFileHeaderSize + 3 * 8;
+ _fCompressedSound.seek(dirOffset + num * 8);
+ int soundOffset = _fCompressedSound.readUint32LE();
+ int soundSize = _fCompressedSound.readUint32LE();
+ if (soundSize != 0) {
+ _fCompressedSound.seek(dirOffset + dirSize * 8 + soundOffset);
+ Common::MemoryReadStream *tmp = _fCompressedSound.readStream(soundSize);
+ if (tmp) {
+ stream = (compressedSoundFilesTable[_compressedSoundType].makeStream)(tmp, true, 0, 0, 1);
+ }
+ }
+ }
+ }
+ if (stream) {
+ _mixer->playInputStream(type, handle, stream, -1, volume * Audio::Mixer::kMaxChannelVolume / kMaxSoundVolume);
+ }
+}
+
+void TuckerEngine::loadActionsTable() {
+ int table = 0;
+ do {
+ if (!_csDataLoaded) {
+ DataTokenizer t(_csDataBuf, _csDataSize);
+ bool found = t.findIndex(_locationNum);
+ assert(found);
+ for (int i = 0; i < _nextAction; ++i) {
+ found = t.findNextToken(kDataTokenDw);
+ assert(found);
+ }
+ _forceRedrawPanelItems = 1;
+ _panelState = 1;
+ setCursorType(2);
+ _tableInstructionsPtr = _csDataBuf + t._pos + 1;
+ _csDataLoaded = true;
+ _csDataHandled = 1;
+ }
+ if (_csDataTableFlag2 == 1 && _charSpeechSoundCounter > 0) {
+ break;
+ }
+ _csDataTableFlag2 = 0;
+ if (_stopActionOnPanelLock == 1) {
+ if (_panelLockedFlag) {
+ break;
+ }
+ _stopActionOnPanelLock = 0;
+ }
+ if (_stopActionCounter > 0) {
+ --_stopActionCounter;
+ break;
+ }
+ if (_stopActionOnSoundFlag != 0) {
+ if (isSoundPlaying(_soundInstructionIndex)) {
+ break;
+ }
+ _stopActionOnSoundFlag = 0;
+ }
+ if (_csDataTableCount != 0) {
+ if (_csDataTableCount == 99) {
+ if (_backgroundSpriteCurrentAnimation > -1) {
+ if (_backgroundSpriteCurrentFrame != _backgroundSpriteLastFrame) {
+ break;
+ }
+ _csDataTableCount = 0;
+ } else {
+ if (_spriteAnimationFramesTable[_spriteAnimationFrameIndex] != 999) {
+ break;
+ }
+ _csDataTableCount = 0;
+ }
+ } else {
+ if (_spritesTable[_csDataTableCount - 1].firstFrame - 1 != _spritesTable[_csDataTableCount - 1].animationFrame) {
+ break;
+ }
+ _csDataTableCount = 0;
+ }
+ }
+ if (_conversationOptionsCount != 0) {
+ if (_mouseButtons != 0 && _nextTableToLoadIndex != -1) {
+ _nextAction = _nextTableToLoadTable[_nextTableToLoadIndex];
+ _csDataLoaded = false;
+ _conversationOptionsCount = 0;
+ setCursorType(2);
+ }
+ break;
+ }
+ table = 0;
+ while (table == 0) {
+ table = parseTableInstruction();
+ }
+ } while (table == 3);
+ if (table == 2) {
+ _nextAction = 0;
+ _csDataLoaded = false;
+ _forceRedrawPanelItems = 1;
+ _panelState = 0;
+ setCursorType(0);
+ _csDataHandled = 0;
+ _skipPanelObjectUnderCursor = 0;
+ _mouseClick = 1;
+ }
+}
+
+} // namespace Tucker
diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp
new file mode 100644
index 0000000000..145c86ef18
--- /dev/null
+++ b/engines/tucker/saveload.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/savefile.h"
+
+#include "tucker/tucker.h"
+
+namespace Tucker {
+
+enum {
+ kCurrentGameStateVersion = 1
+};
+
+void TuckerEngine::generateGameStateFileName(int num, char *dst, int len, bool prefixOnly) const {
+ if (prefixOnly) {
+ snprintf(dst, len, "%s.*", _targetName.c_str());
+ } else {
+ snprintf(dst, len, "%s.%d", _targetName.c_str(), num);
+ }
+ dst[len] = 0;
+}
+
+static void saveOrLoadInt(Common::WriteStream &stream, int &i) {
+ stream.writeSint32LE(i);
+}
+
+static void saveOrLoadInt(Common::ReadStream &stream, int &i) {
+ i = stream.readSint32LE();
+}
+
+template <class S>
+void TuckerEngine::saveOrLoadGameStateData(S &s) {
+ for (int i = 0; i < 300; ++i) {
+ saveOrLoadInt(s, _flagsTable[i]);
+ }
+ for (int i = 0; i < 40; ++i) {
+ saveOrLoadInt(s, _inventoryObjectsList[i]);
+ }
+ for (int i = 0; i < 50; ++i) {
+ saveOrLoadInt(s, _inventoryItemsState[i]);
+ }
+ for (int i = 0; i < 50; ++i) {
+ saveOrLoadInt(s, _panelObjectsOffsetTable[i]);
+ }
+ saveOrLoadInt(s, _mainSpritesBaseOffset);
+ saveOrLoadInt(s, _selectedObject.xPos);
+ saveOrLoadInt(s, _selectedObject.yPos);
+ saveOrLoadInt(s, _locationNum);
+ saveOrLoadInt(s, _xPosCurrent);
+ saveOrLoadInt(s, _yPosCurrent);
+ saveOrLoadInt(s, _inventoryObjectsCount);
+ saveOrLoadInt(s, _inventoryObjectsOffset);
+}
+
+void TuckerEngine::loadGame(int slot) {
+ char gameStateFileName[64];
+ generateGameStateFileName(slot, gameStateFileName, 63);
+ Common::InSaveFile *f = _saveFileMan->openForLoading(gameStateFileName);
+ if (f) {
+ uint16 version = f->readUint16LE();
+ if (version < kCurrentGameStateVersion) {
+ warning("Unsupported gamestate version %d (slot %d)", version, slot);
+ } else {
+ f->skip(2);
+ saveOrLoadGameStateData(*f);
+ if (f->ioFailed()) {
+ warning("Can't read file '%s'", gameStateFileName);
+ } else {
+ _nextLocationNum = _locationNum;
+ setBlackPalette();
+ loadBudSpr(0);
+ }
+ }
+ delete f;
+ }
+}
+
+void TuckerEngine::saveGame(int slot) {
+ char gameStateFileName[64];
+ generateGameStateFileName(slot, gameStateFileName, 63);
+ Common::OutSaveFile *f = _saveFileMan->openForSaving(gameStateFileName);
+ if (f) {
+ f->writeUint16LE(kCurrentGameStateVersion);
+ f->writeUint16LE(0);
+ saveOrLoadGameStateData(*f);
+ f->finalize();
+ if (f->ioFailed()) {
+ warning("Can't write file '%s'", gameStateFileName);
+ }
+ delete f;
+ }
+}
+
+} // namespace Tucker
diff --git a/engines/tucker/sequences.cpp b/engines/tucker/sequences.cpp
new file mode 100644
index 0000000000..780f3c694d
--- /dev/null
+++ b/engines/tucker/sequences.cpp
@@ -0,0 +1,480 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tucker/tucker.h"
+#include "tucker/graphics.h"
+
+namespace Tucker {
+
+void TuckerEngine::handleCreditsSequence() {
+ static const int _creditsSequenceData1[] = { 200, 350, 650, 850, 1150, 1450, 12000 };
+ static const int _creditsSequenceData2[] = { 1, 1, 5, 0, 6, 6, 0 };
+ int counter4 = 0;
+ int counter3 = 0;
+ int num = 0;
+ int imgNum = 0;
+ int prevLocationNum = _locationNum;
+ int counter2 = 0;
+ int counter1 = 0;
+ loadCharset2();
+ stopSounds();
+ _locationNum = 74;
+ uint8 *imgBuf = (uint8 *)malloc(16 * 64000);
+ loadSprC02_01();
+ _spritesCount = _creditsSequenceData2[num];
+ for (int i = 0; i < _spritesCount; ++i) {
+ memset(&_spritesTable[i], 0, sizeof(Sprite));
+ _spritesTable[i].state = -1;
+ _spritesTable[i].stateIndex = -1;
+ }
+ strcpy(_fileToLoad, "credits.txt");
+ loadFile(_ptTextBuf);
+ strcpy(_fileToLoad, "loc74.pcx");
+ loadImage(_quadBackgroundGfxBuf, 1);
+ startSpeechSound(9001, 120);
+ _timerCounter2 = 0;
+ _fadePaletteCounter = 0;
+ do {
+ if (_fadePaletteCounter < 16) {
+ fadeOutPalette();
+ ++_fadePaletteCounter;
+ }
+ if (counter4 + 20 > _creditsSequenceData1[num]) {
+ fadeInPalette();
+ }
+ ++imgNum;
+ if (imgNum == 16) {
+ imgNum = 0;
+ }
+ if (num < 6) {
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf, 320, 320, 200);
+ } else {
+ if (getLastKeyCode() > 0) {
+ return;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf, imgBuf + imgNum * 64000, 320, 320, 200);
+ drawString2(5, 48, counter2 * 6);
+ drawString2(5, 60, counter2 * 6 + 1);
+ drawString2(5, 80, counter2 * 6 + 2);
+ drawString2(5, 92, counter2 * 6 + 3);
+ drawString2(5, 140, counter2 * 6 + 4);
+ drawString2(5, 116, counter2 * 6 + 5);
+ ++counter1;
+ if (counter1 < 20) {
+ fadePaletteColor(191, kFadePaletteStep);
+ } else if (counter1 > 106) {
+ fadePaletteColor(191, -kFadePaletteStep);
+ }
+ if (counter1 > 116) {
+ counter1 = 0;
+ }
+ ++counter2;
+ if (counter2 > 17) {
+ counter2 = 0;
+ }
+ }
+ ++counter3;
+ if (counter3 == 2) {
+ counter3 = 0;
+ updateSprites();
+ }
+ for (int i = 0; i < _spritesCount; ++i) {
+ drawSprite(i);
+ isSpeechSoundPlaying();
+ }
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(3);
+ isSpeechSoundPlaying();
+ _timerCounter1 = 0;
+ counter4 = _timerCounter2 / 3;
+ if (counter4 == _creditsSequenceData1[num]) {
+ _fadePaletteCounter = 0;
+ _spritesCount = _creditsSequenceData2[num];
+ for (int i = 0; i < _spritesCount; ++i) {
+ memset(&_spritesTable[i], 0, sizeof(Sprite));
+ _spritesTable[i].state = -1;
+ _spritesTable[i].stateIndex = -1;
+ }
+ ++num;
+ switch (num) {
+ case 1:
+ strcpy(_fileToLoad, "loc75.pcx");
+ break;
+ case 2:
+ strcpy(_fileToLoad, "loc76.pcx");
+ break;
+ case 3:
+ strcpy(_fileToLoad, "paper-3.pcx");
+ break;
+ case 4:
+ strcpy(_fileToLoad, "loc77.pcx");
+ break;
+ case 5:
+ strcpy(_fileToLoad, "loc78.pcx");
+ break;
+ }
+ if (num == 6) {
+ for (int i = 0; i < 16; ++i) {
+ sprintf(_fileToLoad, "cogs%04d.pcx", i);
+ loadImage(imgBuf + i * 64000, 2);
+ }
+ } else {
+ loadImage(_quadBackgroundGfxBuf, 2);
+ }
+ _spritesCount = _creditsSequenceData2[num];
+ ++_flagsTable[236];
+ }
+ } while (isSpeechSoundPlaying());
+ free(imgBuf);
+ _locationNum = prevLocationNum;
+ do {
+ if (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ --_fadePaletteCounter;
+ }
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(2);
+ } while (_fadePaletteCounter > 0);
+}
+
+void TuckerEngine::handleCongratulationsSequence() {
+ _timerCounter2 = 0;
+ _fadePaletteCounter = 0;
+ stopSounds();
+ strcpy(_fileToLoad, "congrat.pcx");
+ loadImage(_loadTempBuf, 1);
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _loadTempBuf, 320, 320, 200);
+ copyToVGA(_locationBackgroundGfxBuf);
+ while (_timerCounter2 < 450) {
+ while (_fadePaletteCounter < 14) {
+ ++_fadePaletteCounter;
+ fadeOutPalette();
+ }
+ waitForTimer(3);
+ updateTimer();
+ }
+}
+
+void TuckerEngine::handleNewPartSequence() {
+ stopSounds();
+ if (_flagsTable[219] == 1) {
+ _flagsTable[219] = 0;
+ for (int i = 0; i < 50; ++i) {
+ _inventoryItemsState[i] = 0;
+ }
+ _inventoryObjectsOffset = 0;
+ _inventoryObjectsCount = 0;
+ addObjectToInventory(30);
+ if (_partNum == 1 || _partNum == 3) {
+ addObjectToInventory(1);
+ addObjectToInventory(0);
+ }
+ _redrawPanelItemsCounter = 0;
+ }
+ _scrollOffset = 0;
+ switch (_partNum) {
+ case 1:
+ strcpy(_fileToLoad, "pt1bak.pcx");
+ break;
+ case 2:
+ strcpy(_fileToLoad, "pt2bak.pcx");
+ break;
+ default:
+ strcpy(_fileToLoad, "pt3bak.pcx");
+ break;
+ }
+ loadImage(_quadBackgroundGfxBuf, 1);
+ switch (_partNum) {
+ case 1:
+ strcpy(_fileToLoad, "sprites/partone.spr");
+ break;
+ case 2:
+ strcpy(_fileToLoad, "sprites/parttwo.spr");
+ break;
+ default:
+ strcpy(_fileToLoad, "sprites/partthr.spr");
+ break;
+ }
+ _spritesCount = 1;
+ memset(&_spritesTable[0], 0, sizeof(Sprite));
+ _spritesTable[0].state = -1;
+ _spritesTable[0].stateIndex = -1;
+ int currentLocation = _locationNum;
+ _locationNum = 98;
+ for (int i = 1; i < kSprA02TableSize; ++i) {
+ free(_sprA02Table[i]);
+ _sprA02Table[i] = 0;
+ }
+ for (int i = 1; i < kSprC02TableSize; ++i) {
+ free(_sprC02Table[i]);
+ _sprC02Table[i] = 0;
+ }
+ _sprC02Table[1] = loadFile();
+ startSpeechSound(9000, 60);
+ _fadePaletteCounter = 0;
+ do {
+ if (_fadePaletteCounter < 16) {
+ fadeOutPalette();
+ ++_fadePaletteCounter;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf, 320, 320, 200);
+ updateSprites();
+ drawSprite(0);
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(3);
+ if (getLastKeyCode() > 0) {
+ stopSounds();
+ }
+ } while (isSpeechSoundPlaying());
+ do {
+ if (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ --_fadePaletteCounter;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf, 320, 320, 200);
+ updateSprites();
+ drawSprite(0);
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(3);
+ } while (_fadePaletteCounter > 0);
+ _locationNum = currentLocation;
+}
+
+void TuckerEngine::handleMeanwhileSequence() {
+ backupPalette();
+ switch (_partNum) {
+ case 1:
+ strcpy(_fileToLoad, "meanw01.pcx");
+ break;
+ case 2:
+ strcpy(_fileToLoad, "meanw02.pcx");
+ break;
+ default:
+ strcpy(_fileToLoad, "meanw03.pcx");
+ break;
+ }
+ if (_flagsTable[215] == 0 && _flagsTable[231] == 1) {
+ strcpy(_fileToLoad, "loc80.pcx");
+ }
+ loadImage(_quadBackgroundGfxBuf + 89600, 1);
+ _fadePaletteCounter = 0;
+ for (int i = 0; i < 60; ++i) {
+ if (_fadePaletteCounter < 16) {
+ fadeOutPalette();
+ ++_fadePaletteCounter;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf + 89600, 320, 320, 200);
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(3);
+ ++i;
+ }
+ do {
+ if (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ --_fadePaletteCounter;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf, _quadBackgroundGfxBuf + 89600, 320, 320, 200);
+ copyToVGA(_locationBackgroundGfxBuf);
+ waitForTimer(3);
+ } while (_fadePaletteCounter > 0);
+ restorePalette();
+}
+
+void TuckerEngine::handleMapSequence() {
+ strcpy(_fileToLoad, "map2.pcx");
+ loadImage(_quadBackgroundGfxBuf + 89600, 0);
+ strcpy(_fileToLoad, "map1.pcx");
+ loadImage(_loadTempBuf, 1);
+ _selectedObject.locationObject_locationNum = 0;
+ if (_flagsTable[7] > 0) {
+ copyMapRect(0, 0, 140, 86);
+ }
+ if (_flagsTable[7] > 1) {
+ copyMapRect(0, 60, 122, 120);
+ }
+ if (_flagsTable[7] > 2) {
+ copyMapRect(122, 114, 97, 86);
+ }
+ if (_flagsTable[7] == 4) {
+ copyMapRect(140, 0, 88, 125);
+ }
+ if (_flagsTable[120] == 1) {
+ copyMapRect(220, 0, 100, 180);
+ }
+ _fadePaletteCounter = 0;
+ int xPos, yPos, textNum = 0;
+ do {
+ waitForTimer(2);
+ updateMouseState();
+ Graphics::copyTo640(_locationBackgroundGfxBuf + _scrollOffset, _quadBackgroundGfxBuf + 89600, 320, 320, 200);
+ if (_flagsTable[7] > 0 && _mousePosX > 30 && _mousePosX < 86 && _mousePosY > 36 && _mousePosY < 86) {
+ textNum = 13;
+ _nextLocationNum = (_partNum == 1) ? 3 : 65;
+ xPos = 620;
+ yPos = 130;
+ } else if (_flagsTable[7] > 1 && _mousePosX > 60 && _mousePosX < 120 && _mousePosY > 120 && _mousePosY < 170) {
+ textNum = 14;
+ _nextLocationNum = (_partNum == 1) ? 9 : 66;
+ xPos = 344;
+ yPos = 120;
+ } else if (_flagsTable[7] > 2 && _mousePosX > 160 && _mousePosX < 210 && _mousePosY > 110 && _mousePosY < 160) {
+ textNum = 15;
+ _nextLocationNum = (_partNum == 1) ? 16 : 61;
+ xPos = 590;
+ yPos = 130;
+ } else if ((_flagsTable[7] == 4 || _flagsTable[7] == 6) && _mousePosX > 150 && _mousePosX < 200 && _mousePosY > 20 && _mousePosY < 70) {
+ textNum = 16;
+ _nextLocationNum = (_partNum == 1) ? 20 : 68;
+ xPos = 20;
+ yPos = 130;
+ } else if (_flagsTable[120] == 1 && _mousePosX > 240 && _mousePosX < 290 && _mousePosY > 35 && _mousePosY < 90) {
+ textNum = 17;
+ _nextLocationNum = (_partNum == 1) ? 19 : 62;
+ xPos = 20;
+ yPos = 124;
+ } else if (_mousePosX > 135 && _mousePosX < 185 && _mousePosY > 170 && _mousePosY < 200) {
+ textNum = 18;
+ _nextLocationNum = _locationNum;
+ if (!_noPositionChangeAfterMap) {
+ xPos = _xPosCurrent;
+ yPos = _yPosCurrent;
+ } else if (_locationNum == 3 ||_locationNum == 65) {
+ xPos = 620;
+ yPos = 130;
+ } else if (_locationNum == 9 ||_locationNum == 66) {
+ xPos = 344;
+ yPos = 120;
+ } else if (_locationNum == 16 ||_locationNum == 61) {
+ xPos = 590;
+ yPos = 130;
+ } else if (_locationNum == 20 ||_locationNum == 68) {
+ xPos = 20;
+ yPos = 130;
+ } else {
+ xPos = 20;
+ yPos = 124;
+ }
+ }
+ if (textNum > 0) {
+ drawSpeechText(_scrollOffset + _mousePosX + 8, _mousePosY - 10, _infoBarBuf, textNum, 96);
+ }
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ if (_fadePaletteCounter < 14) {
+ fadeOutPalette();
+ ++_fadePaletteCounter;
+ }
+ } while (!_leftMouseButtonPressed || textNum == 0);
+ while (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ --_fadePaletteCounter;
+ }
+ _mouseClick = 1;
+ if (_nextLocationNum == 9 && _noPositionChangeAfterMap) {
+ _backgroundSpriteCurrentAnimation = 2;
+ _backgroundSpriteCurrentFrame = 0;
+ setCursorType(2);
+ } else if (_nextLocationNum == 66 && _noPositionChangeAfterMap) {
+ _backgroundSpriteCurrentAnimation = 1;
+ _backgroundSpriteCurrentFrame = 0;
+ setCursorType(2);
+ }
+ _noPositionChangeAfterMap = false;
+ _xPosCurrent = xPos;
+ _yPosCurrent = yPos;
+}
+
+void TuckerEngine::copyMapRect(int x, int y, int w, int h) {
+ const uint8 *src = _quadBackgroundGfxBuf + 89600 + y * 320 + x;
+ uint8 *dst = _loadTempBuf + y * 320 + x;
+ for (int i = 0; i < h; ++i) {
+ memcpy(dst, src, w);
+ src += 320;
+ dst += 320;
+ }
+}
+
+int TuckerEngine::handleSpecialObjectSelectionSequence() {
+ if (_partNum == 1 && _selectedObjectNum == 6) {
+ strcpy(_fileToLoad, "news1.pcx");
+ _flagsTable[7] = 1;
+ } else if (_partNum == 3 && _selectedObjectNum == 45) {
+ strcpy(_fileToLoad, "profnote.pcx");
+ } else if (_partNum == 1 && _selectedObjectNum == 26) {
+ strcpy(_fileToLoad, "photo.pcx");
+ } else if (_partNum == 3 && _selectedObjectNum == 39) {
+ strcpy(_fileToLoad, "news2.pcx");
+ _flagsTable[135] = 1;
+ } else if (_currentInfoString1SourceType == 0 && _currentActionObj1Num == 259) {
+ strcpy(_fileToLoad, "postit.pcx");
+ } else if (_currentInfoString1SourceType == 1 && _currentActionObj1Num == 91) {
+ strcpy(_fileToLoad, "memo.pcx");
+ } else {
+ return 0;
+ }
+ while (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ --_fadePaletteCounter;
+ }
+ _mouseClick = 1;
+ loadImage(_quadBackgroundGfxBuf, 1);
+ _fadePaletteCounter = 0;
+ while (1) {
+ waitForTimer(2);
+ updateMouseState();
+ Graphics::copyTo640(_locationBackgroundGfxBuf + _scrollOffset, _quadBackgroundGfxBuf, 320, 320, 200);
+ if (_fadePaletteCounter < 14) {
+ fadeOutPalette();
+ ++_fadePaletteCounter;
+ }
+ if (!_leftMouseButtonPressed && _mouseClick == 1) {
+ _mouseClick = 0;
+ }
+ if (_partNum == 3 && _selectedObjectNum == 45) {
+ for (int i = 0; i < 13; ++i) {
+ const int offset = _dataTable[204 + i].yDest * 640 + _dataTable[i].xDest;
+ static const int itemsTable[] = { 15, 44, 25, 19, 21, 24, 12, 27, 20, 29, 35, 23, 3 };
+ if (_inventoryItemsState[itemsTable[i]] > 1) {
+ Graphics::decodeRLE(_locationBackgroundGfxBuf + _scrollOffset + offset, _data3GfxBuf + _dataTable[204 + i].sourceOffset, _dataTable[204 + i].xSize, _dataTable[204 + i].ySize);
+ }
+ }
+ }
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ if (_leftMouseButtonPressed && _mouseClick != 1) {
+ while (_fadePaletteCounter > 0) {
+ fadeInPalette();
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ --_fadePaletteCounter;
+ }
+ _mouseClick = 1;
+ break;
+ }
+ }
+ loadLoc();
+ return 1;
+}
+
+} // namespace Tucker
diff --git a/engines/tucker/staticres.cpp b/engines/tucker/staticres.cpp
new file mode 100644
index 0000000000..dd3c449237
--- /dev/null
+++ b/engines/tucker/staticres.cpp
@@ -0,0 +1,219 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tucker/tucker.h"
+
+namespace Tucker {
+
+const int TuckerEngine::_locationWidthTable[85] = {
+ 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 4, 2, 1,
+ 1, 2, 1, 2, 4, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1,
+ 1, 1, 1, 1, 2, 1, 2, 2, 2, 4, 4, 2, 2, 1, 1, 1, 4, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
+};
+
+const uint8 TuckerEngine::_sprA02LookupTable[88] = {
+ 0, 6, 2, 8, 1, 0, 6, 0, 2, 2, 2, 1, 2, 0, 1, 1, 6, 0,
+ 1, 2, 1, 2, 3, 0, 6, 12, 7, 7, 1, 8, 1, 0, 3, 0, 4,
+ 5, 0, 0, 3, 3, 2, 7, 7, 0, 4, 1, 5, 2, 4, 1, 1, 2, 4,
+ 3, 1, 0, 2, 3, 4, 1, 1, 5, 3, 3, 1, 5, 3, 0, 1, 0, 0,
+ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const uint8 TuckerEngine::_sprC02LookupTable[100] = {
+ 0, 0, 6, 20, 3, 3, 15, 5, 9, 6, 7, 8, 8, 6, 3, 6, 13,
+ 3, 4, 10, 0, 7, 2, 34, 14, 0, 2, 3, 8, 3, 3, 3, 19,
+ 13, 1, 0, 2, 3, 0, 0, 0, 5, 5, 12, 0, 1, 0, 1, 3, 6,
+ 7, 6, 0, 7, 5, 1, 2, 6, 3, 4, 9, 18, 0, 12, 0, 2, 10,
+ 0, 0, 19, 0, 2, 2, 1, 22, 0, 0, 0, 0, 3, 0, 3, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
+};
+
+const uint8 TuckerEngine::_sprC02LookupTable2[100] = {
+ 0, 0, 1, 3, 1, 2, 3, 2, 2, 1, 1, 5, 2, 1, 1, 3, 3, 1,
+ 1, 4, 0, 1, 1, 4, 4, 0, 2, 1, 3, 3, 3, 2, 4, 4, 1, 0,
+ 1, 3, 0, 0, 0, 1, 1, 7, 0, 1, 0, 1, 1, 1, 7, 3, 0, 2,
+ 1, 1, 1, 2, 1, 1, 2, 3, 0, 5, 0, 1, 5, 0, 1, 4, 0, 1,
+ 1, 1, 1, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
+};
+
+const int TuckerEngine::_staticData3Table[1600] = {
+ 0x014, 0x014, 0x015, 0x016, 0x017, 0x017, 0x016, 0x015, 0x3E7, 0x0A9, 0x0A9, 0x0AA, 0x0AA, 0x0AB, 0x0AB, 0x0AC,
+ 0x0AC, 0x3E7, 0x05E, 0x05F, 0x060, 0x061, 0x3E7, 0x0AD, 0x0AE, 0x0AF, 0x0B0, 0x3E7, 0x052, 0x053, 0x054, 0x055,
+ 0x3E7, 0x056, 0x057, 0x058, 0x059, 0x3E7, 0x05A, 0x05B, 0x05C, 0x05D, 0x3E7, 0x062, 0x063, 0x064, 0x065, 0x3E7,
+ 0x066, 0x067, 0x068, 0x069, 0x3E7, 0x00C, 0x00D, 0x00E, 0x00F, 0x3E7, 0x01A, 0x01B, 0x01C, 0x01D, 0x3E7, 0x01E,
+ 0x01F, 0x020, 0x021, 0x3E7, 0x024, 0x025, 0x026, 0x027, 0x3E7, 0x0B1, 0x0B2, 0x0B3, 0x0B4, 0x3E7, 0x0CB, 0x0CC,
+ 0x0CD, 0x0CE, 0x3E7, 0x0CF, 0x0D0, 0x0D1, 0x0D2, 0x3E7, 0x0D3, 0x0D4, 0x0D5, 0x0D6, 0x3E7, 0x0D7, 0x0D8, 0x0D9,
+ 0x0DA, 0x3E7, 0x0B5, 0x0B6, 0x0B7, 0x0B8, 0x3E7, 0x04A, 0x04B, 0x04C, 0x04D, 0x3E7, 0x04E, 0x04F, 0x050, 0x051,
+ 0x3E7, 0x02A, 0x02B, 0x02C, 0x02D, 0x3E7, 0x02E, 0x02F, 0x030, 0x031, 0x3E6, 0x0E6, 0x001, 0x3E7, 0x0B9, 0x0BA,
+ 0x0BB, 0x0BC, 0x3E7, 0x06A, 0x06B, 0x06C, 0x06D, 0x3E7, 0x032, 0x033, 0x034, 0x035, 0x3E7, 0x036, 0x037, 0x038,
+ 0x039, 0x3E7, 0x03A, 0x03B, 0x03C, 0x03D, 0x3E7, 0x03E, 0x03F, 0x040, 0x041, 0x3E7, 0x042, 0x043, 0x044, 0x045,
+ 0x3E7, 0x046, 0x047, 0x048, 0x049, 0x3E7, 0x06E, 0x06F, 0x070, 0x071, 0x3E6, 0x045, 0x000, 0x3E7, 0x072, 0x073,
+ 0x074, 0x075, 0x3E7, 0x076, 0x077, 0x078, 0x079, 0x3E7, 0x07A, 0x07B, 0x07C, 0x07D, 0x3E7, 0x07F, 0x080, 0x081,
+ 0x082, 0x3E7, 0x085, 0x086, 0x087, 0x088, 0x3E7, 0x089, 0x08A, 0x08B, 0x08C, 0x3E7, 0x08F, 0x090, 0x091, 0x092,
+ 0x3E7, 0x0BD, 0x0BE, 0x0BF, 0x0C0, 0x3E7, 0x0C1, 0x0C2, 0x0C3, 0x0C4, 0x3E7, 0x0C5, 0x0C6, 0x0C7, 0x0C8, 0x3E7,
+ 0x093, 0x094, 0x095, 0x096, 0x3E7, 0x099, 0x099, 0x099, 0x09A, 0x09A, 0x09A, 0x09B, 0x09B, 0x09B, 0x09C, 0x09C,
+ 0x09C, 0x3E7, 0x09D, 0x09D, 0x09E, 0x09E, 0x09F, 0x09F, 0x0A0, 0x0A0, 0x3E7, 0x0A1, 0x0A1, 0x0A2, 0x0A2, 0x0A3,
+ 0x0A3, 0x0A4, 0x0A4, 0x3E7, 0x0A5, 0x0A5, 0x0A6, 0x0A6, 0x0A7, 0x0A7, 0x0A8, 0x0A8, 0x3E7, 0x0DE, 0x0DF, 0x0E0,
+ 0x0E1, 0x3E7, 0x010, 0x011, 0x012, 0x013, 0x3E7, 0x0E3, 0x0E4, 0x0E5, 0x0E6, 0x3E6, 0x03F, 0x000, 0x3E7, 0x000,
+ 0x001, 0x002, 0x003, 0x3E7, 0x004, 0x005, 0x006, 0x007, 0x3E7, 0x008, 0x009, 0x00A, 0x00B, 0x3E7, 0x00C, 0x00D,
+ 0x00E, 0x00F, 0x3E7, 0x010, 0x011, 0x012, 0x013, 0x3E7, 0x014, 0x015, 0x016, 0x017, 0x3E7, 0x018, 0x019, 0x01A,
+ 0x01B, 0x3E7, 0x01D, 0x01E, 0x01F, 0x020, 0x3E7, 0x021, 0x022, 0x023, 0x024, 0x3E7, 0x025, 0x026, 0x027, 0x028,
+ 0x3E7, 0x029, 0x02A, 0x02B, 0x02C, 0x3E7, 0x02D, 0x02E, 0x02F, 0x030, 0x3E7, 0x031, 0x032, 0x033, 0x034, 0x3E7,
+ 0x035, 0x036, 0x037, 0x038, 0x3E7, 0x039, 0x03A, 0x03B, 0x03C, 0x3E7, 0x03D, 0x03E, 0x03F, 0x040, 0x3E7, 0x041,
+ 0x042, 0x043, 0x044, 0x3E7, 0x049, 0x04A, 0x04B, 0x04C, 0x3E7, 0x04D, 0x04E, 0x04F, 0x050, 0x3E7, 0x051, 0x052,
+ 0x053, 0x054, 0x3E7, 0x055, 0x056, 0x057, 0x058, 0x3E7, 0x059, 0x05A, 0x05B, 0x05C, 0x3E7, 0x05D, 0x05E, 0x05F,
+ 0x060, 0x3E7, 0x061, 0x062, 0x063, 0x064, 0x3E7, 0x068, 0x069, 0x06A, 0x06B, 0x3E7, 0x06C, 0x06D, 0x06E, 0x06F,
+ 0x3E7, 0x070, 0x071, 0x072, 0x073, 0x3E7, 0x074, 0x075, 0x076, 0x077, 0x3E7, 0x07A, 0x07B, 0x07C, 0x07D, 0x3E7,
+ 0x07E, 0x07F, 0x080, 0x081, 0x3E7, 0x082, 0x083, 0x084, 0x085, 0x3E7, 0x086, 0x087, 0x088, 0x089, 0x3E7, 0x08A,
+ 0x08B, 0x08C, 0x08D, 0x3E7, 0x08E, 0x08E, 0x08F, 0x08F, 0x090, 0x090, 0x091, 0x091, 0x3E7, 0x000, 0x001, 0x002,
+ 0x003, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x3E7,
+ 0x004, 0x005, 0x006, 0x007, 0x3E7, 0x008, 0x009, 0x00A, 0x00B, 0x3E7, 0x00C, 0x00D, 0x00E, 0x00F, 0x3E7, 0x010,
+ 0x011, 0x012, 0x013, 0x3E7, 0x014, 0x015, 0x016, 0x017, 0x3E7, 0x018, 0x019, 0x01A, 0x01B, 0x01C, 0x01D, 0x01E,
+ 0x01F, 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, 0x028, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E,
+ 0x02F, 0x030, 0x031, 0x032, 0x3E7, 0x033, 0x034, 0x035, 0x3E7, 0x036, 0x037, 0x038, 0x3E7, 0x039, 0x03A, 0x03B,
+ 0x3E6, 0x091, 0x003, 0x3E7, 0x03B, 0x03A, 0x039, 0x3E6, 0x091, 0x000, 0x3E7, 0x03C, 0x03D, 0x03E, 0x03F, 0x040,
+ 0x041, 0x042, 0x043, 0x044, 0x3E6, 0x06E, 0x000, 0x3E7, 0x045, 0x046, 0x047, 0x048, 0x049, 0x04A, 0x04B, 0x04C,
+ 0x04D, 0x04E, 0x3E6, 0x068, 0x002, 0x3E7, 0x04F, 0x050, 0x051, 0x052, 0x3E7, 0x052, 0x051, 0x050, 0x04F, 0x3E7,
+ 0x053, 0x054, 0x055, 0x056, 0x3E7, 0x057, 0x058, 0x059, 0x05A, 0x05B, 0x05C, 0x05D, 0x05E, 0x05F, 0x060, 0x061,
+ 0x062, 0x063, 0x064, 0x065, 0x3E7, 0x066, 0x067, 0x068, 0x069, 0x06A, 0x06B, 0x06C, 0x06D, 0x06E, 0x06F, 0x070,
+ 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x3E7, 0x077, 0x078, 0x079, 0x07A, 0x07B, 0x07C, 0x07D, 0x3E6, 0x069,
+ 0x001, 0x3E7, 0x07D, 0x07C, 0x07B, 0x07A, 0x079, 0x078, 0x077, 0x3E6, 0x069, 0x000, 0x3E7, 0x07E, 0x07F, 0x080,
+ 0x081, 0x082, 0x083, 0x084, 0x3E6, 0x06A, 0x001, 0x3E7, 0x084, 0x083, 0x082, 0x081, 0x080, 0x07F, 0x07E, 0x3E6,
+ 0x06A, 0x000, 0x3E7, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08A, 0x08B, 0x08C, 0x08D, 0x08E, 0x08F, 0x090, 0x091,
+ 0x092, 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09A, 0x09B, 0x09C, 0x09D, 0x09E, 0x09F, 0x0A0, 0x0A1,
+ 0x0A2, 0x0A3, 0x0A4, 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x3E7, 0x0AA, 0x0AB, 0x0AC, 0x0AD, 0x0AE, 0x0AF, 0x0B0,
+ 0x0B1, 0x0B2, 0x0B3, 0x3E6, 0x06B, 0x000, 0x3E7, 0x0B3, 0x3E7, 0x0B4, 0x0B4, 0x0B5, 0x0B5, 0x0B6, 0x0B6, 0x0B7,
+ 0x0B7, 0x3E7, 0x0B8, 0x0B9, 0x0B9, 0x0BB, 0x0BC, 0x0BD, 0x0BE, 0x0BF, 0x3E7, 0x0C0, 0x0C1, 0x0C2, 0x0C3, 0x0C4,
+ 0x0C5, 0x0C6, 0x0C7, 0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, 0x0CE, 0x0CF, 0x0D0, 0x0D1, 0x0D2, 0x0D3, 0x0D4,
+ 0x0D5, 0x0D6, 0x0D7, 0x0D8, 0x3E7, 0x0D9, 0x0DA, 0x0DB, 0x0DC, 0x0DD, 0x0DE, 0x0DF, 0x0E0, 0x0E1, 0x0E2, 0x0E3,
+ 0x0E4, 0x0E5, 0x0E6, 0x0E7, 0x0E8, 0x0E9, 0x3E7, 0x1C5, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, 0x0F0, 0x0F1,
+ 0x0F2, 0x3E7, 0x0F3, 0x0F4, 0x0F5, 0x0F6, 0x0F7, 0x0F8, 0x0F9, 0x0FA, 0x3E6, 0x074, 0x001, 0x3E7, 0x0FB, 0x0FC,
+ 0x0FD, 0x0FE, 0x3E7, 0x0FF, 0x100, 0x101, 0x102, 0x3E7, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A,
+ 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x3E7, 0x116, 0x115, 0x114,
+ 0x113, 0x112, 0x111, 0x110, 0x10F, 0x10E, 0x3E7, 0x117, 0x118, 0x119, 0x11A, 0x3E7, 0x11B, 0x11C, 0x11D, 0x11E,
+ 0x3E7, 0x11F, 0x120, 0x121, 0x122, 0x3E7, 0x123, 0x124, 0x125, 0x3E6, 0x091, 0x003, 0x3E7, 0x125, 0x124, 0x123,
+ 0x3E7, 0x126, 0x127, 0x128, 0x3E7, 0x128, 0x127, 0x126, 0x3E7, 0x129, 0x12A, 0x12B, 0x12C, 0x12D, 0x12E, 0x12F,
+ 0x130, 0x131, 0x132, 0x133, 0x134, 0x135, 0x136, 0x137, 0x138, 0x139, 0x13A, 0x13B, 0x13C, 0x13D, 0x13E, 0x13F,
+ 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, 0x149, 0x14A, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F,
+ 0x150, 0x151, 0x152, 0x3E7, 0x153, 0x154, 0x155, 0x156, 0x157, 0x159, 0x15A, 0x15B, 0x15C, 0x3E7, 0x15E, 0x15F,
+ 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16A, 0x16B, 0x16C, 0x16D, 0x16E, 0x16F,
+ 0x170, 0x171, 0x172, 0x3E7, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x173, 0x174, 0x174, 0x174, 0x174, 0x174,
+ 0x174, 0x3E7, 0x175, 0x175, 0x175, 0x175, 0x175, 0x175, 0x176, 0x3E7, 0x177, 0x178, 0x179, 0x17A, 0x17B, 0x17C,
+ 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, 0x3E7, 0x188, 0x189, 0x18A, 0x18B,
+ 0x18C, 0x3E7, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0x19E, 0x19F, 0x1A0, 0x1A1, 0x1A2, 0x1A3, 0x1A4, 0x1A5,
+ 0x1A6, 0x1A7, 0x1A8, 0x1A9, 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF, 0x3E7, 0x1B0, 0x1B1, 0x1B2, 0x3E7, 0x1B3,
+ 0x1B4, 0x1B5, 0x1B6, 0x1B7, 0x1B8, 0x1B9, 0x1BA, 0x3E7, 0x1BB, 0x1BC, 0x1BD, 0x1BE, 0x1BF, 0x1C0, 0x1C1, 0x1C2,
+ 0x1C3, 0x1C4, 0x3E6, 0x06F, 0x000, 0x3E7, 0x098, 0x099, 0x09A, 0x3E7, 0x09A, 0x099, 0x098, 0x3E7, 0x09D, 0x09E,
+ 0x09F, 0x3E7, 0x09F, 0x09E, 0x09D, 0x3E7, 0x0A1, 0x0A2, 0x0A3, 0x3E7, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB,
+ 0x0AC, 0x0AD, 0x3E6, 0x08E, 0x002, 0x3E7, 0x0AE, 0x0AF, 0x0B0, 0x0B1, 0x0B2, 0x0B3, 0x0B4, 0x0B5, 0x0B6, 0x0B7,
+ 0x0B8, 0x0B9, 0x0BA, 0x0BB, 0x0BC, 0x0BD, 0x0BE, 0x3E7, 0x0F2, 0x0F2, 0x0F3, 0x0F3, 0x0F4, 0x0F4, 0x3E6, 0x030,
+ 0x002, 0x3E7, 0x1D3, 0x1D4, 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x3E7, 0x0F6, 0x0F7, 0x0F8, 0x0F8, 0x3E7, 0x0FB, 0x0FC,
+ 0x0FD, 0x0FE, 0x0FF, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x3E6, 0x07F, 0x002, 0x3E7, 0x106, 0x107, 0x108,
+ 0x109, 0x10A, 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, 0x110, 0x111, 0x3E7, 0x1E8, 0x1E7, 0x1E6, 0x1E5, 0x1E4, 0x1E3,
+ 0x1E2, 0x3E6, 0x095, 0x002, 0x3E7, 0x1A7, 0x1A8, 0x3E7, 0x1A9, 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1A9, 0x1AA, 0x1AB,
+ 0x1AC, 0x3E6, 0x09D, 0x003, 0x3E7, 0x1A0, 0x1A1, 0x3E7, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, 0x0F0, 0x0F1,
+ 0x0F2, 0x0F3, 0x0F4, 0x0F5, 0x3E7, 0x0F6, 0x0F7, 0x0F8, 0x0F9, 0x0FA, 0x0FB, 0x0FC, 0x0FD, 0x0FE, 0x0FF, 0x100,
+ 0x101, 0x3E7, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A, 0x10B, 0x10C, 0x10D, 0x3E7, 0x10E,
+ 0x10F, 0x110, 0x111, 0x3E7, 0x112, 0x113, 0x114, 0x115, 0x3E7, 0x116, 0x117, 0x3E7, 0x118, 0x119, 0x11A, 0x11B,
+ 0x3E7, 0x11C, 0x11D, 0x3E7, 0x11E, 0x11F, 0x120, 0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, 0x128, 0x129,
+ 0x3E7, 0x12A, 0x12B, 0x12C, 0x12D, 0x12E, 0x12F, 0x130, 0x131, 0x132, 0x133, 0x134, 0x135, 0x3E7, 0x136, 0x137,
+ 0x138, 0x139, 0x13A, 0x13B, 0x13C, 0x13D, 0x13E, 0x13F, 0x140, 0x141, 0x3E7, 0x106, 0x107, 0x108, 0x109, 0x10A,
+ 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, 0x110, 0x111, 0x3E7, 0x1A2, 0x1A3, 0x1A4, 0x1A2, 0x1A3, 0x1A4, 0x1A2, 0x1A3,
+ 0x1A4, 0x1A2, 0x1A3, 0x1A4, 0x3E6, 0x09D, 0x005, 0x3E7, 0x3E7, 0x3E7, 0x3E7, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
+};
+
+const int TuckerEngine::_instructionIdTable[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'l', 'm',
+ 'n', 'o', 'p', 'r', 's', 't', 'v', 'w', 'x', '+'
+};
+
+int TuckerEngine::_locationHeightTable[80] = {
+ 0x00, 0x1C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+int TuckerEngine::_objectKeysPosXTable[80] = {
+ 0x000, 0x0A0, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x12B, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x140, 0x000, 0x000, 0x000, 0x000, 0x09E, 0x060, 0x0C0, 0x040, 0x0A0, 0x12C, 0x068, 0x098,
+ 0x08E, 0x09A, 0x0A0, 0x098, 0x092, 0x096, 0x09A, 0x09A, 0x08C, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0A0, 0x000,
+ 0x086, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0A0, 0x185, 0x000, 0x0A0, 0x140, 0x140, 0x000,
+ 0x000, 0x124, 0x140, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+};
+
+int TuckerEngine::_objectKeysPosYTable[80] = {
+ 0x000, 0x06B, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x080, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x075, 0x000, 0x000, 0x000, 0x000, 0x086, 0x02B, 0x079, 0x07C, 0x07C, 0x07B, 0x073, 0x07B,
+ 0x06C, 0x08A, 0x086, 0x086, 0x086, 0x086, 0x083, 0x083, 0x07B, 0x000, 0x000, 0x000, 0x000, 0x000, 0x078, 0x000,
+ 0x082, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x089, 0x08A, 0x000, 0x088, 0x082, 0x076, 0x000,
+ 0x000, 0x07F, 0x083, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+};
+
+int TuckerEngine::_objectKeysLocationTable[80] = {
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+ 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001,
+ 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x001, 0x001, 0x001, 0x000,
+ 0x000, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+};
+
+int TuckerEngine::_mapSequenceFlagsLocationTable[70] = {
+ 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 1, 1, 1, 1, 0, 0,
+};
+
+const int TuckerEngine::_charWidthCharset2[58] = {
+ 0x13, 0x0F, 0x10, 0x10, 0x10, 0x0E, 0x11, 0x10, 0x0D, 0x0A, 0x11, 0x0D, 0x14, 0x13, 0x13, 0x11,
+ 0x13, 0x12, 0x10, 0x11, 0x13, 0x14, 0x14, 0x10, 0x13, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x13, 0x0F, 0x10, 0x10, 0x10, 0x0E, 0x11, 0x10, 0x0D, 0x0A, 0x11, 0x0D, 0x14, 0x13, 0x13, 0x11,
+ 0x13, 0x12, 0x10, 0x11, 0x13, 0x14, 0x14, 0x10, 0x13, 0x10,
+};
+
+} // namespace Tucker
diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp
new file mode 100644
index 0000000000..11b40eaf00
--- /dev/null
+++ b/engines/tucker/tucker.cpp
@@ -0,0 +1,3778 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/events.h"
+#include "common/system.h"
+
+#include "graphics/cursorman.h"
+
+#include "tucker/tucker.h"
+#include "tucker/graphics.h"
+
+namespace Tucker {
+
+TuckerEngine::TuckerEngine(OSystem *system, Common::Language language)
+ : Engine(system) {
+}
+
+TuckerEngine::~TuckerEngine() {
+}
+
+Common::Error TuckerEngine::init() {
+ _system->beginGFXTransaction();
+ initCommonGFX(false);
+ _system->initSize(320, 200);
+ _system->endGFXTransaction();
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ return Common::kNoError;
+}
+
+Common::Error TuckerEngine::go() {
+ mainLoop();
+ return Common::kNoError;
+}
+
+void TuckerEngine::syncSoundSettings() {
+ // TODO
+}
+
+int TuckerEngine::getRandomNumber() {
+ return _rnd.getRandomNumber(0x7FFF);
+}
+
+void TuckerEngine::allocateBuffers() {
+ _locationBackgroundGfxBuf = (uint8 *)calloc(1, 640 * 200);
+ _loadTempBuf = (uint8 *)calloc(1, 64010);
+ _panelGfxBuf = (uint8 *)calloc(1, 64010);
+ _itemsGfxBuf = (uint8 *)calloc(1, 19200);
+ _charsetGfxBuf = (uint8 *)calloc(1, 22400);
+ _cursorGfxBuf = (uint8 *)calloc(1, 256 * 7);
+ _infoBarBuf = (uint8 *)calloc(1, 1000);
+ _charNameBuf = 0;
+ _bgTextBuf = 0;
+ _objTxtBuf = 0;
+ _panelObjectsGfxBuf = (uint8 *)calloc(1, 20000);
+ _data5Buf = 0;
+ _data3GfxBuf = (uint8 *)calloc(1, 250000);
+ _quadBackgroundGfxBuf = (uint8 *)calloc(1, 320 * 140 * 4);
+ _locationBackgroundMaskBuf = (uint8 *)calloc(1, 640 * 140);
+ _csDataBuf = 0;
+ _spritesGfxBuf = (uint8 *)calloc(1, 160000);
+ _ptTextBuf = 0;
+ memset(_charWidthTable, 0, sizeof(_charWidthTable));
+}
+
+void TuckerEngine::freeBuffers() {
+ free(_locationBackgroundGfxBuf);
+ free(_loadTempBuf);
+ free(_panelGfxBuf);
+ free(_itemsGfxBuf);
+ free(_charsetGfxBuf);
+ free(_cursorGfxBuf);
+ free(_infoBarBuf);
+ free(_charNameBuf);
+ free(_bgTextBuf);
+ free(_objTxtBuf);
+ free(_panelObjectsGfxBuf);
+ free(_data5Buf);
+ free(_data3GfxBuf);
+ free(_quadBackgroundGfxBuf);
+ free(_locationBackgroundMaskBuf);
+ free(_csDataBuf);
+ free(_spritesGfxBuf);
+ free(_ptTextBuf);
+}
+
+void TuckerEngine::restart() {
+ _quitGame = 0;
+ _fastMode = false;
+ _syncCounter = 0;
+ _lastFrameTime = _system->getMillis();
+ _mainLoopCounter1 = _mainLoopCounter2 = 0;
+ _timerCounter1 = _timerCounter2 = 0;
+ _partNum = _currentPartNum = 0;
+ _locationNum = 0;
+ _nextLocationNum = ConfMan.getInt("boot_param");
+ if (_nextLocationNum == 0) {
+ _nextLocationNum = kStartupLocation;
+ }
+ _gamePaused = _gamePaused2 = 0;
+ memset(_flagsTable, 0, sizeof(_flagsTable));
+
+ _gameHintsIndex = 0;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+
+ memset(_sprA02Table, 0, sizeof(_sprA02Table));
+ memset(_sprC02Table, 0, sizeof(_sprC02Table));
+ memset(_actionsTable, 0, sizeof(_actionsTable));
+ _actionsCount = 0;
+ memset(_locationObjectsTable, 0, sizeof(_locationObjectsTable));
+ _locationObjectsCount = 0;
+ memset(_spritesTable, 0, sizeof(_spritesTable));
+ _spritesCount = 0;
+ memset(_locationAnimationsTable, 0, sizeof(_locationAnimationsTable));
+ _locationAnimationsCount = 0;
+ memset(_dataTable, 0, sizeof(_dataTable));
+ _dataCount = 0;
+ memset(_charPosTable, 0, sizeof(_charPosTable));
+ _charPosCount = 0;
+ memset(_locationSoundsTable, 0, sizeof(_locationSoundsTable));
+ _locationSoundsCount = 0;
+ memset(_locationMusicsTable, 0, sizeof(_locationMusicsTable));
+ _locationMusicsCount = 0;
+
+ _mousePosX = _mousePosY = 0;
+ _prevMousePosX = _prevMousePosY = 0;
+ _mouseButtonsMask = 0;
+ _mouseButton2 = 0;
+ _mouseClick = 0;
+ _mouseClickOnPanelSliders = 0;
+ _mouseIdleCounter = 0;
+ _leftMouseButtonPressed = _rightMouseButtonPressed = false;
+ _keyLastKeyCodePressed = _lastKeyPressed = 0;
+ _cursorNum = 0;
+ _cursorType = 0;
+ _updateCursorFlag = 0;
+
+ _panelNum = 1;
+ _panelState = 0;
+ _forceRedrawPanelItems = 1;
+ _redrawPanelItemsCounter = 0;
+ _switchPanelFlag = 0;
+ memset(_panelObjectsOffsetTable, 0, sizeof(_panelObjectsOffsetTable));
+ _switchPanelCounter = 0;
+ _conversationOptionsCount = 0;
+ _fadedPanel = false;
+ _panelLockedFlag = 0;
+ _panelItemWidth = 0;
+ memset(_inventoryItemsState, 0, sizeof(_inventoryItemsState));
+ memset(_inventoryObjectsList, 0, sizeof(_inventoryObjectsList));
+ _inventoryObjectsOffset = 0;
+ _inventoryObjectsCount = 0;
+ _lastInventoryObjectIndex = 0;
+
+ _currentFxSet = 0;
+ _currentFxDist = 0;
+ _currentFxScale = 0;
+ _currentFxVolume = 0;
+ _currentFxIndex = 0;
+ _speechSoundNum = 0;
+ _speechVolume = kMaxSoundVolume;
+ memset(_soundsMapTable, 0, sizeof(_soundsMapTable));
+ memset(_speechHistoryTable, 0, sizeof(_speechHistoryTable));
+ for (int i = 0; i < kMaxCharacters; ++i) {
+ _charSpeechSoundVolumeTable[i] = kMaxSoundVolume;
+ }
+ _charSpeechSoundCounter = 0;
+ memset(_miscSoundFxDelayCounter, 0, sizeof(_miscSoundFxDelayCounter));
+ _characterSoundFxDelayCounter = 0;
+ _characterSoundFxNum = 0;
+ _speechSoundBaseNum = 0;
+
+ _pendingActionIndex = 0;
+ _pendingActionDelay = 0;
+ _charPositionFlagNum = 0;
+ _charPositionFlagValue = 0;
+ _actionVerb = kVerbWalk;
+ _nextAction = 0;
+ _selectedObjectNum = 0;
+ _selectedObjectType = 0;
+ _selectedCharacterNum = 0;
+ _actionObj1Type = _actionObj2Type = 0;
+ _actionObj1Num = _actionObj2Num = 0;
+ _actionRequiresTwoObjects = 0;
+ _skipPanelObjectUnderCursor = 0;
+ _actionPosX = 0;
+ _actionPosY = 0;
+ _selectedObjectLocationMask = 0;
+ memset(&_selectedObject, 0, sizeof(_selectedObject));
+ _selectedCharacterDirection = 0;
+ _selectedCharacter2Num = 0;
+ _currentActionObj1Num = _currentActionObj2Num = 0;
+ _currentInfoString1SourceType = _currentInfoString2SourceType = 0;
+ memset(_speechActionCounterTable, 0, sizeof(_speechActionCounterTable));
+ _actionCharacterNum = 0;
+
+ _csDataLoaded = false;
+ _csDataHandled = 0;
+ _stopActionOnSoundFlag = 0;
+ _csDataTableFlag2 = 0;
+ _stopActionOnPanelLock = 0;
+ _csDataTableCount = 0;
+ _stopActionCounter = 0;
+ _actionTextColor = 0;
+ _nextTableToLoadIndex = 0;
+ memset(_nextTableToLoadTable, 0, sizeof(_nextTableToLoadTable));
+ _soundInstructionIndex = 0;
+ _tableInstructionsPtr = 0;
+ memset(_tableInstructionObj1Table, 0, sizeof(_tableInstructionObj1Table));
+ memset(_tableInstructionObj2Table, 0, sizeof(_tableInstructionObj2Table));
+ _tableInstructionFlag = 0;
+ _tableInstructionItemNum1 = _tableInstructionItemNum2 = 0;
+ memset(_instructionsActionsTable, 0, sizeof(_instructionsActionsTable));
+ _validInstructionId = 0;
+
+ memset(_spriteFramesTable, 0, sizeof(_spriteFramesTable));
+ memset(_spriteAnimationsTable, 0, sizeof(_spriteAnimationsTable));
+ memset(_spriteAnimationFramesTable, 0, sizeof(_spriteAnimationFramesTable));
+ _spriteAnimationFrameIndex = 0;
+ _backgroundSpriteCurrentFrame = 0;
+ _backgroundSpriteLastFrame = 0;
+ _backgroundSpriteCurrentAnimation = -1;
+ _disableCharactersPath = false;
+ _skipCurrentCharacterDraw = false;
+ _yPosCurrent = 131;
+ _xPosCurrent = 160;
+ _characterSpeechDataPtr = 0;
+ _ptTextOffset = 0;
+ memset(_ctable01Table_sprite, 0, sizeof(_ctable01Table_sprite));
+ memset(_characterAnimationsTable, 0, sizeof(_characterAnimationsTable));
+ memset(_characterStateTable, 0, sizeof(_characterStateTable));
+ _backgroundSprOffset = 0;
+ _updateCharPositionNewType = 0;
+ _updateCharPositionType = 0;
+ _mainSpritesBaseOffset = 0;
+ _currentSpriteAnimationLength = 0;
+ _currentSpriteAnimationFrame = 0;
+ _currentSpriteAnimationFrame2 = 0;
+ _characterAnimationIndex = -1;
+ _characterFacingDirection = _characterPrevFacingDirection = 0;
+ _characterBackFrontFacing = _characterPrevBackFrontFacing = 0;
+ _characterAnimationNum = 0;
+ _noCharacterAnimationChange = 0;
+ _changeBackgroundSprite = 0;
+ _characterSpriteAnimationFrameCounter = 0;
+ _locationMaskIgnore = 0;
+ _locationMaskType = 0;
+ _locationMaskCounter = 0;
+ _updateSpriteFlag1 = 0;
+ _updateSpriteFlag2 = 0;
+ _handleMapCounter = 0;
+ _noPositionChangeAfterMap = false;
+
+ _mirroredDrawing = 0;
+ _loadLocBufPtr = 0;
+ _backgroundSpriteDataPtr = 0;
+ _locationHeight = 0;
+ _scrollOffset = 0;
+ _currentGfxBackgroundCounter = 0;
+ _currentGfxBackground = 0;
+ _fadePaletteCounter = 0;
+ memset(&_currentPalette, 0, sizeof(_currentPalette));
+ memset(&_backupPalette, 0, sizeof(_backupPalette));
+
+ _updateLocationFadePaletteCounter = 0;
+ _updateLocationCounter = 10;
+ _updateLocationPos = 0;
+ for (int i = 0; i < 5; ++i) {
+ _updateLocationXPosTable[i] = 160;
+ _updateLocationYPosTable[i] = 131;
+ }
+ memset(_updateLocationFlagsTable, 0, sizeof(_updateLocationFlagsTable));
+ memset(_updateLocationXPosTable2, 0, sizeof(_updateLocationXPosTable2));
+ memset(_updateLocationYPosTable2, 0, sizeof(_updateLocationYPosTable2));
+ memset(_updateLocationYMaxTable, 0, sizeof(_updateLocationYMaxTable));
+ memset(_updateLocation14Step, 0, sizeof(_updateLocation14Step));
+ memset(_updateLocation14ObjNum, 0, sizeof(_updateLocation14ObjNum));
+ memset(_updateLocation14Delay, 0, sizeof(_updateLocation14Delay));
+ _updateLocationCounter2 = 0;
+ _updateLocationFlag = 0;
+ _updateLocation70StringLen = 0;
+ memset(_updateLocation70String, 0, sizeof(_updateLocation70String));
+}
+
+void TuckerEngine::mainLoop() {
+ allocateBuffers();
+ restart();
+
+ openCompressedSoundFile();
+ _useEnc = Common::File::exists("data5.enc");
+ loadCharSizeDta();
+ loadCharset();
+ loadPanel();
+ strcpy(_fileToLoad, "infobar.txt");
+ loadFile(_infoBarBuf);
+ strcpy(_fileToLoad, "data5.c");
+ _data5Buf = loadFile();
+ strcpy(_fileToLoad, "bgtext.c");
+ _bgTextBuf = loadFile();
+ strcpy(_fileToLoad, "charname.c");
+ _charNameBuf = loadFile();
+ strcpy(_fileToLoad, "csdata.c");
+ _csDataBuf = loadFile();
+ _csDataSize = _fileLoadSize;
+ strcpy(_fileToLoad, "nofiles.dta");
+ loadFile(_loadTempBuf);
+ if (_fileLoadSize > 1) {
+ _maxSaveGameSlot = _loadTempBuf[0];
+ _currentSaveGameSlot = _loadTempBuf[4];
+ }
+ loadBudSpr(0);
+ loadCursor();
+ setCursorNum(_cursorNum);
+ setCursorType(_cursorType);
+
+ _flagsTable[219] = 1;
+ _flagsTable[105] = 1;
+
+ _spriteAnimationFrameIndex = _spriteAnimationsTable[14].firstFrameIndex;
+
+ while (1) {
+ ++_syncCounter;
+ if (_flagsTable[137] != _flagsTable[138]) {
+ loadBudSpr(0);
+ _flagsTable[138] = _flagsTable[137];
+ }
+ if (_syncCounter >= 2) {
+ _syncCounter = 0;
+ waitForTimer(2);
+ }
+ updateMouseState();
+ if (_fadePaletteCounter < 16) {
+ if (_fadePaletteCounter > 1) {
+ fadeOutPalette();
+ }
+ ++_fadePaletteCounter;
+ }
+ if (_fadePaletteCounter > 19 && _fadePaletteCounter < 34) {
+ fadeInPalette();
+ ++_fadePaletteCounter;
+ }
+ if (_nextAction != 0) {
+ loadActionsTable();
+ }
+ if (_nextLocationNum > 0) {
+ setupNewLocation();
+ }
+ updateCharPosition();
+ if (_cursorType == 0) {
+ updateCursor();
+ } else if (_panelState == 2) {
+ handleMouseOnPanel();
+ }
+ if (_mainLoopCounter2 == 0) {
+ updateFlagsForCharPosition();
+ }
+ if (_syncCounter == 0 || !_disableCharactersPath) {
+ updateCharactersPath();
+ }
+ if (_mainLoopCounter2 == 0) {
+ updateCharacterAnimation();
+ if (_backgroundSpriteCurrentAnimation == -1) {
+ _flagsTable[207] = 0;
+ if (_flagsTable[220] > 0) {
+ _flagsTable[_flagsTable[220]] = _flagsTable[221];
+ _flagsTable[220] = 0;
+ }
+ if (_flagsTable[158] == 1) {
+ _flagsTable[158] = 0;
+ _skipCurrentCharacterDraw = 1;
+ }
+ _mainLoopCounter1 = 0;
+ }
+ }
+ if (_mainLoopCounter1 == 0) {
+ updateSprites();
+ updateData3();
+ updateSfxData3_1();
+ }
+ ++_mainLoopCounter2;
+ handleMap();
+ updateScreenScrolling();
+ if (_mainLoopCounter2 > 4) {
+ _mainLoopCounter2 = 0;
+ updateSfxData3_2();
+ }
+ ++_mainLoopCounter1;
+ if (_mainLoopCounter1 > 5) {
+ _mainLoopCounter1 = 0;
+ }
+ if (_locationHeight == 140) {
+ switchPanelType();
+ redrawPanelItems();
+ if (_displayGameHints != 0 && _gameHintsIndex < 6) {
+ updateGameHints();
+ }
+ if (_panelState == 0) {
+ if (_panelLockedFlag == 1 || _pendingActionDelay > 0) {
+ if (!_fadedPanel) {
+ updateItemsGfxColors(0x60, 0x80);
+ _fadedPanel = true;
+ }
+ } else {
+ _fadedPanel = false;
+ clearItemsGfx();
+ if (_gamePaused != 0) {
+ drawPausedInfoBar();
+ } else if (_gameHintsDisplayText == 1 && _mouseIdleCounter > 1000) {
+ drawGameHintString();
+ } else {
+ drawInfoString();
+ }
+ }
+ }
+ }
+ _mainSpritesBaseOffset = 0;
+ if (_locationWidthTable[_locationNum] > 3) {
+ ++_currentGfxBackgroundCounter;
+ if (_currentGfxBackgroundCounter > 39) {
+ _currentGfxBackgroundCounter = 0;
+ }
+ _currentGfxBackground = _quadBackgroundGfxBuf + (_currentGfxBackgroundCounter / 10) * 44800;
+ if (_fadePaletteCounter < 34 && _locationNum == 22) {
+ _spritesTable[0].gfxBackgroundOffset = (_currentGfxBackgroundCounter / 10) * 640;
+ _mainSpritesBaseOffset = _currentGfxBackgroundCounter / 10;
+ if (_locationNum == 22 && _currentGfxBackgroundCounter <= 29) {
+ _spritesTable[0].gfxBackgroundOffset = 640;
+ _mainSpritesBaseOffset = 1;
+ }
+ }
+ } else {
+ _currentGfxBackground = _quadBackgroundGfxBuf;
+ }
+ if (_syncCounter != 0) {
+ continue;
+ }
+ Graphics::copyTo640(_locationBackgroundGfxBuf + _scrollOffset, _currentGfxBackground + _scrollOffset, 320 - _scrollOffset, 320, _locationHeight);
+ Graphics::copyTo640(_locationBackgroundGfxBuf + 320, _currentGfxBackground + 44800, _scrollOffset, 320, _locationHeight);
+ drawData3();
+ execData3PreUpdate();
+ for (int i = 0; i < _spritesCount; ++i) {
+ if (_spritesTable[i].disabled == 0) {
+ drawSprite(i);
+ }
+ }
+ if (_skipCurrentCharacterDraw != 1) {
+ if (_backgroundSpriteCurrentAnimation > -1 && _backgroundSpriteCurrentFrame > 0) {
+ drawBackgroundSprites(0);
+ } else {
+ int offset;
+ SpriteFrame *chr = &_spriteFramesTable[_currentSpriteAnimationFrame];
+ if (_mirroredDrawing == 0) {
+ offset = (_yPosCurrent + _mainSpritesBaseOffset - 54 + chr->yOffset) * 640 + _xPosCurrent;
+ offset += chr->xOffset - 14;
+ } else {
+ offset = (_yPosCurrent + _mainSpritesBaseOffset - 54 + chr->yOffset) * 640 + _xPosCurrent;
+ offset -= chr->xSize + chr->xOffset - 14;
+ }
+ Graphics::decodeRLE_248(_locationBackgroundGfxBuf + offset, _spritesGfxBuf + chr->sourceOffset, chr->xSize, chr->ySize,
+ chr->yOffset, _locationHeightTable[_locationNum], _mirroredDrawing != 0);
+ if (_currentSpriteAnimationLength > 1) {
+ SpriteFrame *chr2 = &_spriteFramesTable[_currentSpriteAnimationFrame2];
+ if (_mirroredDrawing == 0) {
+ offset = (_yPosCurrent + _mainSpritesBaseOffset - 54 + chr2->yOffset) * 640 + _xPosCurrent;
+ offset += chr2->xOffset - 14;
+ } else {
+ offset = (_yPosCurrent + _mainSpritesBaseOffset - 54 + chr2->yOffset) * 640 + _xPosCurrent;
+ offset -= chr2->xSize + chr2->xOffset - 14;
+ }
+ Graphics::decodeRLE_248(_locationBackgroundGfxBuf + offset, _spritesGfxBuf + chr2->sourceOffset, chr2->xSize, chr2->ySize,
+ _spriteFramesTable[_currentSpriteAnimationFrame].yOffset, // _currentCharacter instead ?
+ _locationHeightTable[_locationNum], _mirroredDrawing != 0);
+ }
+ }
+ }
+ if (_locationHeight == 140) {
+ redrawPanelOverBackground();
+ }
+ if (_panelState == 3) {
+ saveOrLoad();
+ }
+ execData3PostUpdate();
+ if (_timerCounter2 > 45) {
+ _timerCounter2 = 0;
+ }
+ updateSoundsTypes3_4();
+ if (_currentFxSet != 0) {
+ setSoundVolumeDistance();
+ }
+ if (_data4FlagDebug != 0) {
+ drawStringInteger(_scrollOffset + _mousePosX, 0, 10, 3);
+ drawStringInteger(_scrollOffset + _mousePosY, 0, 20, 3);
+ drawStringInteger(_backgroundSpriteCurrentFrame, 0, 40, 3);
+ drawStringInteger(_backgroundSpriteCurrentAnimation, 0, 50, 3);
+ drawStringInteger(_mouseButton2, 0, 60, 3);
+ }
+ updateCharSpeechSound();
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ startCharacterSounds();
+ for (int num = 0; num < 2; ++num) {
+ if (_miscSoundFxDelayCounter[num] > 0) {
+ --_miscSoundFxDelayCounter[num];
+ if (_miscSoundFxDelayCounter[num] == 0) {
+ const int index = _soundsMapTable[num];
+ startSound(_locationSoundsTable[index].offset, index, _locationSoundsTable[index].volume);
+ }
+ }
+ }
+ _lastKeyPressed = getLastKeyCode();
+ if (_gamePaused == 1 && _charSpeechSoundCounter == 0) {
+ stopSounds();
+ _gamePaused2 = 1;
+ while (1) {
+ if (_lastKeyPressed == Common::KEYCODE_p && _charSpeechSoundCounter <= 0) { // Paused
+ playSounds();
+ _gamePaused = _gamePaused2 = 0;
+ break;
+ }
+ _lastKeyPressed = getLastKeyCode();
+ if (_charSpeechSoundCounter == 0) {
+ if (_lastKeyPressed >= Common::KEYCODE_1 && _lastKeyPressed <= Common::KEYCODE_5) {
+ if (_speechHistoryTable[_lastKeyPressed - Common::KEYCODE_1] > 0) {
+ startSpeechSound(_speechHistoryTable[_lastKeyPressed - Common::KEYCODE_1], 100);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ }
+ }
+ }
+ updateCharSpeechSound();
+ }
+ }
+ if (_lastKeyPressed == Common::KEYCODE_p && _locationNum == 70) {
+ _gamePaused = 1;
+ }
+ if (_lastKeyPressed == Common::KEYCODE_F3 && _displayGameHints != 0 && _gameHintsDisplayText == 1) {
+ _mouseButton2 = _gameHintsIndex + 1;
+ _mouseIdleCounter = 1100;
+ }
+ if (_lastKeyPressed == 1 && _data4FlagDebug != 0) {
+ _flagsTable[236] = 74;
+ }
+ if (_flagsTable[236] > 70) {
+ handleCreditsSequence();
+ _quitGame = 1;
+ }
+ if ((_lastKeyPressed == Common::KEYCODE_F4 && _data4FlagDebug != 0) || _quitGame == 1 || _flagsTable[100] != 0) {
+ break;
+ }
+ }
+ if (_flagsTable[100] != 1) {
+ handleCongratulationsSequence();
+ }
+ freeBuffers();
+}
+
+void TuckerEngine::updateTimer() {
+ ++_timerCounter1;
+ ++_timerCounter2;
+}
+
+void TuckerEngine::waitForTimer(int ticksCount) {
+ uint32 end = _lastFrameTime + ticksCount * 1000 / 46;
+ do {
+ updateTimer();
+ parseEvents();
+ _system->delayMillis(10);
+ _lastFrameTime = _system->getMillis();
+ } while (!_fastMode && _lastFrameTime < end);
+ _timerCounter1 = 0;
+}
+
+void TuckerEngine::parseEvents() {
+ Common::Event ev;
+ while (_eventMan->pollEvent(ev)) {
+ switch (ev.type) {
+ case Common::EVENT_KEYDOWN:
+ if (ev.kbd.flags == Common::KBD_CTRL) {
+ if (ev.kbd.keycode == Common::KEYCODE_f) {
+ _fastMode = !_fastMode;
+ }
+ }
+ _keyLastKeyCodePressed = ev.kbd.keycode;
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ updateCursorPos(ev.mouse.x, ev.mouse.y);
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ updateCursorPos(ev.mouse.x, ev.mouse.y);
+ _mouseButtonsMask |= 1;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ updateCursorPos(ev.mouse.x, ev.mouse.y);
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ updateCursorPos(ev.mouse.x, ev.mouse.y);
+ _mouseButtonsMask |= 2;
+ break;
+ case Common::EVENT_RBUTTONUP:
+ updateCursorPos(ev.mouse.x, ev.mouse.y);
+ break;
+ default:
+ break;
+ }
+ }
+ if (shouldQuit()) {
+ _flagsTable[100] = 1;
+ }
+}
+
+void TuckerEngine::updateCursorPos(int x, int y) {
+ _prevMousePosX = _mousePosX;
+ _prevMousePosY = _mousePosY;
+ _mousePosX = x;
+ _mousePosY = y;
+}
+
+void TuckerEngine::setCursorNum(int num) {
+ _cursorNum = num;
+ const int cursorW = 16;
+ const int cursorH = 16;
+ CursorMan.replaceCursor(_cursorGfxBuf + _cursorNum * 256, cursorW, cursorH, 1, 1, 0);
+}
+
+void TuckerEngine::setCursorType(int type) {
+ _cursorType = type;
+ CursorMan.showMouse(_cursorType < 2);
+}
+
+void TuckerEngine::setupNewLocation() {
+ _locationNum = _nextLocationNum;
+ loadObj();
+ _switchPanelFlag = 0;
+ _nextLocationNum = 0;
+ _fadePaletteCounter = 0;
+ _mainLoopCounter2 = 0;
+ _mainLoopCounter1 = 0;
+ _characterFacingDirection = 0;;
+ _skipPanelObjectUnderCursor = 0;
+ _locationMaskIgnore = 0;
+ _backgroundSprOffset = 0;
+ if (_backgroundSpriteCurrentAnimation > 0 && _backgroundSpriteCurrentFrame > 0) {
+ _backgroundSpriteCurrentAnimation = -1;
+ _backgroundSpriteCurrentFrame = 0;
+ }
+ if (_panelLockedFlag == 0 || (_backgroundSpriteCurrentAnimation > 0 && _locationNum != 25)) {
+ _locationMaskType = 0;
+ } else {
+ _locationMaskType = 3;
+ }
+ while (_spriteAnimationFramesTable[_spriteAnimationFrameIndex] != 999) {
+ ++_spriteAnimationFrameIndex;
+ }
+ _execData3Counter = 0;
+ stopSounds();
+ loadLoc();
+ loadData4();
+ loadData3();
+ loadActionFile();
+ loadCharPos();
+ loadSprA02_01();
+ loadSprC02_01();
+ loadFx();
+ playSounds();
+ if (_flagsTable[215] > 0) {
+ handleMeanwhileSequence();
+ _flagsTable[215] = 0;
+ }
+ if (_flagsTable[231] > 0) {
+ handleMeanwhileSequence();
+ _flagsTable[231] = 0;
+ }
+}
+
+void TuckerEngine::copyLocBitmap(int offset, int isMask) {
+ int type = (isMask == 0) ? 1 : 0;
+ if (offset > 0 && _locationNum == 16) {
+ type = 0;
+ }
+ if (isMask < 2) {
+ char strNum[3];
+ sprintf(strNum, "%02d", _locationNum);
+ const int digitOffset = (isMask == 0) ? 3 : 4;
+ memcpy(_fileToLoad + digitOffset, strNum, 2);
+ }
+ loadImage(_loadTempBuf, type);
+ uint8 *dst = (isMask == 1) ? _locationBackgroundMaskBuf : _locationBackgroundGfxBuf;
+ dst += offset;
+ const uint8 *src = _loadTempBuf;
+ for (int y = 0; y < _locationHeight; ++y) {
+ memcpy(dst, src, 320);
+ src += 320;
+ dst += 640;
+ }
+}
+
+void TuckerEngine::updateMouseState() {
+ if (_cursorType < 2) {
+ _leftMouseButtonPressed = (_mouseButtonsMask & 1) != 0;
+ if (_leftMouseButtonPressed) {
+ _mouseIdleCounter = 0;
+ _mouseButton2 = 0;
+ }
+ _rightMouseButtonPressed = (_mouseButtonsMask & 2) != 0;
+ _mouseButtonsMask = 0;
+ if (_prevMousePosX == _mousePosX && _prevMousePosY == _mousePosY) {
+ ++_mouseIdleCounter;
+ } else {
+ _mouseIdleCounter = 0;
+ _mouseButton2 = 0;
+ }
+ }
+ if (_mousePosX > 307) {
+ _mousePosX = 307;
+ }
+ if (_mousePosY > 195) {
+ _mousePosY = 195;
+ }
+ if (_cursorType == 1) {
+ if (_panelState == 1) {
+ setCursorNum(1);
+ }
+ if (_mousePosY < 140) {
+ _mousePosY = 140;
+ }
+ }
+}
+
+void TuckerEngine::updateCharPositionHelper() {
+ setCursorType(2);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ _updateCharPositionNewType = 0;
+ startSpeechSound(_speechSoundNum, _speechVolume);
+ int pos = getPositionForLine(_speechSoundNum, _characterSpeechDataPtr);
+ _characterSpeechDataPtr += pos;
+ _speechSoundNum = 0;
+}
+
+void TuckerEngine::updateCharPosition() {
+ if (_updateCharPositionNewType == 0 || _locationMaskCounter == 0) {
+ return;
+ }
+ if (_updateCharPositionNewType == 1 && _locationNum != 18) {
+ int pos;
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ switch (_currentInfoString1SourceType) {
+ case 0:
+ if (_currentActionObj1Num == 0) {
+ return;
+ }
+ if (_currentActionObj1Num == 259) {
+ handleSpecialObjectSelectionSequence();
+ _updateCharPositionNewType = 0;
+ return;
+ }
+ _speechSoundNum = _currentActionObj1Num;
+ _characterSpeechDataPtr = _ptTextBuf;
+ pos = getPositionForLine(_speechSoundNum + 1865, _characterSpeechDataPtr);
+ if (_characterSpeechDataPtr[pos] == '*') {
+ switch (_characterSpeechDataPtr[pos + 1]) {
+ case 'E':
+ ++_flagsTable[200];
+ if (_flagsTable[200] > 6) {
+ _flagsTable[200] = 1;
+ }
+ _speechSoundNum = 262 + _flagsTable[200];
+ break;
+ case 'M':
+ ++_flagsTable[200];
+ if (_flagsTable[200] > 10) {
+ _flagsTable[200] = 1;
+ }
+ _speechSoundNum = 268 + _flagsTable[200];
+ break;
+ case 'R':
+ ++_flagsTable[200];
+ if (_flagsTable[200] > 10) {
+ _flagsTable[200] = 1;
+ }
+ _speechSoundNum = 281 + _flagsTable[200];
+ break;
+ }
+ }
+ _speechSoundNum += 1865;
+ updateCharPositionHelper();
+ return;
+ case 1:
+ if (_locationAnimationsTable[_selectedCharacter2Num].getFlag == 1) {
+ _speechSoundNum = _speechSoundBaseNum + _locationAnimationsTable[_selectedCharacter2Num].inventoryNum;
+ _characterSpeechDataPtr = _ptTextBuf;
+ updateCharPositionHelper();
+ return;
+ } else if (_currentActionObj1Num == 91) {
+ handleSpecialObjectSelectionSequence();
+ _updateCharPositionNewType = 0;
+ return;
+ }
+ break;
+ case 2:
+ _characterSpeechDataPtr = _ptTextBuf;
+ _speechSoundNum = 2175 + _charPosTable[_selectedCharacterNum].description;
+ if (_charPosTable[_selectedCharacterNum].description != 0) {
+ updateCharPositionHelper();
+ return;
+ }
+ break;
+ }
+ }
+ 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) {
+ skip = 1;
+ if (_actionsTable[i].testFlag1Num != 0) {
+ if (_actionsTable[i].testFlag1Num < 500) {
+ if (_flagsTable[_actionsTable[i].testFlag1Num] != _actionsTable[i].testFlag1Value) {
+ skip = 0;
+ }
+ } else if (_inventoryItemsState[_actionsTable[i].testFlag1Num - 500] != _actionsTable[i].testFlag1Value) {
+ skip = 0;
+ }
+ }
+ if (_actionsTable[i].testFlag2Num != 0) {
+ if (_actionsTable[i].testFlag2Num < 500) {
+ if (_flagsTable[_actionsTable[i].testFlag2Num] != _actionsTable[i].testFlag2Value) {
+ skip = 0;
+ }
+ } else if (_inventoryItemsState[_actionsTable[i].testFlag2Num - 500] != _actionsTable[i].testFlag2Value) {
+ skip = 0;
+ }
+ }
+ }
+ if (skip == 0) {
+ ++i;
+ }
+ }
+ if (skip == 0) {
+ playSpeechForAction(_updateCharPositionNewType);
+ _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;
+ _characterFacingDirection = 5;
+ _mainLoopCounter2 = 0;
+ } else {
+ _backgroundSpriteCurrentAnimation = _actionsTable[i].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;
+ _updateCharPositionType = _updateCharPositionNewType;
+ _updateCharPositionNewType = 0;
+}
+
+void TuckerEngine::updateFlagsForCharPosition() {
+ if (_pendingActionDelay != 0) {
+ --_pendingActionDelay;
+ if (_pendingActionDelay > 0) {
+ return;
+ }
+ if (_updateCharPositionType == 3 || _updateCharPositionType == 4 || _updateCharPositionType == 8 || _updateCharPositionType == 2) {
+ _flagsTable[_charPositionFlagNum] = _charPositionFlagValue;
+ } else if (_updateCharPositionType == 6 && _charPositionFlagValue == 1) {
+ addObjectToInventory(_charPositionFlagNum);
+ _forceRedrawPanelItems = 1;
+ }
+ if (_pendingActionIndex > 0) {
+ _nextAction = _pendingActionIndex;
+ }
+ }
+}
+
+void TuckerEngine::backupPalette() {
+ memcpy(_backupPalette, _currentPalette, 256 * 3);
+}
+
+void TuckerEngine::restorePalette() {
+ memcpy(_currentPalette, _backupPalette, 256 * 3);
+}
+
+void TuckerEngine::fadeOutPalette(int colorsCount) {
+ uint8 pal[256 * 4];
+ _system->grabPalette(pal, 0, colorsCount);
+ for (int color = 0; color < colorsCount; ++color) {
+ for (int i = 0; i < 3; ++i) {
+ const int c = int(pal[color * 4 + i]) + kFadePaletteStep * 4;
+ pal[color * 4 + i] = MIN<int>(c, _currentPalette[color * 3 + i]);
+ }
+ }
+ _system->setPalette(pal, 0, colorsCount);
+ _system->updateScreen();
+ _system->delayMillis(20);
+}
+
+void TuckerEngine::fadeInPalette(int colorsCount) {
+ uint8 pal[256 * 4];
+ _system->grabPalette(pal, 0, colorsCount);
+ for (int color = 0; color < colorsCount; ++color) {
+ for (int i = 0; i < 3; ++i) {
+ const int c = int(pal[color * 4 + i]) - kFadePaletteStep * 4;
+ pal[color * 4 + i] = MAX<int>(c, 0);
+ }
+ }
+ _system->setPalette(pal, 0, colorsCount);
+ _system->updateScreen();
+ _system->delayMillis(20);
+}
+
+void TuckerEngine::fadePaletteColor(int color, int step) {
+ uint8 rgb[4];
+ _system->grabPalette(rgb, color, 1);
+ for (int i = 0; i < 3; ++i) {
+ const int c = _currentPalette[color * 3 + i] + step * 4;
+ rgb[i] = MIN(c, 255);
+ }
+ _system->setPalette(rgb, color, 1);
+}
+
+void TuckerEngine::setBlackPalette() {
+ uint8 pal[256 * 4];
+ memset(pal, 0, sizeof(pal));
+ _system->setPalette(pal, 0, 256);
+}
+
+void TuckerEngine::setPaletteColor(int color, int r, int g, int b) {
+ uint8 rgb[4];
+ rgb[0] = r & 255;
+ rgb[1] = g & 255;
+ rgb[2] = b & 255;
+ rgb[3] = 255;
+ _system->setPalette(rgb, color, 1);
+}
+
+void TuckerEngine::updateCursor() {
+ setCursorNum(0);
+ if (_backgroundSpriteCurrentAnimation == -1 && _panelLockedFlag == 0 && _selectedObject.locationObject_locationNum > 0) {
+ _selectedObject.locationObject_locationNum = 0;
+ }
+ if (_locationMaskType > 0 || _selectedObject.locationObject_locationNum > 0 || _pendingActionDelay > 0) {
+ return;
+ }
+ if (_rightMouseButtonPressed) {
+ if (_updateCursorFlag == 0) {
+ ++_actionVerb;
+ if (_actionVerb > 8) {
+ _actionVerb = 0;
+ }
+ _updateCursorFlag = 1;
+ _skipPanelObjectUnderCursor = 1;
+ _actionRequiresTwoObjects = false;
+ }
+ } else {
+ _updateCursorFlag = 0;
+ }
+ if (_skipPanelObjectUnderCursor == 0) {
+ setActionVerbUnderCursor();
+ if (_actionVerb == 0 && _locationNum == 63) {
+ _actionVerb = 8;
+ }
+ }
+ _selectedObjectNum = 0;
+ _selectedObjectType = 0;
+ int num = setCharacterUnderCursor();
+ if (_selectedObjectType == 0) {
+ num = setLocationAnimationUnderCursor();
+ }
+ if (_selectedObjectType > 0) {
+ _selectedObjectNum = num;
+ } else {
+ num = getObjectUnderCursor();
+ if (num > -1) {
+ _selectedObjectNum = _locationObjectsTable[num].textNum;
+ }
+ }
+ handleMouseClickOnInventoryObject();
+ if (_actionVerb == 2 && _selectedObjectType != 2) {
+ _selectedObjectNum = 0;
+ _selectedObjectType = 0;
+ } else if (_actionVerb == 5 && _selectedObjectType != 3 && !_actionRequiresTwoObjects) {
+ _selectedObjectNum = 0;
+ _selectedObjectType = 0;
+ }
+ if (_skipPanelObjectUnderCursor == 0 && _selectedObjectType == 2 && _selectedObjectNum != 21) {
+ _actionVerb = 2;
+ }
+ if (!_actionRequiresTwoObjects) {
+ _actionObj1Num = _selectedObjectNum;
+ _actionObj1Type = _selectedObjectType;
+ _actionObj2Num = 0;
+ _actionObj2Type = 0;
+ } else if (_actionObj1Num == _selectedObjectNum && _actionObj1Type == _selectedObjectType) {
+ _selectedObjectNum = 0;
+ _selectedObjectType = 0;
+ _actionObj2Num = 0;
+ _actionObj2Type = 0;
+ } else {
+ _actionObj2Num = _selectedObjectNum;
+ _actionObj2Type = _selectedObjectType;
+ }
+ if (!_leftMouseButtonPressed) {
+ _mouseClick = 0;
+ }
+ if (_leftMouseButtonPressed && _mouseClick == 0) {
+ _fadedPanel = 0;
+ _mouseClick = 1;
+ clearItemsGfx();
+ drawInfoString();
+ if (_mousePosY >= 150 && _mousePosX < 212) {
+ if (_mousePosX < 200) {
+ setActionVerbUnderCursor();
+ _skipPanelObjectUnderCursor = 1;
+ _actionRequiresTwoObjects = false;
+ } else if (_mousePosY < 175) {
+ moveDownInventoryObjects();
+ } else {
+ moveUpInventoryObjects();
+ }
+ } else {
+ if (_selectedObjectType == 3) {
+ setActionForInventoryObject();
+ } else if (_actionVerb != 0) {
+ _skipPanelObjectUnderCursor = 0;
+ setActionState();
+ } else if (_actionObj1Num == 261 || (_actionObj1Num == 205 && _flagsTable[143] == 0)) {
+ _skipPanelObjectUnderCursor = 0;
+ setActionState();
+ } else {
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ _updateCharPositionNewType = 0;
+ setSelectedObjectKey();
+ }
+ }
+ }
+}
+
+int TuckerEngine::getLastKeyCode() {
+ int keyCode = _keyLastKeyCodePressed;
+ _keyLastKeyCodePressed = 0;
+ return keyCode;
+}
+
+void TuckerEngine::stopSounds() {
+ for (int i = 0; i < _locationSoundsCount; ++i) {
+ stopSound(i);
+ }
+ for (int i = 0; i < _locationMusicsCount; ++i) {
+ stopMusic(i);
+ }
+}
+
+void TuckerEngine::playSounds() {
+ for (int i = 0; i < 29; ++i) {
+ if (i < _locationSoundsCount) {
+ if (_locationSoundsTable[i].type == 1 || _locationSoundsTable[i].type == 2 || _locationSoundsTable[i].type == 5 ||
+ (_locationSoundsTable[i].type == 7 && _flagsTable[_locationSoundsTable[i].flagNum] == _locationSoundsTable[i].flagValueStartFx)) {
+ startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume);
+ }
+ }
+ if (i < _locationMusicsCount) {
+ if (_locationMusicsTable[i].flag > 0) {
+ startMusic(_locationMusicsTable[i].offset, i, _locationMusicsTable[i].volume);
+ }
+ }
+ }
+}
+
+void TuckerEngine::updateCharactersPath() {
+ int i = 0;
+ int flag = 0;
+ if (_panelLockedFlag == 0) {
+ return;
+ }
+ if (_backgroundSpriteCurrentAnimation != -1 && _locationNum != 25) {
+ if (_xPosCurrent == _selectedObject.xPos && _yPosCurrent == _selectedObject.yPos) {
+ _locationMaskCounter = 1;
+ _panelLockedFlag = 0;
+ }
+ return;
+ }
+ int xPos = _xPosCurrent;
+ int yPos = _yPosCurrent;
+ if (_characterFacingDirection == 5) {
+ _characterPrevFacingDirection = 5;
+ }
+ if (_yPosCurrent > _selectedObject.yPos) {
+ if (testLocationMask(_xPosCurrent, _yPosCurrent - 1) == 1) {
+ --_yPosCurrent;
+ _characterFacingDirection = 4;
+ flag = 1;
+ } else {
+ ++i;
+ }
+ } else if (_yPosCurrent < _selectedObject.yPos) {
+ if (testLocationMask(_xPosCurrent, _yPosCurrent + 1) == 1) {
+ ++_yPosCurrent;
+ _characterFacingDirection = 2;
+ flag = 1;
+ } else {
+ ++i;
+ }
+ }
+ if (_xPosCurrent > _selectedObject.xPos) {
+ if (testLocationMask(_xPosCurrent - 1, _yPosCurrent) == 1) {
+ --_xPosCurrent;
+ _characterFacingDirection = 3;
+ _characterBackFrontFacing = 0;
+ flag = 1;
+ } else {
+ ++i;
+ }
+ } else if (_xPosCurrent < _selectedObject.xPos) {
+ if (testLocationMask(_xPosCurrent + 1, _yPosCurrent) == 1) {
+ ++_xPosCurrent;
+ _characterFacingDirection = 1;
+ _characterBackFrontFacing = 1;
+ flag = 1;
+ } else {
+ ++i;
+ }
+ }
+ if (flag == 0) {
+ if (_selectedObjectLocationMask == 1) {
+ _selectedObjectLocationMask = 0;
+ _selectedObject.xPos = _selectedObject.xDefaultPos;
+ _selectedObject.yPos = _selectedObject.yDefaultPos;
+ } else {
+ _panelLockedFlag = 0;
+ _characterFacingDirection = 0;
+ if (_xPosCurrent == _selectedObject.xPos && _yPosCurrent == _selectedObject.yPos) {
+ _locationMaskCounter = 1;
+ }
+ }
+ }
+ if (_locationNum == 25) {
+ if ((_backgroundSpriteCurrentAnimation == 3 || _characterBackFrontFacing != 0) && (_backgroundSpriteCurrentAnimation != 6 || _characterBackFrontFacing != 1)) {
+ _xPosCurrent = xPos;
+ _yPosCurrent = yPos;
+ return;
+ }
+ }
+ if (_xPosCurrent != _selectedObject.xPos || _yPosCurrent != _selectedObject.yPos) {
+ return;
+ }
+ if (_selectedObjectLocationMask != 0) {
+ return;
+ }
+ _locationMaskCounter = 1;
+ _panelLockedFlag = 0;
+ _locationMaskIgnore = 0;
+ if (_characterPrevFacingDirection <= 0 || _characterPrevFacingDirection >= 5) {
+ return;
+ }
+ if (_selectedObject.locationObject_locationNum == 0) {
+ _characterFacingDirection = 5;
+ while (_spriteAnimationFramesTable[_spriteAnimationFrameIndex] != 999) {
+ ++_spriteAnimationFrameIndex;
+ }
+ ++_spriteAnimationFrameIndex;
+ }
+}
+
+void TuckerEngine::setSoundVolumeDistance() {
+ int w = ABS(_xPosCurrent - _currentFxDist);
+ int d = w * _currentFxScale / 10;
+ int volume = (d > _currentFxVolume) ? 0 : _currentFxVolume - d;
+ setVolumeSound(_currentFxIndex, volume);
+}
+
+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;
+ } else {
+ _locationAnimationsTable[i].drawFlag = (_inventoryItemsState[_locationAnimationsTable[i].inventoryNum] == 0) ? 1 : 0;
+ }
+ }
+}
+
+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;
+ } else {
+ ++_locationAnimationsTable[i].animCurrentCounter;
+ }
+ const int index = _locationAnimationsTable[i].animCurrentCounter;
+ if (_staticData3Table[index] == 998) {
+ _flagsTable[_staticData3Table[index + 1]] = _staticData3Table[index + 2];
+ _locationAnimationsTable[i].animCurrentCounter = _locationAnimationsTable[i].animInitCounter;
+ _locationAnimationsTable[i].drawFlag = 0;
+ }
+ _locationAnimationsTable[i].graphicNum = _staticData3Table[_locationAnimationsTable[i].animCurrentCounter];
+ }
+ }
+ updateData3DrawFlag();
+}
+
+void TuckerEngine::updateSfxData3_1() {
+ for (int i = 0; i < _locationSoundsCount; ++i) {
+ if ((_locationSoundsTable[i].type == 6 || _locationSoundsTable[i].type == 7) && _locationSoundsTable[i].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;
+ }
+ 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;
+ stopSound(i);
+ }
+ }
+ }
+ }
+ }
+}
+
+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;
+ }
+ 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;
+ stopSound(i);
+ }
+ }
+ }
+ }
+}
+
+void TuckerEngine::saveOrLoad() {
+ if (!_leftMouseButtonPressed) {
+ _mouseClick = 0;
+ }
+ if (_firstSaveGameSlot > 0) {
+ drawSpeechText(_scrollOffset + 120, 170, _infoBarBuf, _mouseClickOnPanelSliders + 19, 102);
+ int len = getStringWidth(_mouseClickOnPanelSliders + 19, _infoBarBuf);
+ drawStringInteger(_firstSaveGameSlot, len / 2 + 128, 160, 2);
+ } else {
+ drawSpeechText(_scrollOffset + 120, 170, _infoBarBuf, 21, 102);
+ }
+ if (_leftMouseButtonPressed && _mouseClick == 0) {
+ _mouseClick = 1;
+ if (_mousePosX > 228 && _mousePosX < 240 && _mousePosY > 154 & _mousePosY < 170) {
+ if (_firstSaveGameSlot < _lastSaveGameSlot) {
+ ++_firstSaveGameSlot;
+ _forceRedrawPanelItems = 1;
+ }
+ return;
+ }
+ if (_mousePosX > 228 && _mousePosX < 240 && _mousePosY > 170 && _mousePosY < 188) {
+ if (_firstSaveGameSlot > 1) {
+ --_firstSaveGameSlot;
+ _forceRedrawPanelItems = 1;
+ }
+ return;
+ }
+ if (_mousePosX > 244 && _mousePosX < 310 && _mousePosY > 170 && _mousePosY < 188) {
+ _forceRedrawPanelItems = 1;
+ _panelState = 2;
+ return;
+ }
+ if (_mousePosX > 260 && _mousePosX < 290 && _mousePosY > 152 && _mousePosY < 168) {
+ if (_mouseClickOnPanelSliders == 1) {
+ saveGame(_firstSaveGameSlot);
+ } else if (_firstSaveGameSlot > 0) {
+ loadGame(_firstSaveGameSlot);
+ }
+ _forceRedrawPanelItems = 1;
+ _panelState = 0;
+ setCursorType(0);
+ return;
+ }
+ }
+}
+
+void TuckerEngine::handleMouseOnPanel() {
+ if (!_leftMouseButtonPressed) {
+ _mouseClick = 0;
+ }
+ if (_leftMouseButtonPressed && _mouseClick == 0) {
+ _mouseClick = 1;
+ if (_mousePosY < 160 || _mousePosY > 176) {
+ return;
+ }
+ if (_mousePosX < 45 || _mousePosX > 275) {
+ return;
+ }
+ if (_mousePosX < 96) {
+ _mouseClickOnPanelSliders = 0;
+ _forceRedrawPanelItems = 1;
+ _panelState = 3;
+ _firstSaveGameSlot = _currentSaveGameSlot;
+ _lastSaveGameSlot = _maxSaveGameSlot;
+ } else if (_mousePosX < 158) {
+ _mouseClickOnPanelSliders = 1;
+ _forceRedrawPanelItems = 1;
+ _panelState = 3;
+ if (_maxSaveGameSlot < 99) {
+ _firstSaveGameSlot = _maxSaveGameSlot + 1;
+ _lastSaveGameSlot = _firstSaveGameSlot;
+ } else {
+ _lastSaveGameSlot = 99;
+ if (_currentSaveGameSlot < 99) {
+ _firstSaveGameSlot = _currentSaveGameSlot + 1;
+ } else {
+ _firstSaveGameSlot = 1;
+ }
+ }
+ } else if (_mousePosX < 218) {
+ _forceRedrawPanelItems = 1;
+ _panelState = 0;
+ setCursorType(0);
+ } else {
+ _quitGame = 1;
+ }
+ }
+}
+
+void TuckerEngine::switchPanelType() {
+ if (_panelState == 0 && _switchPanelFlag == 0 && _lastKeyPressed == Common::KEYCODE_F1) {
+ _switchPanelFlag = 1;
+ _switchPanelCounter = 1;
+ return;
+ }
+ if (_switchPanelFlag == 0) {
+ return;
+ }
+ if (_switchPanelFlag == 1) {
+ if (_switchPanelCounter == 25) {
+ if (_panelNum == 0) {
+ _panelNum = 1;
+ } else {
+ _panelNum = 0;
+ }
+ _switchPanelFlag = 2;
+ loadPanel();
+ _forceRedrawPanelItems = 1;
+ } else {
+ ++_switchPanelCounter;
+ }
+ } else {
+ --_switchPanelCounter;
+ if (_switchPanelCounter == 0) {
+ _switchPanelFlag = 0;
+ }
+ }
+}
+
+void TuckerEngine::redrawPanelOverBackground() {
+ const uint8 *src = _itemsGfxBuf;
+ uint8 *dst = _locationBackgroundGfxBuf + 89600 + _scrollOffset;
+ for (int y = 0; y < 10; ++y) {
+ memcpy(dst, src, 320);
+ src += 320;
+ dst += 640;
+ }
+ for (int y = 0; y < _switchPanelCounter; ++y) {
+ for (int x = 0; x < 320; ++x) {
+ dst[x] = 0;
+ }
+ dst += 640;
+ }
+ int y2 = 50 - _switchPanelCounter * 2;
+ for (int y = 0; y < y2; ++y) {
+ int i = y * 50 / y2;
+ memcpy(dst, src + i * 320, 320);
+ dst += 640;
+ }
+ for (int y = 0; y < _switchPanelCounter; ++y) {
+ for (int x = 0; x < 320; ++x) {
+ dst[x] = 0;
+ }
+ dst += 640;
+ }
+ if (_conversationOptionsCount > 0) {
+ drawConversationTexts();
+ }
+}
+
+void TuckerEngine::drawConversationTexts() {
+ int x = 0;
+ int y = 141;
+ int flag = 0;
+ for (int i = 0; i < _conversationOptionsCount; ++i) {
+ int color = 108;
+ if ((_mousePosY > y && _mousePosY < y + 11) || _nextTableToLoadIndex == i) {
+ color = 106;
+ }
+ drawSpeechText(x, y, _characterSpeechDataPtr, _instructionsActionsTable[i], color);
+ if (_mousePosY > y && _mousePosY < _panelItemWidth * 10 + y + 1) {
+ _nextTableToLoadIndex = i;
+ flag = 1;
+ }
+ y += _panelItemWidth * 10;
+ }
+ if (flag == 0) {
+ _nextTableToLoadIndex = -1;
+ }
+}
+
+void TuckerEngine::updateScreenScrolling() {
+ if (_locationWidthTable[_locationNum] != 2) {
+ _scrollOffset = 0;
+ } else if (_validInstructionId == 1) {
+ _scrollOffset = _xPosCurrent - 200;
+ } else if (_locationNum == 16 && _backgroundSpriteCurrentAnimation == 6 && _scrollOffset + 200 < _xPosCurrent) {
+ ++_scrollOffset;
+ if (_scrollOffset > 320) {
+ _scrollOffset = 320;
+ }
+ } else if (_scrollOffset + 120 > _xPosCurrent) {
+ _scrollOffset = _xPosCurrent - 120;
+ if (_scrollOffset < 0) {
+ _scrollOffset = 0;
+ }
+ } else if (_scrollOffset + 200 < _xPosCurrent) {
+ _scrollOffset = _xPosCurrent - 200;
+ if (_scrollOffset > 320) {
+ _scrollOffset = 320;
+ }
+ }
+}
+
+void TuckerEngine::updateGameHints() {
+ if (_gameHintsIndex == 0 && _flagsTable[3] > 0) {
+ _gameHintsIndex = 1;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ } else if (_gameHintsIndex == 1 && _flagsTable[12] > 0) {
+ _gameHintsIndex = 2;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ } else if (_gameHintsIndex == 2 && _flagsTable[20] > 0) {
+ _gameHintsIndex = 3;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ } else if (_gameHintsIndex == 3 && _flagsTable[9] > 0) {
+ _gameHintsIndex = 4;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ } else if (_gameHintsIndex == 4 && _flagsTable[23] > 0) {
+ _gameHintsIndex = 5;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ } else if (_flagsTable[19] > 0) {
+ _gameHintsIndex = 6;
+ _gameHintsCounter = 0;
+ _gameHintsDisplayText = 0;
+ }
+ ++_gameHintsCounter;
+ if (_gameHintsCounter > 1500) {
+ _gameHintsDisplayText = 1;
+ }
+}
+
+void TuckerEngine::startCharacterSounds() {
+ if (_characterSoundFxDelayCounter != 0) {
+ --_characterSoundFxDelayCounter;
+ if (_characterSoundFxDelayCounter <= 0) {
+ startSound(_locationSoundsTable[_characterSoundFxNum].offset, _characterSoundFxNum, _locationSoundsTable[_characterSoundFxNum].volume);
+ }
+ }
+}
+
+void TuckerEngine::updateSoundsTypes3_4() {
+ if (isSoundPlaying(0)) {
+ return;
+ }
+ for (int i = 0; i < _locationSoundsCount; ++i) {
+ switch (_locationSoundsTable[i].type) {
+ case 3:
+ if (getRandomNumber() >= 32300) {
+ startSound(_locationSoundsTable[i].offset, 0, _locationSoundsTable[i].volume);
+ return;
+ }
+ break;
+ case 4:
+ if (getRandomNumber() >= 32763) {
+ startSound(_locationSoundsTable[i].offset, 0, _locationSoundsTable[i].volume);
+ return;
+ }
+ break;
+ }
+ }
+}
+
+void TuckerEngine::drawData3() {
+ for (int i = 0; i < _locationAnimationsCount; ++i) {
+ int num = _locationAnimationsTable[i].graphicNum;
+ const int offset = _dataTable[num].yDest * 640 + _dataTable[num].xDest;
+ if (_locationAnimationsTable[i].drawFlag != 0) {
+ Graphics::decodeRLE(_locationBackgroundGfxBuf + offset, _data3GfxBuf + _dataTable[num].sourceOffset, _dataTable[num].xSize, _dataTable[num].ySize);
+ }
+ }
+}
+
+void TuckerEngine::execData3PreUpdate() {
+ switch (_locationNum) {
+ case 1:
+ execData3PreUpdate_locationNum1();
+ break;
+ case 2:
+ execData3PreUpdate_locationNum2();
+ break;
+ case 3:
+ execData3PreUpdate_locationNum3();
+ break;
+ case 4:
+ execData3PreUpdate_locationNum4();
+ break;
+ case 6:
+ execData3PreUpdate_locationNum6();
+ break;
+ case 9:
+ execData3PreUpdate_locationNum9();
+ break;
+ case 10:
+ execData3PreUpdate_locationNum10();
+ break;
+ case 12:
+ execData3PreUpdate_locationNum12();
+ break;
+ case 13:
+ execData3PreUpdate_locationNum13();
+ break;
+ case 14:
+ if (_yPosCurrent > 126) {
+ execData3PreUpdate_locationNum14();
+ }
+ break;
+ case 15:
+ execData3PreUpdate_locationNum15();
+ break;
+ case 16:
+ execData3PreUpdate_locationNum16();
+ break;
+ case 19:
+ execData3PreUpdate_locationNum19();
+ break;
+ case 21:
+ execData3PreUpdate_locationNum21();
+ break;
+ case 22:
+ execData3PreUpdate_locationNum22();
+ break;
+ case 24:
+ execData3PreUpdate_locationNum24();
+ break;
+ case 25:
+ execData3PreUpdate_locationNum25();
+ break;
+ case 26:
+ execData3PreUpdate_locationNum26();
+ break;
+ case 27:
+ execData3PreUpdate_locationNum27();
+ break;
+ case 28:
+ execData3PreUpdate_locationNum28();
+ break;
+ case 29:
+ execData3PreUpdate_locationNum29();
+ break;
+ case 30:
+ execData3PreUpdate_locationNum30();
+ break;
+ case 31:
+ execData3PreUpdate_locationNum31();
+ break;
+ case 32:
+ execData3PreUpdate_locationNum32();
+ break;
+ case 33:
+ execData3PreUpdate_locationNum33();
+ break;
+ case 34:
+ execData3PreUpdate_locationNum34();
+ break;
+ case 35:
+ execData3PreUpdate_locationNum35();
+ break;
+ case 36:
+ execData3PreUpdate_locationNum36();
+ break;
+ case 38:
+ execData3PreUpdate_locationNum38();
+ break;
+ case 41:
+ execData3PreUpdate_locationNum41();
+ break;
+ case 42:
+ execData3PreUpdate_locationNum42();
+ break;
+ case 43:
+ execData3PreUpdate_locationNum43();
+ break;
+ case 44:
+ execData3PreUpdate_locationNum44();
+ break;
+ case 49:
+ execData3PreUpdate_locationNum49();
+ break;
+ case 52:
+ execData3PreUpdate_locationNum52();
+ break;
+ case 53:
+ execData3PreUpdate_locationNum53();
+ break;
+ case 57:
+ execData3PreUpdate_locationNum57();
+ break;
+ case 58:
+ execData3PreUpdate_locationNum58();
+ break;
+ case 61:
+ execData3PreUpdate_locationNum61();
+ break;
+ case 63:
+ execData3PreUpdate_locationNum63();
+ break;
+ case 64:
+ execData3PreUpdate_locationNum64();
+ break;
+ case 65:
+ execData3PreUpdate_locationNum65();
+ break;
+ case 66:
+ execData3PreUpdate_locationNum66();
+ break;
+ case 70:
+ execData3PreUpdate_locationNum70();
+ break;
+ }
+}
+
+void TuckerEngine::drawBackgroundSprites(int flipX) {
+ if (_backgroundSpriteDataPtr && _backgroundSpriteCurrentFrame != 0 && _backgroundSpriteCurrentFrame <= _backgroundSpriteLastFrame) {
+ int frameOffset = READ_LE_UINT24(_backgroundSpriteDataPtr + _backgroundSpriteCurrentFrame * 4);
+ int srcW = READ_LE_UINT16(_backgroundSpriteDataPtr + frameOffset);
+ int srcH = READ_LE_UINT16(_backgroundSpriteDataPtr + frameOffset + 2);
+ int srcX = READ_LE_UINT16(_backgroundSpriteDataPtr + frameOffset + 8);
+ int srcY = READ_LE_UINT16(_backgroundSpriteDataPtr + frameOffset + 10);
+ if (_locationNum == 22 && _backgroundSpriteCurrentAnimation > 1) {
+ srcY += _mainSpritesBaseOffset;
+ }
+ if (_locationNum == 29 && _backgroundSpriteCurrentAnimation == 3) {
+ srcX += 228;
+ } else if (_locationNum == 58 && _backgroundSpriteCurrentAnimation == 1) {
+ srcX += 100;
+ } else if (_xPosCurrent > 320 && _xPosCurrent < 640) {
+ srcX += 320;
+ }
+ int offset = _backgroundSprOffset + srcY * 640 + srcX;
+ Graphics::decodeRLE_248(_locationBackgroundGfxBuf + offset, _backgroundSpriteDataPtr + frameOffset + 12, srcW, srcH, 0, _locationHeightTable[_locationNum], flipX);
+ }
+}
+
+void TuckerEngine::setVolumeSound(int index, int volume) {
+ if (volume < 0) {
+ volume = 0;
+ }
+ _mixer->setChannelVolume(_sfxHandles[index], volume * Audio::Mixer::kMaxChannelVolume / kMaxSoundVolume);
+}
+
+void TuckerEngine::setVolumeMusic(int index, int volume) {
+ if (volume < 0) {
+ volume = 0;
+ }
+ _mixer->setChannelVolume(_musicHandles[index], volume * Audio::Mixer::kMaxChannelVolume / kMaxSoundVolume);
+}
+
+void TuckerEngine::startSound(int offset, int index, int volume) {
+ bool loop = (_locationSoundsTable[index].type == 2 || _locationSoundsTable[index].type == 5 || _locationSoundsTable[index].type == 7);
+ loadSound(Audio::Mixer::kSFXSoundType, _locationSoundsTable[index].num, volume, loop, &_sfxHandles[index]);
+}
+
+void TuckerEngine::stopSound(int index) {
+ _mixer->stopHandle(_sfxHandles[index]);
+}
+
+bool TuckerEngine::isSoundPlaying(int index) {
+ return _mixer->isSoundHandleActive(_sfxHandles[index]);
+}
+
+void TuckerEngine::startMusic(int offset, int index, int volume) {
+ bool loop = (_locationMusicsTable[index].flag == 2);
+ loadSound(Audio::Mixer::kMusicSoundType, _locationMusicsTable[index].num, volume, loop, &_musicHandles[index]);
+}
+
+void TuckerEngine::stopMusic(int index) {
+ _mixer->stopHandle(_musicHandles[index]);
+}
+
+void TuckerEngine::startSpeechSound(int num, int volume) {
+ loadSound(Audio::Mixer::kSpeechSoundType, num, volume, false, &_speechHandle);
+}
+
+bool TuckerEngine::isSpeechSoundPlaying() {
+ return _mixer->isSoundHandleActive(_speechHandle);
+}
+
+void TuckerEngine::redrawPanelItems() {
+ const uint8 *src;
+ uint8 *dst;
+ int sz;
+ if (_forceRedrawPanelItems != 0 || (_redrawPanelItemsCounter != 0 && _panelState == 0)) {
+ _forceRedrawPanelItems = 0;
+ if (_redrawPanelItemsCounter > 0) {
+ --_redrawPanelItemsCounter;
+ }
+ switch (_panelState) {
+ case 0:
+ src = _panelGfxBuf;
+ dst = _itemsGfxBuf + 3200;
+ sz = 16000;
+ break;
+ case 1:
+ src = _panelGfxBuf + 16320;
+ dst = _itemsGfxBuf;
+ sz = 19200;
+ break;
+ case 2:
+ src = _panelGfxBuf + 16320;
+ dst = _itemsGfxBuf;
+ sz = 19200;
+ memcpy(dst, src, sz);
+ src = _panelGfxBuf + 55040;
+ dst = _itemsGfxBuf + 6400;
+ sz = 5120;
+ break;
+ case 3:
+ src = _panelGfxBuf + 35200;
+ dst = _itemsGfxBuf;
+ sz = 19200;
+ break;
+ }
+ memcpy(dst, src, sz);
+ if (_panelState == 0) {
+ redrawPanelItemsHelper();
+ }
+ }
+}
+
+void TuckerEngine::redrawPanelItemsHelper() {
+ const int k = (_redrawPanelItemsCounter / 4) - ((_redrawPanelItemsCounter / 8) * 2);
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ if (i * 3 + j + _inventoryObjectsOffset >= _inventoryObjectsCount) {
+ continue;
+ }
+ if (i * 3 + j + _inventoryObjectsOffset == _lastInventoryObjectIndex && k != 0) {
+ continue;
+ }
+ const int obj = _inventoryObjectsList[i * 3 + j + _inventoryObjectsOffset];
+ const uint8 *src = _panelObjectsGfxBuf + _panelObjectsOffsetTable[obj];
+ uint8 *dst = _itemsGfxBuf + 3412 + i * 8320 + j * 34;
+ Graphics::decodeRLE_320(dst, src, 32, 24);
+ }
+ }
+}
+
+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);
+ }
+ }
+ }
+}
+
+void TuckerEngine::clearItemsGfx() {
+ memset(_itemsGfxBuf, 0, 3200);
+}
+
+void TuckerEngine::drawPausedInfoBar() {
+ int len = getStringWidth(36, _infoBarBuf);
+ int x = 159 - len / 2;
+ drawString(_itemsGfxBuf + 326 + x, 36, _infoBarBuf);
+}
+
+const uint8 *TuckerEngine::getStringBuf(int type) const {
+ const uint8 *p = 0;
+ switch (type) {
+ case 0:
+ p = _data5Buf;
+ break;
+ case 1:
+ p = _bgTextBuf;
+ break;
+ case 2:
+ p = _charNameBuf;
+ break;
+ case 3:
+ p = _objTxtBuf;
+ break;
+ }
+ return p;
+}
+
+void TuckerEngine::drawInfoString() {
+ const uint8 *infoStrBuf = _infoBarBuf;
+ const uint8 *obj1StrBuf = getStringBuf(_actionObj1Type);
+ const uint8 *obj2StrBuf = 0;
+ int infoStringWidth = 0;
+ int object1NameWidth = 0;
+ int verbWidth = getStringWidth(_actionVerb + 1, infoStrBuf);
+ if (_actionObj1Num > 0 || _actionObj1Type > 0) {
+ object1NameWidth = getStringWidth(_actionObj1Num + 1, obj1StrBuf) + 4;
+ infoStringWidth = verbWidth + object1NameWidth;
+ } else {
+ infoStringWidth = verbWidth;
+ }
+ int verbPreposition = 0;
+ int verbPrepositionWidth = 0;
+ if (_actionRequiresTwoObjects) {
+ verbPreposition = (_actionVerb == 5) ? 12 : 11;
+ verbPrepositionWidth = getStringWidth(verbPreposition, infoStrBuf) + 4;
+ if ((_actionObj2Num > 0 || _actionObj2Type > 0) && verbPreposition > 0) {
+ infoStringWidth = 0;
+ verbWidth = 0;
+ object1NameWidth = 0;
+ }
+ infoStringWidth += verbPrepositionWidth;
+ obj2StrBuf = getStringBuf(_actionObj2Type);
+ if (_actionObj2Num > 0 && _actionObj2Type > 0) {
+ infoStringWidth += getStringWidth(_actionObj2Num + 1, obj2StrBuf);
+ }
+ }
+ const int xPos = 159 - infoStringWidth / 2;
+ if (verbPreposition == 0 || (_actionObj2Num == 0 && _actionObj2Type == 0)) {
+ drawString(_itemsGfxBuf + xPos, _actionVerb + 1, infoStrBuf);
+ if (_actionObj1Num != 0 || _actionObj1Type != 0) {
+ drawString(_itemsGfxBuf + 4 + xPos + verbWidth, _actionObj1Num + 1, obj1StrBuf);
+ }
+ }
+ if (verbPreposition > 0) {
+ drawString(_itemsGfxBuf + xPos + 4 + verbWidth + object1NameWidth, verbPreposition, infoStrBuf);
+ if (_actionObj2Num != 0 || _actionObj2Type != 0) {
+ drawString(_itemsGfxBuf + xPos + 4 + verbWidth + object1NameWidth + verbPrepositionWidth, _actionObj2Num + 1, obj2StrBuf);
+ }
+ }
+}
+
+void TuckerEngine::drawGameHintString() {
+ int len = getStringWidth(_mouseButton2 + 29, _infoBarBuf);
+ int x = 159 - len / 2;
+ drawString(_itemsGfxBuf + 326 + x, _mouseButton2 + 29, _infoBarBuf);
+}
+
+void TuckerEngine::updateCharacterAnimation() {
+ if (_characterAnimationIndex > -1) {
+ if (_backgroundSpriteCurrentFrame == 0) {
+ _backgroundSpriteCurrentAnimation = _characterAnimationsTable[_characterAnimationIndex];
+ ++_characterAnimationIndex;
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ _backgroundSpriteCurrentFrame = _characterAnimationsTable[_characterAnimationIndex];
+ ++_characterAnimationIndex;
+ } else if (_characterAnimationsTable[_characterAnimationIndex] == 99) {
+ _characterAnimationIndex = -1;
+ _backgroundSpriteCurrentAnimation = -1;
+ if (_nextAction == 0) {
+ setCursorType(0);
+ }
+ } else {
+ _backgroundSpriteCurrentFrame = _characterAnimationsTable[_characterAnimationIndex];
+ if (_noCharacterAnimationChange == 0) {
+ ++_characterAnimationIndex;
+ }
+ }
+ } else if (_backgroundSpriteCurrentAnimation > -1) {
+ while (_spriteAnimationFramesTable[_spriteAnimationFrameIndex] != 999) {
+ ++_spriteAnimationFrameIndex;
+ }
+ _characterFacingDirection = 0;
+ if (_changeBackgroundSprite == 1) {
+ if (_backgroundSpriteCurrentFrame == 0) {
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteCurrentFrame = _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ } else {
+ --_backgroundSpriteCurrentFrame;
+ if (_backgroundSpriteCurrentFrame > 1) {
+ _backgroundSpriteCurrentAnimation = -1;
+ _backgroundSpriteCurrentFrame = 0;
+ _changeBackgroundSprite = 0;
+ if (_nextAction == 0) {
+ setCursorType(0);
+ }
+ }
+ }
+ } else {
+ if (_backgroundSpriteCurrentFrame == 0) {
+ _backgroundSpriteCurrentFrame = 1;
+ assert(_backgroundSpriteCurrentAnimation >= 0 && _backgroundSpriteCurrentAnimation < kSprA02TableSize);
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ } else if (_locationNum == 25 && _panelLockedFlag != 1 && (_backgroundSpriteCurrentAnimation == 3 || _backgroundSpriteCurrentAnimation == 6)) {
+ _backgroundSpriteCurrentFrame = 0;
+ _backgroundSpriteCurrentAnimation = -1;
+ } else {
+ ++_backgroundSpriteCurrentFrame;
+ if (_backgroundSpriteCurrentFrame > _backgroundSpriteLastFrame) {
+ _backgroundSpriteCurrentAnimation = -1;
+ _backgroundSpriteCurrentFrame = 0;
+ if (_nextAction == 0 && _panelState == 0) {
+ setCursorType(0);
+ }
+ }
+ }
+ }
+ }
+ if (_locationNum == 24 && _flagsTable[103] == 0) {
+ if (_panelLockedFlag == 1) {
+ _panelLockedFlag = 0;
+ _selectedObject.locationObject_locationNum = 0;
+ if (_actionVerb != 2) {
+ _speechSoundNum = 2236;
+ startSpeechSound(_speechSoundNum, _speechVolume);
+ _characterSpeechDataPtr = _ptTextBuf + getPositionForLine(_speechSoundNum, _ptTextBuf);
+ _speechSoundNum = 0;
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ setCursorType(2);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+
+ }
+ }
+ if (_charSpeechSoundCounter == 0 || _actionCharacterNum != 99) {
+ if (_backgroundSpriteCurrentAnimation == 5) {
+ _backgroundSpriteCurrentFrame = 0;
+ }
+ } else {
+ if (_backgroundSpriteCurrentAnimation != 5) {
+ _backgroundSpriteCurrentFrame = 0;
+ }
+ }
+ if (_backgroundSpriteCurrentFrame == 0) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 99) {
+ _backgroundSpriteCurrentAnimation = 5;
+ } else {
+ _backgroundSpriteCurrentAnimation = (getRandomNumber() < 33000) ? 2 : 3;
+ }
+ _backgroundSpriteCurrentFrame = 1;
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ }
+ } else if (_locationNum == 25) {
+ if (_backgroundSpriteCurrentFrame == 0) {
+ if (_characterBackFrontFacing == 0) {
+ if (_characterBackFrontFacing != _characterPrevBackFrontFacing) {
+ _backgroundSpriteCurrentAnimation = 10;
+ } else if (_panelLockedFlag == 1) {
+ _backgroundSpriteCurrentAnimation = 3;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 99) {
+ _backgroundSpriteCurrentAnimation = 8;
+ } else {
+ _backgroundSpriteCurrentAnimation = (getRandomNumber() < 32000) ? 11 : 5;
+ }
+ } else {
+ if (_characterBackFrontFacing != _characterPrevBackFrontFacing) {
+ _backgroundSpriteCurrentAnimation = 2;
+ } else if (_panelLockedFlag == 1) {
+ _backgroundSpriteCurrentAnimation = 6;
+ } else if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 99) {
+ _backgroundSpriteCurrentAnimation = 9;
+ } else {
+ _backgroundSpriteCurrentAnimation = (getRandomNumber() < 32000) ? 12 : 7;
+ }
+ }
+ _characterPrevBackFrontFacing = _characterBackFrontFacing;
+ _backgroundSpriteCurrentFrame = 1;
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ }
+ _backgroundSprOffset = _xPosCurrent - 160;
+ } else if (_locationNum == 63 && _backgroundSpriteCurrentFrame == 0) {
+ if (_charSpeechSoundCounter > 0 && _actionCharacterNum == 99) {
+ _backgroundSpriteCurrentAnimation = 1;
+ } else {
+ _backgroundSpriteCurrentAnimation = (getRandomNumber() < 32000) ? 3 : 2;
+ }
+ _backgroundSpriteCurrentFrame = 1;
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ }
+ int var8 = _spriteAnimationFramesTable[_spriteAnimationFrameIndex];
+ if (_panelLockedFlag == 0 && _characterFacingDirection < 5 && _selectedObject.locationObject_locationNum == 0) {
+ _characterFacingDirection = 0;
+ }
+ if (_charSpeechSoundCounter > 0 && _characterFacingDirection == 6 && _actionCharacterNum == 99) {
+ _characterFacingDirection = 6;
+ var8 = 999;
+ } else {
+ if (_characterFacingDirection == 6 && _charSpeechSoundCounter != 0 && _actionCharacterNum != 99) {
+ _characterFacingDirection = 0;
+ var8 = 999;
+ }
+ }
+ int num;
+ if (var8 == 999 || (_characterFacingDirection != _characterPrevFacingDirection && _characterFacingDirection < 5)) {
+ _mirroredDrawing = 0;
+ if (_characterFacingDirection == 6) {
+ if (_csDataHandled != 0) {
+ if (_selectedCharacterDirection == 1) {
+ num = 17;
+ } else if (_selectedCharacterDirection == 2) {
+ num = 16;
+ } else if (_selectedCharacterDirection == 4) {
+ num = 15;
+ } else {
+ num = 16;
+ _mirroredDrawing = 1;
+ }
+ } else {
+ num = 15;
+ }
+ }
+ if (_characterFacingDirection == 5) {
+ _characterFacingDirection = 0;
+ }
+ if (_characterFacingDirection == 0) {
+ if (_csDataHandled != 0) {
+ _mirroredDrawing = 0;
+ if (_selectedCharacterDirection == 1) {
+ num = 3;
+ } else if (_selectedCharacterDirection == 2) {
+ num = 1; // 2 ?
+ } else if (_selectedCharacterDirection == 3) {
+ num = 1;
+ _mirroredDrawing = 1;
+ } else {
+ num = 5;
+ }
+ } else if (getRandomNumber() < 2000) {
+ num = 13;
+ } else if (getRandomNumber() < 3000) {
+ num = 14;
+ if (_locationNum == 57) {
+ num = 18;
+ }
+ } else {
+ num = (getRandomNumber() < 20000) ? 18 : 6;
+ }
+ } else {
+ if (_characterFacingDirection == 1) {
+ num = 0;
+ } else if (_characterFacingDirection == 2) {
+ num = 4;
+ } else if (_characterFacingDirection == 3) {
+ num = 0;
+ _mirroredDrawing = 1;
+ } else if (_characterFacingDirection == 4) {
+ num = 2;
+ }
+ }
+ _currentSpriteAnimationLength = _spriteAnimationsTable[num].numParts;
+ _spriteAnimationFrameIndex = _spriteAnimationsTable[num].firstFrameIndex;
+ var8 = _spriteAnimationFramesTable[_spriteAnimationFrameIndex];
+ }
+ if (_characterAnimationNum > 0) {
+ num = _characterAnimationNum;
+ _currentSpriteAnimationLength = _spriteAnimationsTable[num].numParts;
+ _spriteAnimationFrameIndex = _spriteAnimationsTable[num].firstFrameIndex;
+ var8 = _spriteAnimationFramesTable[_spriteAnimationFrameIndex];
+ _characterAnimationNum = 0;
+ }
+ _currentSpriteAnimationFrame = var8;
+ ++_spriteAnimationFrameIndex;
+ if (_currentSpriteAnimationLength > 1) {
+ _currentSpriteAnimationFrame2 = _spriteAnimationFramesTable[_spriteAnimationFrameIndex];
+ ++_spriteAnimationFrameIndex;
+ if (_characterSpriteAnimationFrameCounter > 0) {
+ ++_characterSpriteAnimationFrameCounter;
+ if (_characterSpriteAnimationFrameCounter > 121) {
+ _characterSpriteAnimationFrameCounter = 0;
+ }
+ if (_selectedCharacterDirection == 1) {
+ _currentSpriteAnimationFrame = (_characterSpriteAnimationFrameCounter > 2 && _characterSpriteAnimationFrameCounter < 120) ? 122 : 121;
+ } else {
+ _currentSpriteAnimationFrame = (_characterSpriteAnimationFrameCounter > 2 && _characterSpriteAnimationFrameCounter < 120) ? 120 : 119;
+ }
+ }
+ }
+ _characterPrevFacingDirection = _characterFacingDirection;
+}
+
+void TuckerEngine::execData3PostUpdate() {
+ switch (_locationNum) {
+ case 1:
+ execData3PostUpdate_locationNum1();
+ break;
+ case 6:
+ if (_flagsTable[26] < 4) {
+ execData3PreUpdate_locationNum6Helper1();
+ }
+ break;
+ case 8:
+ execData3PostUpdate_locationNum8();
+ break;
+ case 9:
+ execData3PostUpdate_locationNum9();
+ break;
+ case 14:
+ if (_yPosCurrent < 127) {
+ execData3PreUpdate_locationNum14();
+ }
+ break;
+ case 21:
+ execData3PostUpdate_locationNum21();
+ break;
+ case 24:
+ execData3PostUpdate_locationNum24();
+ break;
+ case 27:
+ execData3PostUpdate_locationNum27();
+ break;
+ case 28:
+ execData3PostUpdate_locationNum28();
+ break;
+ case 32:
+ execData3PostUpdate_locationNum32();
+ break;
+ case 60:
+ execData3PostUpdate_locationNum60();
+ break;
+ case 66:
+ execData3PostUpdate_locationNum66();
+ break;
+ }
+}
+
+void TuckerEngine::addObjectToInventory(int num) {
+ _inventoryObjectsList[_inventoryObjectsCount] = num;
+ _lastInventoryObjectIndex = _inventoryObjectsCount;
+ _redrawPanelItemsCounter = 50;
+ ++_inventoryObjectsCount;
+ _inventoryItemsState[num] = 1;
+ if (_inventoryObjectsOffset + 5 < _lastInventoryObjectIndex) {
+ _inventoryObjectsOffset += 3;
+ }
+}
+
+void TuckerEngine::removeObjectFromInventory(int num) {
+ int i = 0;
+ while (_inventoryObjectsList[i] != num && i < _inventoryObjectsCount) {
+ ++i;
+ }
+ --_inventoryObjectsCount;
+ int j = i;
+ while (j < _inventoryObjectsCount) {
+ _inventoryObjectsList[j] = _inventoryObjectsList[j + 1];
+ ++j;
+ }
+ _inventoryItemsState[num] = 2;
+}
+
+void TuckerEngine::handleMap() {
+ if (_handleMapCounter > 0) {
+ ++_handleMapCounter;
+ if (_handleMapCounter > 19) {
+ _handleMapCounter = 0;
+ _locationMaskCounter = 1;
+ _panelLockedFlag = 0;
+ }
+ }
+ if (_panelLockedFlag == 0 && (_backgroundSpriteCurrentAnimation == -1 || _locationNum == 25) && _locationMaskType == 3) {
+ setCursorType(0);
+ if (_locationMaskCounter == 1) {
+ _characterFacingDirection = 0;
+ _locationMaskType = 0;
+ }
+ return;
+ }
+ if (_selectedObject.locationObject_locationNum != 0 && _locationMaskCounter != 0 && (_backgroundSpriteCurrentAnimation <= -1 || _locationNum == 25)) {
+ if (_locationNum == 25 || _backgroundSpriteCurrentAnimation != 4) {
+ if (_locationMaskType == 0) {
+ _locationMaskType = 1;
+ setCursorType(2);
+ if (_selectedObject.locationObject_toWalkX2 > 800) {
+ _backgroundSpriteCurrentAnimation = _selectedObject.locationObject_toWalkX2 - 900;
+ if (_selectedObject.locationObject_toWalkY2 > 499) {
+ _changeBackgroundSprite = 1;
+ _backgroundSprOffset = _selectedObject.locationObject_toWalkY2 - 500;
+ } else {
+ _backgroundSprOffset = _selectedObject.locationObject_toWalkY2;
+ _changeBackgroundSprite = 0;
+ }
+ _backgroundSpriteCurrentFrame = 0;
+ _mirroredDrawing = 0;
+ if (_locationNum == 25) {
+ _backgroundSpriteDataPtr = _sprA02Table[_backgroundSpriteCurrentAnimation];
+ _backgroundSpriteLastFrame = READ_LE_UINT16(_backgroundSpriteDataPtr);
+ _backgroundSpriteCurrentFrame = 1;
+ }
+ } else {
+ _locationMaskCounter = 0;
+ _selectedObject.xPos = _selectedObject.locationObject_toWalkX2;
+ _selectedObject.yPos = _selectedObject.locationObject_toWalkY2;
+ _handleMapCounter = 1;
+ _panelLockedFlag = 1;
+ }
+ return;
+ }
+ _locationMaskType = 2;
+ _panelState = 0;
+ setCursorType(0);
+ if (_selectedObject.locationObject_locationNum == 99) {
+ _noPositionChangeAfterMap = true;
+ handleMapSequence();
+ return;
+ }
+ for (int i = 0; i < 14; ++i) {
+ fadeInPalette();
+ copyToVGA(_locationBackgroundGfxBuf + _scrollOffset);
+ _fadePaletteCounter = 34;
+ }
+ _nextLocationNum = _selectedObject.locationObject_locationNum;
+ _xPosCurrent = _selectedObject.locationObject_toX;
+ _yPosCurrent = _selectedObject.locationObject_toY;
+ if (_selectedObject.locationObject_toX2 > 800) {
+ _backgroundSpriteCurrentAnimation = _selectedObject.locationObject_toX2 - 900;
+ if (_selectedObject.locationObject_toY2 > 499) {
+ _changeBackgroundSprite = 1;
+ _backgroundSprOffset = _selectedObject.locationObject_toY2 - 500;
+ } else {
+ _changeBackgroundSprite = 0;
+ _backgroundSprOffset = _selectedObject.locationObject_toY2;
+ }
+ _backgroundSpriteCurrentFrame = 0;
+ } else {
+ _selectedObject.xPos = _selectedObject.locationObject_toX2;
+ _selectedObject.yPos = _selectedObject.locationObject_toY2;
+ _panelLockedFlag = 1;
+ }
+ _scrollOffset = 0;
+ _handleMapCounter = 0;
+ _locationMaskCounter = 0;
+ _selectedObject.locationObject_locationNum = 0;
+ }
+ }
+}
+
+void TuckerEngine::updateSprites() {
+ const int count = (_locationNum == 9) ? 3 : _spritesCount;
+ for (int i = 0; i < count; ++i) {
+ if (_spritesTable[i].stateIndex > -1) {
+ ++_spritesTable[i].stateIndex;
+ if (_characterStateTable[_spritesTable[i].stateIndex] == 99) {
+ _spritesTable[i].stateIndex = -1;
+ _spritesTable[i].state = -1;
+ updateSprite(i);
+ } else {
+ _spritesTable[i].animationFrame = _characterStateTable[_spritesTable[i].stateIndex];
+ }
+ continue;
+ }
+ if (_spritesTable[i].state == -1) {
+ updateSprite(i);
+ continue;
+ }
+ if (_charSpeechSoundCounter > 0 && i == _actionCharacterNum && _spritesTable[i].needUpdate == 0) {
+ updateSprite(i);
+ continue;
+ }
+ if (_charSpeechSoundCounter == 0 && _spritesTable[i].needUpdate > 0) {
+ updateSprite(i);
+ continue;
+ }
+ if (_spritesTable[i].updateDelay > 0) {
+ --_spritesTable[i].updateDelay;
+ if (_spritesTable[i].updateDelay == 0) {
+ updateSprite(i);
+ }
+ continue;
+ }
+ if (_spritesTable[i].defaultUpdateDelay > 0) {
+ _spritesTable[i].updateDelay = _spritesTable[i].defaultUpdateDelay - 1;
+ ++_spritesTable[i].animationFrame;
+ if (_spritesTable[i].animationFrame == _spritesTable[i].firstFrame) {
+ updateSprite(i);
+ }
+ continue;
+ }
+ if (_spritesTable[i].nextAnimationFrame == 0) {
+ ++_spritesTable[i].animationFrame;
+ if (_spritesTable[i].firstFrame - 1 < _spritesTable[i].animationFrame) {
+ if (_spritesTable[i].prevAnimationFrame == 1) {
+ --_spritesTable[i].animationFrame;
+ _spritesTable[i].nextAnimationFrame = 1;
+ } else {
+ updateSprite(i);
+ }
+ }
+ continue;
+ }
+ --_spritesTable[i].animationFrame;
+ if (_spritesTable[i].animationFrame == 0) {
+ updateSprite(i);
+ }
+ }
+}
+
+void TuckerEngine::updateSprite(int i) {
+ _spritesTable[i].prevState = _spritesTable[i].state;
+ _spritesTable[i].prevAnimationFrame = 0;
+ _spritesTable[i].nextAnimationFrame = 0;
+ _updateSpriteFlag1 = 0;
+ _updateSpriteFlag2 = 0;
+ _spritesTable[i].defaultUpdateDelay = 0;
+ _spritesTable[i].updateDelay = 0;
+ switch (_locationNum) {
+ case 2:
+ updateSprite_locationNum2();
+ break;
+ case 3:
+ if (i == 0) {
+ updateSprite_locationNum3_0(i);
+ } else if (i == 1) {
+ updateSprite_locationNum3_1(i);
+ } else {
+ updateSprite_locationNum3_2(i);
+ }
+ break;
+ case 4:
+ updateSprite_locationNum4(0);
+ break;
+ case 5:
+ if (i == 0) {
+ updateSprite_locationNum5_0();
+ } else {
+ updateSprite_locationNum5_1(1);
+ }
+ break;
+ case 6:
+ if (i == 0) {
+ updateSprite_locationNum6_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum6_1(1);
+ } else {
+ updateSprite_locationNum6_2(2);
+ }
+ break;
+ case 7:
+ if (i == 0) {
+ updateSprite_locationNum7_0(0);
+ } else {
+ updateSprite_locationNum7_1(1);
+ }
+ break;
+ case 8:
+ if (i == 0) {
+ updateSprite_locationNum8_0(0);
+ } else {
+ updateSprite_locationNum8_1(1);
+ }
+ break;
+ case 9:
+ if (i == 0) {
+ updateSprite_locationNum9_0(i);
+ } else if (i == 1) {
+ updateSprite_locationNum9_1(i);
+ } else {
+ updateSprite_locationNum9_2(i);
+ }
+ break;
+ case 10:
+ updateSprite_locationNum10();
+ break;
+ case 11:
+ if (i == 0) {
+ updateSprite_locationNum11_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum11_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum11_2(2);
+ } else if (i == 3) {
+ updateSprite_locationNum11_3(3);
+ } else if (i == 4) {
+ updateSprite_locationNum11_4(4);
+ }
+ break;
+ case 12:
+ if (i == 0) {
+ updateSprite_locationNum12_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum12_1(1);
+ }
+ break;
+ case 13:
+ updateSprite_locationNum13(0);
+ break;
+ case 14:
+ updateSprite_locationNum14(0);
+ break;
+ case 15:
+ if (i == 1) {
+ updateSprite_locationNum15_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum15_2(2);
+ } else if (i == 0) {
+ updateSprite_locationNum15_0(0);
+ }
+ break;
+ case 16:
+ if (i == 0) {
+ updateSprite_locationNum16_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum16_1(1);
+ } else {
+ updateSprite_locationNum16_2(2);
+ }
+ break;
+ case 17:
+ updateSprite_locationNum17();
+ break;
+ case 18:
+ updateSprite_locationNum18();
+ break;
+ case 19:
+ if (i == 0) {
+ updateSprite_locationNum19_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum19_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum19_2(2);
+ } else {
+ updateSprite_locationNum19_3(3);
+ }
+ break;
+ case 21:
+ updateSprite_locationNum21();
+ break;
+ case 22:
+ updateSprite_locationNum22();
+ break;
+ case 23:
+ if (i == 0) {
+ updateSprite_locationNum23_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum23_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum23_2(2);
+ } else {
+ updateSprite_locationNum23_3(3);
+ }
+ break;
+ case 24:
+ if (i == 0) {
+ updateSprite_locationNum24_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum24_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum24_2(2);
+ } else {
+ updateSprite_locationNum24_3(3);
+ }
+ break;
+ case 26:
+ if (i == 0) {
+ updateSprite_locationNum26_0(0);
+ } else {
+ updateSprite_locationNum26_1(1);
+ }
+ break;
+ case 27:
+ updateSprite_locationNum27(0);
+ break;
+ case 28:
+ if (i == 0) {
+ updateSprite_locationNum28_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum28_1(1);
+ } else {
+ updateSprite_locationNum28_2(2);
+ }
+ break;
+ case 29:
+ if (i == 0) {
+ updateSprite_locationNum29_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum29_1(1);
+ } else {
+ updateSprite_locationNum29_2(2);
+ }
+ break;
+ case 30:
+ updateSprite_locationNum30_34(i);
+ break;
+ case 31:
+ if (i == 0) {
+ updateSprite_locationNum31_0(0);
+ } else {
+ updateSprite_locationNum31_1(1);
+ }
+ break;
+ case 32:
+ if (i == 0) {
+ updateSprite_locationNum32_0(0);
+ } else {
+ _spritesTable[i].state = -1;
+ }
+ break;
+ case 33:
+ if (i == 1) {
+ updateSprite_locationNum33_1(1);
+ } else if (i == 0) {
+ updateSprite_locationNum33_0(0);
+ } else if (i == 2) {
+ updateSprite_locationNum33_2(2);
+ } else {
+ _spritesTable[i].state = 12;
+ }
+ break;
+ case 34:
+ updateSprite_locationNum30_34(0);
+ break;
+ case 36:
+ updateSprite_locationNum36(0);
+ break;
+ case 37:
+ if (i == 0) {
+ _spritesTable[0].state = -1;
+ } else {
+ updateSprite_locationNum37(i, i + 1, 200 - i * 45);
+ }
+ break;
+ case 41:
+ updateSprite_locationNum41(i);
+ break;
+ case 42:
+ updateSprite_locationNum42(i);
+ break;
+ case 43:
+ if (i == 2) {
+ updateSprite_locationNum43_2(i);
+ } else if (i < 2) {
+ if (_flagsTable[236] < 4) {
+ _spritesTable[0].state = i + 1;
+ } else {
+ _spritesTable[0].state = -1;
+ }
+ } else if (i == 3) {
+ updateSprite_locationNum43_3(3);
+ } else if (i == 4) {
+ updateSprite_locationNum43_4(4);
+ } else if (i == 5) {
+ updateSprite_locationNum43_5(5);
+ } else {
+ updateSprite_locationNum43_6(6);
+ }
+ break;
+ case 45:
+ _spritesTable[0].state = 1;
+ break;
+ case 47:
+ _spritesTable[i].state = i + 1;
+ break;
+ case 48:
+ updateSprite_locationNum48(0);
+ break;
+ case 49:
+ updateSprite_locationNum49(0);
+ break;
+ case 50:
+ if (i < 6) {
+ updateSprite_locationNum50(i);
+ } else {
+ _spritesTable[i].state = i + 1;
+ }
+ break;
+ case 51:
+ if (i == 2) {
+ updateSprite_locationNum51_2(2);
+ } else if (i == 0) {
+ updateSprite_locationNum51_0(0);
+ } else {
+ updateSprite_locationNum51_1(1);
+ }
+ break;
+ case 53:
+ if (i == 0) {
+ updateSprite_locationNum53_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum53_1(1);
+ }
+ break;
+ case 54:
+ updateSprite_locationNum54(0);
+ break;
+ case 55:
+ updateSprite_locationNum55(0);
+ break;
+ case 56:
+ updateSprite_locationNum56(0);
+ break;
+ case 57:
+ if (i == 0) {
+ updateSprite_locationNum57_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum57_1(1);
+ }
+ break;
+ case 58:
+ updateSprite_locationNum58(0);
+ break;
+ case 59:
+ updateSprite_locationNum59(0);
+ break;
+ case 60:
+ if (i == 0) {
+ updateSprite_locationNum60_0(0);
+ } else {
+ updateSprite_locationNum60_1(1);
+ }
+ break;
+ case 61:
+ if (i == 0) {
+ updateSprite_locationNum61_0(0);
+ } else if (i == 2) {
+ updateSprite_locationNum61_2(2);
+ } else {
+ updateSprite_locationNum61_1(1);
+ }
+ break;
+ case 63:
+ if (i == 0) {
+ updateSprite_locationNum63_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum63_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum63_2(2);
+ } else if (i == 3) {
+ updateSprite_locationNum63_3(3);
+ } else if (i == 4) {
+ updateSprite_locationNum63_4(4);
+ }
+ break;
+ case 65:
+ updateSprite_locationNum65(0);
+ break;
+ case 66:
+ if (i == 0) {
+ updateSprite_locationNum66_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum66_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum66_2(2);
+ } else if (i == 3) {
+ updateSprite_locationNum66_3(3);
+ } else {
+ updateSprite_locationNum66_4(4);
+ }
+ break;
+ case 69:
+ if (i == 0) {
+ _spritesTable[0].state = 1;
+ } else if (i == 1) {
+ updateSprite_locationNum69_1(1);
+ } else if (i == 2) {
+ updateSprite_locationNum69_2(2);
+ } else if (i == 3) {
+ updateSprite_locationNum69_3(3);
+ }
+ break;
+ case 71:
+ updateSprite_locationNum71(0);
+ break;
+ case 72:
+ updateSprite_locationNum72(0);
+ break;
+ case 74:
+ updateSprite_locationNum74(i);
+ break;
+ case 79:
+ updateSprite_locationNum79(0);
+ break;
+ case 81:
+ if (i == 0) {
+ updateSprite_locationNum81_0(0);
+ } else if (i == 1) {
+ updateSprite_locationNum81_1(1);
+ }
+ break;
+ case 82:
+ updateSprite_locationNum82(0);
+ break;
+ case 98:
+ _spritesTable[0].state = 1;
+ break;
+ }
+ if (_spritesTable[i].stateIndex <= -1) {
+ if (_updateSpriteFlag1 == 0) {
+ _spritesTable[i].animationFrame = 1;
+ }
+ _spritesTable[i].animationData = _sprC02Table[_spritesTable[i].state];
+ _spritesTable[i].firstFrame = READ_LE_UINT16(_spritesTable[i].animationData);
+ if (_updateSpriteFlag2 == 1) {
+ _spritesTable[i].state = _spritesTable[i].firstFrame;
+ _spritesTable[i].nextAnimationFrame = 1;
+ _spritesTable[i].prevAnimationFrame = 1;
+ }
+ }
+}
+
+void TuckerEngine::drawStringInteger(int num, int x, int y, int digits) {
+ int offset = y * 640 + x + _scrollOffset;
+ char numStr[4];
+ assert(num < 1000);
+ sprintf(numStr, "%03d", num);
+ int i = (digits > 2) ? 0 : 1;
+ for (; i < 3; ++i) {
+ Graphics::drawStringChar(_locationBackgroundGfxBuf + offset, numStr[i], 640, 102, _charsetGfxBuf);
+ offset += 8;
+ }
+}
+
+void TuckerEngine::drawStringAlt(uint8 *dst, int color, const uint8 *str, int strLen) {
+ int pos = 0;
+ while (pos != strLen && str[pos] != '\n') {
+ const uint8 chr = str[pos];
+ Graphics::drawStringChar(dst, chr, 640, color, _charsetGfxBuf);
+ dst += _charWidthTable[chr];
+ ++pos;
+ }
+}
+
+void TuckerEngine::drawString(uint8 *dst, int num, const uint8 *str) {
+ int count = getPositionForLine(num, str);
+ while (str[count] != '\n') {
+ const uint8 chr = str[count];
+ Graphics::drawStringChar(dst, chr, 320, 1, _charsetGfxBuf);
+ dst += _charWidthTable[chr];
+ ++count;
+ }
+}
+
+void TuckerEngine::drawString2(int x, int y, int num) {
+ uint8 *dst = _locationBackgroundGfxBuf + y * 640 + x;
+ int pos = getPositionForLine(num, _ptTextBuf);
+ while (_ptTextBuf[pos] != '\n') {
+ const uint8 chr = _ptTextBuf[pos];
+ Graphics::drawStringChar2(dst, chr, 640, 1, _charsetGfxBuf);
+ dst += _charWidthTable[chr];
+ ++pos;
+ }
+}
+
+void TuckerEngine::updateCharSpeechSound() {
+ if (_charSpeechSoundCounter == 0) {
+ return;
+ }
+ --_charSpeechSoundCounter;
+ int i = isSpeechSoundPlaying();
+ if (_charSpeechSoundCounter == 0) {
+ _charSpeechSoundCounter = i;
+ if (_charSpeechSoundCounter == 0) {
+ _characterSpriteAnimationFrameCounter = 0;
+ }
+ }
+ if (_charSpeechSoundCounter == 0 && _csDataHandled == 0) {
+ setCursorType(0);
+ return;
+ }
+ static const int constEq0 = 0; // display text for speech
+ if (constEq0 == 1 && _gamePaused2 == 0) {
+ drawSpeechText(_actionPosX, _actionPosY, _characterSpeechDataPtr, _speechSoundNum, _actionTextColor);
+ }
+}
+
+void TuckerEngine::updateItemsGfxColors(int color1, int color128) {
+ for (int i = 0; i < 3200; ++i) {
+ if (_itemsGfxBuf[i] == 1) {
+ _itemsGfxBuf[i] = color1;
+ } else if (_itemsGfxBuf[i] == 128) {
+ _itemsGfxBuf[i] = color128;
+ }
+ }
+}
+
+int TuckerEngine::testLocationMask(int x, int y) {
+ if (_locationMaskType > 0 || _locationMaskIgnore > 0) {
+ return 1;
+ }
+ if (_locationNum == 26 || _locationNum == 32) {
+ y -= 3;
+ }
+ const int offset = y * 640 + x;
+ return _locationBackgroundMaskBuf[offset] > 0 ? 1 : 0;
+}
+
+int TuckerEngine::getStringWidth(int num, const uint8 *ptr) {
+ int w = 0;
+ int pos = getPositionForLine(num, ptr);
+ uint8 chr;
+ while ((chr = ptr[pos]) != '\n') {
+ w += _charWidthTable[chr];
+ ++pos;
+ }
+ return w;
+}
+
+int TuckerEngine::getPositionForLine(int num, const uint8 *ptr) {
+ int linesCount = 0;
+ int i = 0;
+ while (linesCount < num) {
+ if (ptr[i] == '\n') {
+ ++linesCount;
+ if (ptr[i + 1] == '\r') {
+ ++i;
+ }
+ }
+ ++i;
+ }
+ while (1) {
+ if (ptr[i] != '\n' && ptr[i] != '\r') {
+ break;
+ }
+ ++i;
+ }
+ return i;
+}
+
+void TuckerEngine::copyToVGA(const uint8 *src) {
+ _system->copyRectToScreen(src, 640, 0, 0, 320, 200);
+ _system->updateScreen();
+}
+
+void TuckerEngine::findActionKey(int count) {
+ _backgroundSpriteCurrentFrame = 0;
+ _characterAnimationIndex = 0;
+ for (int i = 0; i < count; ++i) {
+ while (_characterAnimationsTable[_characterAnimationIndex] != 99) {
+ ++_characterAnimationIndex;
+ }
+ ++_characterAnimationIndex;
+ }
+}
+
+static int parseInt(const uint8 *buf, int offset, int len) {
+ assert(len < 16);
+ char tmpBuf[16];
+ memcpy(tmpBuf, buf + offset, len);
+ tmpBuf[len] = 0;
+ return strtol(tmpBuf, 0, 10);
+}
+
+int TuckerEngine::parseTableInstruction() {
+ int spr;
+ printf("parseTableInstruction instruction %c %c %c\n", _tableInstructionsPtr[0], _tableInstructionsPtr[1], _tableInstructionsPtr[2]);
+ switch (_tableInstructionsPtr[0]) {
+ case 'p': // 12
+ if (_tableInstructionsPtr[1] == 'a') { // 0
+ _tableInstructionsPtr += 4;
+ _panelState = parseInt(_tableInstructionsPtr, 0, 2);
+ _forceRedrawPanelItems = 1;
+ _tableInstructionsPtr += 3;
+ return 0;
+ }
+ break;
+ case 'b': // 1
+ if (_tableInstructionsPtr[2] == 'a') { // 0
+ _backgroundSpriteCurrentAnimation = parseInt(_tableInstructionsPtr, 4, 3);
+ _backgroundSpriteCurrentFrame = 0;
+ _backgroundSprOffset = 0;
+ _mainLoopCounter2 = 0;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'b') { // 1
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ _spriteAnimationFrameIndex = _spriteAnimationsTable[i].firstFrameIndex;
+ _characterFacingDirection = 5;
+ _mainLoopCounter2 = 0;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'c') { // 2
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ findActionKey(i);
+ _backgroundSpriteCurrentFrame = 0;
+ _backgroundSprOffset = 0;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'd') { // 4
+ _selectedCharacterDirection = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'f') { // 5
+ _skipCurrentCharacterDraw = 1;
+ _tableInstructionsPtr += 4;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'h') { // 7
+ _noCharacterAnimationChange = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'n') { // 10
+ _skipCurrentCharacterDraw = 0;
+ _tableInstructionsPtr += 4;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'o') { // 11
+ _backgroundSprOffset = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 's') { // 14
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ _speechSoundNum = i - 1;
+ _speechHistoryTable[4] = _speechHistoryTable[3];
+ _speechHistoryTable[3] = _speechHistoryTable[2];
+ _speechHistoryTable[2] = _speechHistoryTable[1];
+ _speechHistoryTable[1] = _speechHistoryTable[0];
+ _speechHistoryTable[0] = _partNum * 3000 + _ptTextOffset + _speechSoundNum - 3000;
+ startSpeechSound(_partNum * 3000 + _ptTextOffset + _speechSoundNum - 3000, _speechVolume);
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'v') { // 16
+ _speechVolume = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'w') { // 17
+ _selectedObject.xPos = parseInt(_tableInstructionsPtr, 4, 3);
+ _selectedObject.yPos = parseInt(_tableInstructionsPtr, 8, 3);
+ _locationMaskIgnore = 1;
+ _panelLockedFlag = 1;
+ _tableInstructionsPtr += 12;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'x') { // 18
+ _xPosCurrent = parseInt(_tableInstructionsPtr, 4, 3);
+ _yPosCurrent = parseInt(_tableInstructionsPtr, 8, 3);
+ _tableInstructionsPtr += 12;
+ return 0;
+ }
+ break;
+ case 'c': // 2
+ spr = _tableInstructionsPtr[1] - '0';
+ if (_tableInstructionsPtr[2] == 'a') { // 0
+ _spritesTable[spr].state = parseInt(_tableInstructionsPtr, 4, 3);
+ if (_spritesTable[spr].state == 999) {
+ _spritesTable[spr].state = -1;
+ }
+ _mainLoopCounter1 = 0;
+ _spritesTable[spr].updateDelay = 0;
+ _spritesTable[spr].nextAnimationFrame = 0;
+ _spritesTable[spr].prevAnimationFrame = 0;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'e') { // 4
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ setCharacterAnimation(i, spr);
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 's') { // 14
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ _speechSoundNum = i - 1;
+ _speechHistoryTable[4] = _speechHistoryTable[3];
+ _speechHistoryTable[3] = _speechHistoryTable[2];
+ _speechHistoryTable[2] = _speechHistoryTable[1];
+ _speechHistoryTable[1] = _speechHistoryTable[0];
+ _speechHistoryTable[0] = _partNum * 3000 + _ptTextOffset + _speechSoundNum - 3000;
+ startSpeechSound(_partNum * 3000 + _ptTextOffset + _speechSoundNum - 3000, _charSpeechSoundVolumeTable[spr]);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ _actionTextColor = 181 + spr;
+ if (_tableInstructionFlag == 0) {
+ _actionPosX = _tableInstructionItemNum1;
+ _actionPosY = _tableInstructionItemNum2;
+ } else {
+ _actionPosX = _tableInstructionObj1Table[spr];
+ _actionPosY = _tableInstructionObj2Table[spr];
+ }
+ _actionCharacterNum = spr;
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'v') { // 16
+ _charSpeechSoundVolumeTable[spr] = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionsPtr += 8;
+ return 0;
+ }
+ break;
+ case 'e': // 4
+ if (_tableInstructionsPtr[1] == 'n') { // 10
+ return 2;
+ }
+ break;
+ case 'f': // 5
+ if (_tableInstructionsPtr[2] == 'd') { // 3
+ _fadePaletteCounter = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ return 0;
+ }
+ if (_tableInstructionsPtr[1] == 'm') { // 9
+ _redrawPanelItemsCounter = 50;
+ _lastInventoryObjectIndex = 1;
+ _inventoryObjectsOffset = 0;
+ _tableInstructionsPtr += 3;
+ return 0;
+ }
+ if (_tableInstructionsPtr[1] == 'w') { // 17
+ _selectedCharacterNum = parseInt(_tableInstructionsPtr, 3, 2);
+ _tableInstructionsPtr += 6;
+ _actionVerb = 0;
+ _selectedObjectType = 0;
+ _selectedObjectNum = 1;
+ setSelectedObjectKey();
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'x') { // 18
+ int i = parseInt(_tableInstructionsPtr, 4, 2);
+ if (_tableInstructionsPtr[1] == 'l') { // 8
+ _locationSoundsTable[i].type = 2;
+ startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume);
+ } else {
+ if (isSoundPlaying(i)) {
+ stopSound(i);
+ }
+ }
+ _tableInstructionsPtr += 7;
+ return 0;
+ }
+ if (_tableInstructionsPtr[1] == 'x') { // 18
+ int i = parseInt(_tableInstructionsPtr, 3, 2);
+ startSound(_locationSoundsTable[i].offset, i, _locationSoundsTable[i].volume);
+ _soundInstructionIndex = i;
+ _tableInstructionsPtr += 6;
+ return 0;
+ }
+ break;
+ case 'g': // 6
+ if (_tableInstructionsPtr[2] == 'g') { // 6
+ int i = parseInt(_tableInstructionsPtr, 4, 3);
+ _flagsTable[i] = parseInt(_tableInstructionsPtr, 8, 2);
+ _tableInstructionsPtr += 11;
+ return 0;
+ }
+ if (_tableInstructionsPtr[1] == 'v') { // 16
+ _characterAnimationNum = parseInt(_tableInstructionsPtr, 3, 2);
+ _tableInstructionsPtr += 6;
+ return 0;
+ }
+ break;
+ case 'l': // 8
+ if (_tableInstructionsPtr[2] == 'c') { // 2
+ _nextLocationNum = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ return 1;
+ }
+ break;
+ case 'o': // 11
+ if (_tableInstructionsPtr[2] == 't') { // 15
+ _conversationOptionsCount = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ for (int i = 0; i < _conversationOptionsCount; ++i) {
+ _instructionsActionsTable[i] = parseInt(_tableInstructionsPtr, 0, 3) - 1;
+ _nextTableToLoadTable[i] = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionsPtr += 8;
+ }
+ _nextTableToLoadIndex = -1;
+ setCursorType(1);
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 'f') { // 5
+ int count = parseInt(_tableInstructionsPtr, 4, 2);
+ _tableInstructionsPtr += 7;
+ _conversationOptionsCount = 0;
+ for (int i = 0; i < count; ++i) {
+ int flag = parseInt(_tableInstructionsPtr, 0, 3);
+ int value = parseInt(_tableInstructionsPtr, 4, 2);
+ if (value == _flagsTable[flag]) {
+ _instructionsActionsTable[_conversationOptionsCount] = parseInt(_tableInstructionsPtr, 7, 3) - 1;
+ _nextTableToLoadTable[_conversationOptionsCount] = parseInt(_tableInstructionsPtr, 11, 3);
+ ++_conversationOptionsCount;
+ }
+ _tableInstructionsPtr += 15;
+ }
+ _nextTableToLoadIndex = -1;
+ setCursorType(1);
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 'g') { // 6
+ int i = parseInt(_tableInstructionsPtr, 8, 2);
+ if (i == 0) {
+ int obj = parseInt(_tableInstructionsPtr, 4, 3);
+ removeObjectFromInventory(obj);
+ } else {
+ int obj = parseInt(_tableInstructionsPtr, 4, 3);
+ addObjectToInventory(obj);
+ }
+ _tableInstructionsPtr += 11;
+ return 0;
+ }
+ break;
+ case 's': // 14
+ if (_tableInstructionsPtr[2] == 'c') { // 2
+ _tableInstructionsPtr += 4;
+ _mainLoopCounter1 = 0;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'e') { // 4
+ _nextAction = parseInt(_tableInstructionsPtr, 4, 3);
+ _csDataLoaded = false;
+ return 3;
+ }
+ if (_tableInstructionsPtr[2] == 'p') { // 12
+ if (_tableInstructionsPtr[1] == 's') { // 14
+ _tableInstructionFlag = 0;
+ _tableInstructionItemNum1 = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionItemNum2 = parseInt(_tableInstructionsPtr, 8, 3);
+ } else {
+ int num = _tableInstructionsPtr[1] - '0';
+ _tableInstructionFlag = 1;
+ _tableInstructionObj1Table[num] = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionObj2Table[num] = parseInt(_tableInstructionsPtr, 8, 3);
+ }
+ _tableInstructionsPtr += 12;
+ return 0;
+ }
+ if (_tableInstructionsPtr[1] == 'p') { // 12
+ _characterSpriteAnimationFrameCounter = 1;
+ _tableInstructionsPtr += 3;
+ return 0;
+ }
+ break;
+ case 't': // 15
+ if (_tableInstructionsPtr[2] == 'o') { // 11
+ _ptTextOffset = parseInt(_tableInstructionsPtr, 4, 4);
+ _characterSpeechDataPtr = _ptTextBuf + getPositionForLine(_ptTextOffset, _ptTextBuf);
+ _tableInstructionsPtr += 9;
+ return 0;
+ }
+ break;
+ case 'w': // 17
+ if (_tableInstructionsPtr[2] == '+') { // 19
+ _csDataTableFlag2 = 1;
+ _stopActionCounter = 20;
+ _tableInstructionsPtr += 4;
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 'm') { // 9
+ _stopActionOnPanelLock = 1;
+ _tableInstructionsPtr += 4;
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 't') { // 15
+ _stopActionCounter = parseInt(_tableInstructionsPtr, 4, 3);
+ _tableInstructionsPtr += 8;
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 's') { // 14
+ _csDataTableFlag2 = 1;
+ _tableInstructionsPtr += 4;
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 'a') { // 0
+ if (_tableInstructionsPtr[1] == 'b') { // 1
+ _csDataTableCount = 99;
+ } else {
+ _csDataTableCount = _tableInstructionsPtr[1] - '0' + 1;
+ }
+ return 1;
+ }
+ if (_tableInstructionsPtr[2] == 'x') { // 18
+ _stopActionOnSoundFlag = 1;
+ _tableInstructionsPtr += 4;
+ return 1;
+ }
+ break;
+ case 'x': // 18
+ if (_tableInstructionsPtr[2] == 'r') { // 13
+ _validInstructionId = 1;
+ _tableInstructionsPtr += 4;
+ return 0;
+ }
+ if (_tableInstructionsPtr[2] == 'm') { // 9
+ _validInstructionId = 0;
+ _tableInstructionsPtr += 4;
+ return 0;
+ }
+ break;
+ }
+ printf("Instruction not recognised %c %c %c\n", _tableInstructionsPtr[0], _tableInstructionsPtr[1], _tableInstructionsPtr[2]);
+ return 2;
+}
+
+void TuckerEngine::moveUpInventoryObjects() {
+ if (_inventoryObjectsOffset + 6 < _inventoryObjectsCount) {
+ _inventoryObjectsOffset += 3;
+ _forceRedrawPanelItems = 1;
+ }
+}
+
+void TuckerEngine::moveDownInventoryObjects() {
+ if (_inventoryObjectsOffset > 2) {
+ _inventoryObjectsOffset -= 3;
+ _forceRedrawPanelItems = 1;
+ }
+}
+
+void TuckerEngine::setActionVerbUnderCursor() {
+ if (_mousePosY < 150) {
+ _actionVerb = 0;
+ } else if (_mousePosX > 195) {
+ _actionVerb = 1;
+ } else if (_panelNum == 0) {
+ _actionVerb = ((_mousePosY - 150) / 17) * 3 + (_mousePosX / 67);
+ } else {
+ _actionVerb = 0;
+ if (_mousePosX < 30) {
+ _actionVerb = 7;
+ } else if (_mousePosX > 130 && _mousePosX < 165) {
+ _actionVerb = 5;
+ } else {
+ if (_mousePosY < 175) {
+ if (_mousePosX < 67) {
+ _actionVerb = 3;
+ } else if (_mousePosX > 164) {
+ _actionVerb = 6;
+ } else if (_mousePosX > 99) {
+ _actionVerb = 4;
+ }
+ } else {
+ if (_mousePosX < 85) {
+ _actionVerb = 1;
+ } else if (_mousePosX > 165) {
+ _actionVerb = 2;
+ } else {
+ _actionVerb = 8;
+ }
+ }
+ }
+ }
+}
+
+int TuckerEngine::getObjectUnderCursor() {
+ if (_mousePosY > 140) {
+ return -1;
+ }
+ for (int i = 0; i < _locationObjectsCount; ++i) {
+ if (_mousePosX + _scrollOffset + 1 <= _locationObjectsTable[i].xPos) {
+ continue;
+ }
+ if (_mousePosX + _scrollOffset >= _locationObjectsTable[i].xPos + _locationObjectsTable[i].xSize) {
+ continue;
+ }
+ if (_mousePosY <= _locationObjectsTable[i].yPos) {
+ continue;
+ }
+ if (_mousePosY >= _locationObjectsTable[i].yPos + _locationObjectsTable[i].ySize) {
+ continue;
+ }
+ _selectedObjectType = 0;
+ _selectedCharacterNum = i;
+ setCursorNum(_locationObjectsTable[i].cursorNum);
+ return i;
+ }
+ return -1;
+}
+
+void TuckerEngine::setSelectedObjectKey() {
+ const int x = _mousePosX + _scrollOffset;
+ if (_mousePosY > 139 && _nextAction == 0) {
+ return;
+ }
+ _panelLockedFlag = 1;
+ _locationMaskCounter = 0;
+ _actionRequiresTwoObjects = false;
+ _selectedObject.yPos = 0;
+ _selectedObject.locationObject_locationNum = 0;
+ _pendingActionIndex = 0;
+ if (_selectedObjectType == 0) {
+ if (_selectedObjectNum == 0) {
+ _selectedObject.xPos = x;
+ _selectedObject.yPos = _mousePosY;
+ } else {
+ _selectedObject.xPos = _locationObjectsTable[_selectedCharacterNum].standX;
+ _selectedObject.yPos = _locationObjectsTable[_selectedCharacterNum].standY;
+ if (_actionVerb == 0 || _actionVerb == 8) {
+ _selectedObject.locationObject_locationNum = _locationObjectsTable[_selectedCharacterNum].locationNum;
+ _selectedObject.locationObject_toX = _locationObjectsTable[_selectedCharacterNum].toX;
+ _selectedObject.locationObject_toY = _locationObjectsTable[_selectedCharacterNum].toY;
+ _selectedObject.locationObject_toX2 = _locationObjectsTable[_selectedCharacterNum].toX2;
+ _selectedObject.locationObject_toY2 = _locationObjectsTable[_selectedCharacterNum].toY2;
+ _selectedObject.locationObject_toWalkX2 = _locationObjectsTable[_selectedCharacterNum].toWalkX2;
+ _selectedObject.locationObject_toWalkY2 = _locationObjectsTable[_selectedCharacterNum].toWalkY2;
+
+ }
+ }
+ } else {
+ switch (_selectedObjectType) {
+ case 1:
+ _selectedObject.xPos = _locationAnimationsTable[_selectedCharacterNum].standX;
+ _selectedObject.yPos = _locationAnimationsTable[_selectedCharacterNum].standY;
+ break;
+ case 2:
+ _selectedObject.xPos = _charPosTable[_selectedCharacterNum].xWalkTo;
+ _selectedObject.yPos = _charPosTable[_selectedCharacterNum].yWalkTo;
+ break;
+ case 3:
+ _selectedObject.xPos = _xPosCurrent;
+ _selectedObject.yPos = _yPosCurrent;
+ break;
+ }
+ }
+ if (_selectedObject.yPos == 0) {
+ _selectedObject.xPos = x;
+ _selectedObject.yPos = _mousePosY;
+ }
+ _selectedObjectLocationMask = testLocationMask(_selectedObject.xPos, _selectedObject.yPos);
+ if (_selectedObjectLocationMask == 0 && _objectKeysLocationTable[_locationNum] == 1) {
+ if (_selectedObject.yPos < _objectKeysPosYTable[_locationNum]) {
+ while (_selectedObjectLocationMask == 0 && _selectedObject.yPos < _objectKeysPosYTable[_locationNum]) {
+ ++_selectedObject.yPos;
+ _selectedObjectLocationMask = testLocationMask(_selectedObject.xPos, _selectedObject.yPos);
+ }
+ } else {
+ while (_selectedObjectLocationMask == 0 && _selectedObject.yPos < _objectKeysPosYTable[_locationNum]) {
+ --_selectedObject.yPos;
+ _selectedObjectLocationMask = testLocationMask(_selectedObject.xPos, _selectedObject.yPos);
+ }
+ }
+ }
+ if (_selectedObjectLocationMask == 1) {
+ _selectedObjectLocationMask = testLocationMaskArea(_xPosCurrent, _yPosCurrent, _selectedObject.xPos, _selectedObject.yPos);
+ if (_selectedObjectLocationMask == 1 && _objectKeysPosXTable[_locationNum] > 0) {
+ _selectedObject.xDefaultPos = _selectedObject.xPos;
+ _selectedObject.yDefaultPos = _selectedObject.yPos;
+ _selectedObject.xPos = _objectKeysPosXTable[_locationNum];
+ _selectedObject.yPos = _objectKeysPosYTable[_locationNum];
+ if (_objectKeysLocationTable[_locationNum] == 1) {
+ _selectedObject.xPos = _selectedObject.xDefaultPos;
+ }
+ }
+ }
+}
+
+void TuckerEngine::setCharacterAnimation(int count, int spr) {
+ _spritesTable[spr].animationFrame = 0;
+ _spritesTable[spr].stateIndex = 0;
+ for (int i = 0; i < count; ++i) {
+ while (_characterStateTable[_spritesTable[spr].stateIndex] != 99) {
+ ++_spritesTable[spr].stateIndex;
+ }
+ ++_spritesTable[spr].stateIndex;
+ }
+ _spritesTable[spr].state = _characterStateTable[_spritesTable[spr].stateIndex];
+ ++_spritesTable[spr].stateIndex;
+ _spritesTable[spr].animationFrame = _characterStateTable[_spritesTable[spr].stateIndex];
+ ++_spritesTable[spr].stateIndex;
+ _spritesTable[spr].animationData = _sprC02Table[_spritesTable[spr].state];
+ _spritesTable[spr].firstFrame = READ_LE_UINT16(_spritesTable[spr].animationData);
+}
+
+int TuckerEngine::testLocationMaskArea(int xBase, int yBase, int xPos, int yPos) {
+ int i = 0;
+ bool quitLoop = false;
+ while (!quitLoop) {
+ bool flag = false;
+ if (yBase > yPos) {
+ if (testLocationMask(xBase, yBase - 1) == 1) {
+ --yBase;
+ flag = true;
+ } else {
+ ++i;
+ }
+ } else if (yBase < yPos) {
+ if (testLocationMask(xBase, yBase + 1) == 1) {
+ ++yBase;
+ flag = true;
+ } else {
+ ++i;
+ }
+ }
+ if (xBase > xPos) {
+ if (testLocationMask(xBase - 1, yBase) == 1) {
+ --xBase;
+ flag = true;
+ } else {
+ ++i;
+ }
+ } else if (xBase <= xPos) {
+ if (testLocationMask(xBase + 1, yBase) == 1) {
+ ++xBase;
+ flag = true;
+ } else {
+ ++i;
+ }
+ }
+ if (xBase == xPos && yBase == yPos) {
+ break;
+ }
+ if (!flag) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void TuckerEngine::handleMouseClickOnInventoryObject() {
+ if (_panelState != 0) {
+ return;
+ }
+ if (_mousePosY < 150 || _mousePosX < 212) {
+ return;
+ }
+ int pos = ((_mousePosY - 150) / 25) * 3 + (_mousePosX - 212) / 36;
+ int obj = _inventoryObjectsOffset + pos;
+ if (_inventoryObjectsCount - 1 < obj) {
+ return;
+ }
+ _selectedObjectNum = _inventoryObjectsList[obj];
+ _selectedObjectType = 3;
+ switch (_selectedObjectNum) {
+ case 30:
+ if (_skipPanelObjectUnderCursor == 1 && _leftMouseButtonPressed) {
+ _selectedObjectType = 0;
+ _selectedObjectNum = 0;
+ _actionVerb = 0;
+ _skipPanelObjectUnderCursor = 0;
+ _forceRedrawPanelItems = 1;
+ _panelState = 2;
+ setCursorType(1);
+ }
+ break;
+ case 1:
+ if (_actionVerb == 8 && _leftMouseButtonPressed) {
+ if (_mapSequenceFlagsLocationTable[_locationNum - 1] == 1) {
+ handleMapSequence();
+ } else {
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ setCursorType(2);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ _updateCharPositionNewType = 0;
+ _speechSoundNum = 2235;
+ startSpeechSound(_speechSoundNum, _speechVolume);
+ _characterSpeechDataPtr = _ptTextBuf + getPositionForLine(_speechSoundNum, _ptTextBuf);
+ _speechSoundNum = 0;
+ _actionVerb = 0;
+ _selectedObjectType = 0;
+ _selectedObjectNum = 0;
+ _skipPanelObjectUnderCursor = 0;
+ }
+ }
+ break;
+ }
+}
+
+int TuckerEngine::setCharacterUnderCursor() {
+ if (_mousePosY > 140) {
+ return -1;
+ }
+ for (int i = 0; i < _charPosCount; ++i) {
+ if (_mousePosX + _scrollOffset <= _charPosTable[i].xPos) {
+ continue;
+ }
+ if (_mousePosX + _scrollOffset >= _charPosTable[i].xPos + _charPosTable[i].xSize) {
+ continue;
+ }
+ if (_mousePosY <= _charPosTable[i].yPos) {
+ continue;
+ }
+ if (_mousePosY >= _charPosTable[i].yPos + _charPosTable[i].ySize) {
+ continue;
+ }
+ if (_charPosTable[i].flagNum == 0 || _flagsTable[_charPosTable[i].flagNum] == _charPosTable[i].flagValue) {
+ _selectedObjectType = 2;
+ _selectedCharacterDirection = _charPosTable[i].direction;
+ _selectedCharacterNum = i;
+ return _charPosTable[i].name;
+ }
+ }
+ return -1;
+}
+
+int TuckerEngine::setLocationAnimationUnderCursor() {
+ if (_mousePosY > 140) {
+ return -1;
+ }
+ for (int i = _locationAnimationsCount - 1; i >= 0; --i) {
+ if (_locationAnimationsTable[i].drawFlag == 0) {
+ continue;
+ }
+ int num = _locationAnimationsTable[i].graphicNum;
+ if (_mousePosX + _scrollOffset + 1 <= _dataTable[num].xDest) {
+ continue;
+ }
+ if (_mousePosX + _scrollOffset >= _dataTable[num].xDest + _dataTable[num].xSize) {
+ continue;
+ }
+ if (_mousePosY <= _dataTable[num].yDest) {
+ continue;
+ }
+ if (_mousePosY >= _dataTable[num].yDest + _dataTable[num].ySize) {
+ continue;
+ }
+ if (_locationAnimationsTable[i].selectable == 0) {
+ return -1;
+ }
+ _selectedObjectType = 1;
+ _selectedCharacterNum = i;
+ _selectedCharacter2Num = i;
+ return _locationAnimationsTable[i].selectable;
+ }
+ return -1;
+}
+
+void TuckerEngine::setActionForInventoryObject() {
+ if (_actionVerb == 0 || _actionVerb == 2 || _actionVerb == 6 || _actionVerb == 7) {
+ playSpeechForAction(_actionVerb);
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ return;
+ }
+ if (_actionVerb == 3 || _actionVerb == 4) {
+ if (!(_partNum == 2 && _selectedObjectNum == 19) && !(_partNum == 3 && _selectedObjectNum == 42)) {
+ playSpeechForAction(_actionVerb);
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ return;
+ }
+ }
+ _currentActionObj1Num = _actionObj1Num;
+ _currentInfoString1SourceType = _actionObj1Type;
+ _currentActionObj2Num = _actionObj2Num;
+ _currentInfoString2SourceType = _actionObj2Type;
+ if (_actionVerb == 1 && _selectedObjectType == 3) {
+ if (_panelLockedFlag == 1) {
+ if (_locationMaskType != 0) {
+ return;
+ }
+ _panelLockedFlag = 0;
+ }
+ if (handleSpecialObjectSelectionSequence() == 1) {
+ return;
+ }
+ _speechSoundNum = _actionObj1Num + _speechSoundBaseNum;
+ startSpeechSound(_speechSoundNum, _speechVolume);
+ _characterSpeechDataPtr = _ptTextBuf + getPositionForLine(_speechSoundNum, _ptTextBuf);
+ _speechSoundNum = 0;
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ setCursorType(2);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ return;
+ }
+ if ((_partNum == 3 && (_actionObj1Num == 6 || _actionObj1Num == 3 || _actionObj1Num == 17)) ||
+ (_partNum == 2 && _actionObj1Num == 19) ||
+ (_partNum == 3 && (_actionObj1Num == 42 && _selectedObjectNum == 18)) ) {
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ _locationMaskCounter = 1;
+ setActionState();
+ return;
+ }
+ if (!_actionRequiresTwoObjects) {
+ _actionRequiresTwoObjects = true;
+ } else {
+ _skipPanelObjectUnderCursor = 0;
+ _actionRequiresTwoObjects = false;
+ _locationMaskCounter = 1;
+ setActionState();
+ }
+}
+
+void TuckerEngine::setActionState() {
+ _updateCharPositionNewType = (_actionVerb == 0) ? 8 : _actionVerb;
+ _currentActionObj1Num = _actionObj1Num;
+ _currentInfoString1SourceType = _actionObj1Type;
+ _currentActionObj2Num = _actionObj2Num;
+ _currentInfoString2SourceType = _actionObj2Type;
+ _actionRequiresTwoObjects = false;
+ if (_selectedObjectType < 3) {
+ setSelectedObjectKey();
+ }
+}
+
+void TuckerEngine::playSpeechForAction(int i) {
+ static const int speechActionTable[] = { 0, 2235, 2235, 2251, 2261, 2276, 2294, 2312, 2235 };
+ static const int maxCounterTable[] = { 0, 1, 13, 7, 12, 15, 15, 15, 14 };
+ ++_speechActionCounterTable[i];
+ if (_speechActionCounterTable[i] > maxCounterTable[i]) {
+ _speechActionCounterTable[i] = 0;
+ }
+ if (speechActionTable[i] >= 2000) {
+ if (_updateCharPositionNewType == 8 && _currentActionObj1Num == 6 && _currentInfoString1SourceType == 3) {
+ _speechSoundNum = 2395;
+ } else {
+ _speechSoundNum = _speechActionCounterTable[i] + speechActionTable[i];
+ }
+ startSpeechSound(_speechSoundNum, _speechVolume);
+ _characterSpeechDataPtr = _ptTextBuf + getPositionForLine(_speechSoundNum, _ptTextBuf);
+ _speechSoundNum = 0;
+ _actionPosX = _xPosCurrent;
+ _actionPosY = _yPosCurrent - 64;
+ _actionTextColor = 1;
+ _actionCharacterNum = 99;
+ setCursorType(2);
+ _charSpeechSoundCounter = kDefaultCharSpeechSoundCounter;
+ }
+}
+
+void TuckerEngine::drawSpeechText(int xStart, int y, const uint8 *dataPtr, int num, int color) {
+ int x = (xStart - _scrollOffset) * 2;
+ int offset = (_scrollOffset + 320 - xStart) * 2;
+ if (_conversationOptionsCount > 0) {
+ x = 319;
+ } else {
+ if (x > offset) {
+ x = offset;
+ }
+ if (x > 180) {
+ x = 220;
+ } else if (x < 150) {
+ x = 220;
+ }
+ }
+ int count = 0;
+ int flag = 0;
+ struct {
+ int w, count, offset;
+ } lines[5];
+ lines[0].offset = getPositionForLine(num, dataPtr);
+ while (flag == 0 && count < 4) {
+ int lineCharsCount, lineWidth;
+ flag = splitSpeechTextLines(dataPtr, lines[count].offset, x, lineCharsCount, lineWidth);
+ lines[count].w = lineWidth;
+ lines[count].count = lineCharsCount;
+ lines[count + 1].offset = lines[count].offset + lineCharsCount + 1;
+ ++count;
+ }
+ if (count * 10 > y) {
+ y = count * 10;
+ }
+ for (int i = 0; i < count; ++i) {
+ int dstOffset = xStart - lines[i].w / 2;
+ if (dstOffset < _scrollOffset) {
+ dstOffset = _scrollOffset;
+ } else if (lines[i].w > _scrollOffset + 320) {
+ dstOffset = _scrollOffset + 320 - lines[i].w;
+ }
+ uint8 *dst;
+ if (_conversationOptionsCount) {
+ dstOffset = xStart + _scrollOffset;
+ dst = (i * 10 + y) * 640 + _locationBackgroundGfxBuf + dstOffset;
+ _panelItemWidth = count; // ?
+ } else {
+ dst = (y - (count - i) * 10) * 640 + _locationBackgroundGfxBuf + dstOffset;
+ }
+ drawSpeechTextLine(dataPtr, lines[i].offset, lines[i].count, dst, color);
+ }
+}
+
+int TuckerEngine::splitSpeechTextLines(const uint8 *dataPtr, int pos, int x, int &lineCharsCount, int &lineWidth) {
+ int count = 0;
+ int w = 0;
+ lineCharsCount = 0;
+ lineWidth = 0;
+ while (x + 1 > w && dataPtr[pos] != '\n' && dataPtr[pos] != '\r') {
+ if (dataPtr[pos] == ' ') {
+ lineCharsCount = count;
+ lineWidth = w;
+ }
+ w += _charWidthTable[dataPtr[pos]];
+ ++count;
+ ++pos;
+ }
+ int ret = 0;
+ if (x + 1 > w) {
+ lineCharsCount = count;
+ lineWidth = w;
+ ret = 1;
+ }
+ return ret;
+}
+
+void TuckerEngine::drawSpeechTextLine(const uint8 *dataPtr, int pos, int count, uint8 *dst, uint8 color) {
+ while (count > 0 && dataPtr[pos] != '\n') {
+ Graphics::drawStringChar(dst, dataPtr[pos], 640, color, _charsetGfxBuf);
+ dst += _charWidthTable[dataPtr[pos]];
+ ++pos;
+ --count;
+ }
+}
+
+} // namespace Tucker
diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h
new file mode 100644
index 0000000000..f9458bebc9
--- /dev/null
+++ b/engines/tucker/tucker.h
@@ -0,0 +1,802 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TUCKER_ENGINE_H__
+#define TUCKER_ENGINE_H__
+
+#include "common/file.h"
+#include "common/util.h"
+#include "common/endian.h"
+#include "common/events.h"
+#include "common/stream.h"
+
+#include "sound/mixer.h"
+
+#include "engines/engine.h"
+
+namespace Tucker {
+
+struct Action {
+ int key;
+ int testFlag1Num;
+ int testFlag1Value;
+ int testFlag2Num;
+ int testFlag2Value;
+ int speech;
+ int flipX;
+ int index;
+ int delay;
+ int setFlagNum;
+ int setFlagValue;
+ int fxNum;
+ int fxDelay;
+};
+
+struct Sprite {
+ int state;
+ int gfxBackgroundOffset;
+ int updateDelay;
+ int backgroundOffset;
+ int needUpdate;
+ int stateIndex;
+ int counter;
+ int disabled;
+ int colorType;
+ int animationFrame;
+ int firstFrame;
+ uint8 *animationData;
+ int prevState;
+ int nextAnimationFrame;
+ int prevAnimationFrame;
+ int defaultUpdateDelay;
+ int xSource;
+ int yMaxBackground;
+ int flipX;
+};
+
+struct CharPos {
+ int xPos;
+ int yPos;
+ int xSize;
+ int ySize;
+ int xWalkTo;
+ int yWalkTo;
+ int flagNum;
+ int flagValue;
+ int direction;
+ int name;
+ int description;
+};
+
+struct SpriteFrame {
+ int sourceOffset;
+ int xOffset;
+ int yOffset;
+ int xSize;
+ int ySize;
+};
+
+struct SpriteAnimation {
+ int numParts;
+ int rotateFlag;
+ int firstFrameIndex;
+};
+
+struct Data {
+ int sourceOffset;
+ int xSize;
+ int ySize;
+ int xDest;
+ int yDest;
+ int index;
+};
+
+struct LocationAnimation {
+ int graphicNum;
+ int animInitCounter;
+ int animCurrentCounter;
+ int animLastCounter;
+ int getFlag;
+ int inventoryNum;
+ int flagNum;
+ int flagValue;
+ int selectable;
+ int standX;
+ int standY;
+ int drawFlag;
+};
+
+struct LocationObject {
+ int xPos;
+ int yPos;
+ int xSize;
+ int ySize;
+ int textNum;
+ int locationNum;
+ int toX;
+ int toY;
+ int toX2;
+ int toY2;
+ int toWalkX2;
+ int toWalkY2;
+ int standX;
+ int standY;
+ int cursorNum;
+};
+
+struct LocationSound {
+ int startFxSpriteState;
+ int startFxSpriteNum;
+ int updateType;
+ int stopFxSpriteState;
+ int stopFxSpriteNum;
+ int offset;
+ int type;
+ int volume;
+ int flagValueStartFx;
+ int flagValueStopFx;
+ int flagNum;
+ int num;
+};
+
+struct LocationMusic {
+ int flag;
+ int offset;
+ int volume;
+ int num;
+};
+
+enum {
+ kFadePaletteStep = 5,
+ kStartupLocation = 1,
+ kDefaultCharSpeechSoundCounter = 1,
+ kMaxSoundVolume = 127
+};
+
+enum Verb {
+ kVerbWalk = 0,
+ kVerbLook = 1,
+ kVerbTalk = 2,
+ kVerbOpen = 3,
+ kVerbClose = 4,
+ kVerbGive = 5,
+ kVerbTake = 6,
+ kVerbMove = 7,
+ kVerbUse = 8
+};
+
+class TuckerEngine: public Engine {
+public:
+
+ enum {
+ kLocationAnimationsTableSize = 20,
+ kLocationObjectsTableSize = 10,
+ kActionsTableSize = 100,
+ kFlagsTableSize = 800,
+ kLocationSoundsTableSize = 30,
+ kLocationMusicsTableSize = 4,
+ kSpriteFramesTableSize = 200,
+ kSprA02TableSize = 20,
+ kSprC02TableSize = 40,
+ kDataTableSize = 500,
+ kSpeechHistoryTableSize = 5,
+ kMaxCharacters = 8
+ };
+
+ TuckerEngine(OSystem *system, Common::Language language);
+ ~TuckerEngine();
+
+ virtual Common::Error init();
+ virtual Common::Error go();
+ virtual bool hasFeature(EngineFeature f) const { return false; }
+ virtual void syncSoundSettings();
+
+protected:
+
+ int getRandomNumber();
+ void allocateBuffers();
+ void freeBuffers();
+ void restart();
+ void mainLoop();
+ void updateTimer();
+ void waitForTimer(int ticksCount);
+ void parseEvents();
+ void updateCursorPos(int x, int y);
+ void setCursorNum(int num);
+ void setCursorType(int type);
+ void setupNewLocation();
+ void copyLocBitmap(int offset, int isMask);
+ void updateMouseState();
+ void updateCharPositionHelper();
+ void updateCharPosition();
+ void updateFlagsForCharPosition();
+ void backupPalette();
+ void restorePalette();
+ void fadeOutPalette(int colorsCount = 256);
+ void fadeInPalette(int colorsCount = 256);
+ void fadePaletteColor(int color, int step);
+ void setBlackPalette();
+ void setPaletteColor(int color, int r, int g, int b);
+ void updateCursor();
+ int getLastKeyCode();
+ void stopSounds();
+ void playSounds();
+ void updateCharactersPath();
+ void setSoundVolumeDistance();
+ void updateData3DrawFlag();
+ void updateData3();
+ void updateSfxData3_1();
+ void updateSfxData3_2();
+ void saveOrLoad();
+ void handleMouseOnPanel();
+ void switchPanelType();
+ void redrawPanelOverBackground();
+ void drawConversationTexts();
+ void updateScreenScrolling();
+ void updateGameHints();
+ void startCharacterSounds();
+ void updateSoundsTypes3_4();
+ void drawData3();
+ void execData3PreUpdate();
+ void drawBackgroundSprites(int flipX);
+ void setVolumeSound(int index, int volume);
+ void setVolumeMusic(int index, int volume);
+ void startSound(int offset, int index, int volume);
+ void stopSound(int index);
+ bool isSoundPlaying(int index);
+ void startMusic(int offset, int index, int volume);
+ void stopMusic(int index);
+ void startSpeechSound(int num, int volume);
+ bool isSpeechSoundPlaying();
+ void isSoundFinished();
+ void redrawPanelItems();
+ void redrawPanelItemsHelper();
+ void drawSprite(int i);
+ void clearItemsGfx();
+ void drawPausedInfoBar();
+ const uint8 *getStringBuf(int type) const;
+ void drawInfoString();
+ void drawGameHintString();
+ void updateCharacterAnimation();
+ void execData3PostUpdate();
+ void addObjectToInventory(int num);
+ void removeObjectFromInventory(int num);
+ void handleMap();
+ void updateSprites();
+ void updateSprite(int i);
+ void drawStringInteger(int num, int x, int y, int digits);
+ void drawStringAlt(uint8 *dst, int color, const uint8 *str, int strLen = -1);
+ void drawString(uint8 *dst, int num, const uint8 *str);
+ void drawString2(int x, int y, int num);
+ void updateCharSpeechSound();
+ void updateItemsGfxColors(int bit0, int bit7);
+ int testLocationMask(int x, int y);
+ int getStringWidth(int num, const uint8 *ptr);
+ int getPositionForLine(int num, const uint8 *ptr);
+ void copyToVGA(const uint8 *src);
+ void findActionKey(int count);
+ int parseTableInstruction();
+ void moveUpInventoryObjects();
+ void moveDownInventoryObjects();
+ void setActionVerbUnderCursor();
+ int getObjectUnderCursor();
+ void setSelectedObjectKey();
+ void setCharacterAnimation(int count, int spr);
+ int testLocationMaskArea(int xBase, int yBase, int xPos, int yPos);
+ void handleMouseClickOnInventoryObject();
+ int setCharacterUnderCursor();
+ int setLocationAnimationUnderCursor();
+ void setActionForInventoryObject();
+ void setActionState();
+ void playSpeechForAction(int i);
+ void drawSpeechText(int xStart, int y, const uint8 *dataPtr, int num, int color);
+ int splitSpeechTextLines(const uint8 *dataPtr, int pos, int x, int &lineCharsCount, int &lineWidth);
+ void drawSpeechTextLine(const uint8 *dataPtr, int pos, int count, uint8 *dst, uint8 color);
+
+ void execData3PreUpdate_locationNum1();
+ void execData3PreUpdate_locationNum1Helper1();
+ void execData3PreUpdate_locationNum1Helper2();
+ int execData3PreUpdate_locationNum1Helper3(int dx, int dy);
+ void execData3PostUpdate_locationNum1();
+ void updateSprite_locationNum2();
+ void execData3PreUpdate_locationNum2();
+ void execData3PreUpdate_locationNum2Helper();
+ void updateSprite_locationNum3_0(int i);
+ void updateSprite_locationNum3_1(int i);
+ void updateSprite_locationNum3_2(int i);
+ void execData3PreUpdate_locationNum3();
+ void updateSprite_locationNum4(int i);
+ void execData3PreUpdate_locationNum4();
+ void updateSprite_locationNum5_0();
+ void updateSprite_locationNum5_1(int i);
+ void updateSprite_locationNum6_0(int i);
+ void updateSprite_locationNum6_1(int i);
+ void updateSprite_locationNum6_2(int i);
+ void execData3PreUpdate_locationNum6();
+ void execData3PreUpdate_locationNum6Helper1();
+ void execData3PreUpdate_locationNum6Helper2(uint8 *dst, const uint8 *src);
+ void execData3PreUpdate_locationNum6Helper3(uint8 *dst, const uint8 *src);
+ void updateSprite_locationNum7_0(int i);
+ void updateSprite_locationNum7_1(int i);
+ void updateSprite_locationNum8_0(int i);
+ void updateSprite_locationNum8_1(int i);
+ void execData3PostUpdate_locationNum8();
+ void updateSprite_locationNum9_0(int i);
+ void updateSprite_locationNum9_1(int i);
+ void updateSprite_locationNum9_2(int i);
+ void execData3PreUpdate_locationNum9();
+ void execData3PostUpdate_locationNum9();
+ void updateSprite_locationNum10();
+ void execData3PreUpdate_locationNum10();
+ void updateSprite_locationNum11_0(int i);
+ void updateSprite_locationNum11_1(int i);
+ void updateSprite_locationNum11_2(int i);
+ void updateSprite_locationNum11_3(int i);
+ void updateSprite_locationNum11_4(int i);
+ void updateSprite_locationNum12_0(int i);
+ void updateSprite_locationNum12_1(int i);
+ void execData3PreUpdate_locationNum12();
+ void updateSprite_locationNum13(int i);
+ void execData3PreUpdate_locationNum13();
+ void updateSprite_locationNum14(int i);
+ void execData3PreUpdate_locationNum14();
+ void execData3PreUpdate_locationNum14Helper1(int i);
+ void execData3PreUpdate_locationNum14Helper2(int i);
+ void updateSprite_locationNum15_0(int i);
+ void updateSprite_locationNum15_1(int i);
+ void updateSprite_locationNum15_2(int i);
+ void execData3PreUpdate_locationNum15();
+ void updateSprite_locationNum16_0(int i);
+ void updateSprite_locationNum16_1(int i);
+ void updateSprite_locationNum16_2(int i);
+ void execData3PreUpdate_locationNum16();
+ void updateSprite_locationNum17();
+ void updateSprite_locationNum18();
+ void updateSprite_locationNum19_0(int i);
+ void updateSprite_locationNum19_1(int i);
+ void updateSprite_locationNum19_2(int i);
+ void updateSprite_locationNum19_3(int i);
+ void execData3PreUpdate_locationNum19();
+ void updateSprite_locationNum21();
+ void execData3PreUpdate_locationNum21();
+ void execData3PostUpdate_locationNum21();
+ void updateSprite_locationNum22();
+ void execData3PreUpdate_locationNum22();
+ void updateSprite_locationNum23_0(int i);
+ void updateSprite_locationNum23_1(int i);
+ void updateSprite_locationNum23_2(int i);
+ void updateSprite_locationNum23_3(int i);
+ void updateSprite_locationNum24_0(int i);
+ void updateSprite_locationNum24_1(int i);
+ void updateSprite_locationNum24_2(int i);
+ void updateSprite_locationNum24_3(int i);
+ void execData3PreUpdate_locationNum24();
+ void execData3PostUpdate_locationNum24();
+ void execData3PreUpdate_locationNum25();
+ void updateSprite_locationNum26_0(int i);
+ void updateSprite_locationNum26_1(int i);
+ void execData3PreUpdate_locationNum26();
+ void updateSprite_locationNum27(int i);
+ void execData3PreUpdate_locationNum27();
+ void execData3PostUpdate_locationNum27();
+ void updateSprite_locationNum28_0(int i);
+ void updateSprite_locationNum28_1(int i);
+ void updateSprite_locationNum28_2(int i);
+ void execData3PreUpdate_locationNum28();
+ void execData3PostUpdate_locationNum28();
+ void updateSprite_locationNum29_0(int i);
+ void updateSprite_locationNum29_1(int i);
+ void updateSprite_locationNum29_2(int i);
+ void execData3PreUpdate_locationNum29();
+ void updateSprite_locationNum30_34(int i);
+ void execData3PreUpdate_locationNum30();
+ void updateSprite_locationNum31_0(int i);
+ void updateSprite_locationNum31_1(int i);
+ void execData3PreUpdate_locationNum31();
+ void execData3PreUpdate_locationNum31Helper(int r, int flag);
+ void updateSprite_locationNum32_0(int i);
+ void execData3PreUpdate_locationNum32();
+ void execData3PostUpdate_locationNum32();
+ void updateSprite_locationNum33_0(int i);
+ void updateSprite_locationNum33_1(int i);
+ void updateSprite_locationNum33_2(int i);
+ void execData3PreUpdate_locationNum33();
+ void execData3PreUpdate_locationNum34();
+ void execData3PreUpdate_locationNum35();
+ void updateSprite_locationNum36(int i);
+ void execData3PreUpdate_locationNum36();
+ void updateSprite_locationNum37(int i, int j, int offset);
+ void execData3PreUpdate_locationNum38();
+ void updateSprite_locationNum41(int i);
+ void execData3PreUpdate_locationNum41();
+ void updateSprite_locationNum42(int i);
+ void execData3PreUpdate_locationNum42();
+ void updateSprite_locationNum43_2(int i);
+ void updateSprite_locationNum43_3(int i);
+ void updateSprite_locationNum43_4(int i);
+ void updateSprite_locationNum43_5(int i);
+ void updateSprite_locationNum43_6(int i);
+ void execData3PreUpdate_locationNum43();
+ void execData3PreUpdate_locationNum44();
+ void updateSprite_locationNum48(int i);
+ void updateSprite_locationNum49(int i);
+ void execData3PreUpdate_locationNum49();
+ void updateSprite_locationNum50(int i);
+ void updateSprite_locationNum51_0(int i);
+ void updateSprite_locationNum51_1(int i);
+ void updateSprite_locationNum51_2(int i);
+ void execData3PreUpdate_locationNum52();
+ void updateSprite_locationNum53_0(int i);
+ void updateSprite_locationNum53_1(int i);
+ void execData3PreUpdate_locationNum53();
+ void updateSprite_locationNum54(int i);
+ void updateSprite_locationNum55(int i);
+ void updateSprite_locationNum56(int i);
+ void updateSprite_locationNum57_0(int i);
+ void updateSprite_locationNum57_1(int i);
+ void execData3PreUpdate_locationNum57();
+ void updateSprite_locationNum58(int i);
+ void execData3PreUpdate_locationNum58();
+ void updateSprite_locationNum59(int i);
+ void updateSprite_locationNum60_0(int i);
+ void updateSprite_locationNum60_1(int i);
+ void execData3PostUpdate_locationNum60();
+ void updateSprite_locationNum61_0(int i);
+ void updateSprite_locationNum61_1(int i);
+ void updateSprite_locationNum61_2(int i);
+ void execData3PreUpdate_locationNum61();
+ void updateSprite_locationNum63_0(int i);
+ void updateSprite_locationNum63_1(int i);
+ void updateSprite_locationNum63_2(int i);
+ void updateSprite_locationNum63_3(int i);
+ void updateSprite_locationNum63_4(int i);
+ void execData3PreUpdate_locationNum63();
+ void execData3PreUpdate_locationNum64();
+ void updateSprite_locationNum65(int i);
+ void execData3PreUpdate_locationNum65();
+ void updateSprite_locationNum66_0(int i);
+ void updateSprite_locationNum66_1(int i);
+ void updateSprite_locationNum66_2(int i);
+ void updateSprite_locationNum66_3(int i);
+ void updateSprite_locationNum66_4(int i);
+ void execData3PreUpdate_locationNum66();
+ void execData3PostUpdate_locationNum66();
+ void updateSprite_locationNum69_1(int i);
+ void updateSprite_locationNum69_2(int i);
+ void updateSprite_locationNum69_3(int i);
+ void execData3PreUpdate_locationNum70();
+ void execData3PreUpdate_locationNum70Helper();
+ void updateSprite_locationNum71(int i);
+ void updateSprite_locationNum72(int i);
+ void updateSprite_locationNum74(int i);
+ void updateSprite_locationNum79(int i);
+ void updateSprite_locationNum81_0(int i);
+ void updateSprite_locationNum81_1(int i);
+ void updateSprite_locationNum82(int i);
+
+ void generateGameStateFileName(int num, char *dst, int len, bool prefixOnly = false) const;
+ template <class S> void saveOrLoadGameStateData(S &s);
+ void loadGame(int slot);
+ void saveGame(int slot);
+
+ void handleCreditsSequence();
+ void handleCongratulationsSequence();
+ void handleNewPartSequence();
+ void handleMeanwhileSequence();
+ void handleMapSequence();
+ void copyMapRect(int x, int y, int w, int h);
+ int handleSpecialObjectSelectionSequence();
+
+ void openCompressedSoundFile();
+ uint8 *loadFile(uint8 *p = 0);
+ void loadImage(uint8 *dst, int a);
+ void loadCursor();
+ void loadCharset();
+ void loadCharset2();
+ void loadCharsetHelper(int charW, int charH, int xSize, int ySize);
+ void loadCharSizeDta();
+ void loadPanel();
+ void loadBudSpr(int startOffset);
+ void loadCTable01(int firstObjNum, int firstSpriteNum, int &lastSpriteNum);
+ void loadCTable02(int fl);
+ void loadLoc();
+ void loadObj();
+ void loadData();
+ int loadDataHelper(int offset, int index);
+ void loadPanObj();
+ void loadData3();
+ void loadData4();
+ void loadActionFile();
+ void loadCharPos();
+ void loadSprA02_01();
+ void loadSprC02_01();
+ void loadFx();
+ void loadSound(Audio::Mixer::SoundType type, int num, int volume, bool loop, Audio::SoundHandle *handle);
+ void loadActionsTable();
+
+
+ Common::RandomSource _rnd;
+
+ int _quitGame;
+ bool _fastMode;
+ int _syncCounter;
+ uint32 _lastFrameTime;
+ int _mainLoopCounter1;
+ int _mainLoopCounter2;
+ int _timerCounter1;
+ int _timerCounter2;
+ int _flagsTable[kFlagsTableSize];
+ int _partNum;
+ int _currentPartNum;
+ int _locationNum;
+ int _nextLocationNum;
+ int _gamePaused;
+ int _gamePaused2;
+ int _data4FlagDebug;
+ int _displayGameHints;
+ int _execData3Counter;
+
+ uint8 _maxSaveGameSlot, _currentSaveGameSlot;
+ uint8 _firstSaveGameSlot, _lastSaveGameSlot;
+
+ int _gameHintsIndex;
+ int _gameHintsCounter;
+ int _gameHintsDisplayText;
+
+ char _fileToLoad[40];
+ int _fileLoadSize;
+ bool _useEnc;
+ int _compressedSoundType;
+ Common::File _fCompressedSound;
+ uint8 *_loadTempBuf;
+ uint8 *_cursorGfxBuf;
+ uint8 *_charsetGfxBuf;
+ uint8 *_panelGfxBuf;
+ uint8 *_itemsGfxBuf;
+ uint8 *_spritesGfxBuf;
+ uint8 *_locationBackgroundGfxBuf;
+ uint8 *_data5Buf;
+ uint8 *_data3GfxBuf;
+ uint8 *_quadBackgroundGfxBuf;
+ uint8 *_objTxtBuf;
+ uint8 *_panelObjectsGfxBuf;
+ uint8 *_ptTextBuf;
+ uint8 *_infoBarBuf;
+ uint8 *_bgTextBuf;
+ uint8 *_charNameBuf;
+ uint8 *_locationBackgroundMaskBuf;
+ uint8 *_csDataBuf;
+ int _csDataSize;
+ uint8 _charWidthTable[256];
+
+ int _mousePosX, _mousePosY;
+ int _prevMousePosX, _prevMousePosY;
+ int _mouseButtonsMask;
+ int _mouseButtons;
+ int _mouseButton2;
+ int _mouseClick;
+ int _mouseClickOnPanelSliders;
+ int _mouseIdleCounter;
+ bool _leftMouseButtonPressed;
+ bool _rightMouseButtonPressed;
+ int _lastKeyPressed;
+ int _keyLastKeyCodePressed;
+ int _cursorNum;
+ int _cursorType;
+ int _updateCursorFlag;
+
+ int _panelNum;
+ int _panelState;
+ int _forceRedrawPanelItems;
+ int _redrawPanelItemsCounter;
+ int _switchPanelFlag;
+ int _panelObjectsOffsetTable[50];
+ int _switchPanelCounter;
+ int _conversationOptionsCount;
+ bool _fadedPanel;
+ int _panelLockedFlag;
+ int _panelItemWidth;
+ int _inventoryItemsState[50];
+ int _inventoryObjectsList[40];
+ int _inventoryObjectsOffset;
+ int _inventoryObjectsCount;
+ int _lastInventoryObjectIndex;
+
+ uint8 *_sprA02Table[kSprA02TableSize];
+ uint8 *_sprC02Table[kSprC02TableSize];
+ Action _actionsTable[kActionsTableSize];
+ int _actionsCount;
+ LocationObject _locationObjectsTable[kLocationObjectsTableSize];
+ int _locationObjectsCount;
+ Sprite _spritesTable[kMaxCharacters];
+ int _spritesCount;
+ LocationAnimation _locationAnimationsTable[kLocationAnimationsTableSize];
+ int _locationAnimationsCount;
+ Data _dataTable[kDataTableSize];
+ int _dataCount;
+ CharPos _charPosTable[kMaxCharacters];
+ int _charPosCount;
+ LocationSound _locationSoundsTable[kLocationSoundsTableSize];
+ int _locationSoundsCount;
+ LocationMusic _locationMusicsTable[kLocationMusicsTableSize];
+ int _locationMusicsCount;
+
+ int _currentFxSet;
+ int _currentFxDist;
+ int _currentFxScale;
+ int _currentFxVolume;
+ int _currentFxIndex;
+ int _speechSoundNum;
+ int _speechVolume;
+ Audio::SoundHandle _sfxHandles[6];
+ Audio::SoundHandle _musicHandles[2];
+ Audio::SoundHandle _speechHandle;
+ int _soundsMapTable[2];
+ int _speechHistoryTable[kSpeechHistoryTableSize];
+ int _charSpeechSoundVolumeTable[kMaxCharacters];
+ int _charSpeechSoundCounter;
+ int _miscSoundFxDelayCounter[2];
+ int _characterSoundFxDelayCounter;
+ int _characterSoundFxNum;
+ int _speechSoundBaseNum;
+
+ int _pendingActionIndex;
+ int _pendingActionDelay;
+ int _charPositionFlagNum;
+ int _charPositionFlagValue;
+ int _actionVerb;
+ int _nextAction;
+ int _selectedObjectNum;
+ int _selectedObjectType;
+ int _selectedCharacterNum;
+ int _actionObj1Type, _actionObj2Type;
+ int _actionObj1Num, _actionObj2Num;
+ bool _actionRequiresTwoObjects;
+ int _skipPanelObjectUnderCursor;
+ int _actionPosX;
+ int _actionPosY;
+ int _selectedObjectLocationMask;
+ struct {
+ int xDefaultPos;
+ int yDefaultPos;
+ int xPos;
+ int yPos;
+ int locationObject_locationNum;
+ int locationObject_toX;
+ int locationObject_toY;
+ int locationObject_toX2;
+ int locationObject_toY2;
+ int locationObject_toWalkX2;
+ int locationObject_toWalkY2;
+ } _selectedObject;
+ int _selectedCharacterDirection;
+ int _selectedCharacter2Num;
+ int _currentActionObj1Num, _currentActionObj2Num;
+ int _currentInfoString1SourceType, _currentInfoString2SourceType;
+ int _speechActionCounterTable[9];
+ int _actionCharacterNum;
+
+ bool _csDataLoaded;
+ int _csDataHandled;
+ int _stopActionOnSoundFlag;
+ int _csDataTableFlag2;
+ int _stopActionOnPanelLock;
+ int _csDataTableCount;
+ int _stopActionCounter;
+ int _actionTextColor;
+ int _nextTableToLoadIndex;
+ int _nextTableToLoadTable[6];
+ int _soundInstructionIndex;
+ const uint8 *_tableInstructionsPtr;
+ int _tableInstructionObj1Table[6];
+ int _tableInstructionObj2Table[6];
+ int _tableInstructionFlag;
+ int _tableInstructionItemNum1, _tableInstructionItemNum2;
+ int _instructionsActionsTable[6];
+ int _validInstructionId;
+
+ SpriteFrame _spriteFramesTable[kSpriteFramesTableSize];
+ SpriteAnimation _spriteAnimationsTable[200];
+ int _spriteAnimationFramesTable[500];
+ int _spriteAnimationFrameIndex;
+ int _backgroundSpriteCurrentFrame;
+ int _backgroundSpriteLastFrame;
+ int _backgroundSpriteCurrentAnimation;
+ bool _disableCharactersPath;
+ bool _skipCurrentCharacterDraw;
+ int _xPosCurrent;
+ int _yPosCurrent;
+ const uint8 *_characterSpeechDataPtr;
+ int _ptTextOffset;
+ int _ctable01Table_sprite[20];
+ int _characterAnimationsTable[200];
+ int _characterStateTable[200];
+ int _backgroundSprOffset;
+ int _updateCharPositionNewType;
+ int _updateCharPositionType;
+ int _mainSpritesBaseOffset;
+ int _currentSpriteAnimationLength;
+ int _currentSpriteAnimationFrame;
+ int _currentSpriteAnimationFrame2;
+ int _characterAnimationIndex;
+ int _characterFacingDirection;
+ int _characterPrevFacingDirection;
+ int _characterBackFrontFacing;
+ int _characterPrevBackFrontFacing;
+ int _characterAnimationNum;
+ int _noCharacterAnimationChange;
+ int _changeBackgroundSprite;
+ int _characterSpriteAnimationFrameCounter;
+ int _locationMaskIgnore;
+ int _locationMaskType;
+ int _locationMaskCounter;
+ int _updateSpriteFlag1;
+ int _updateSpriteFlag2;
+ int _handleMapCounter;
+ bool _noPositionChangeAfterMap;
+
+ int _mirroredDrawing;
+ uint8 *_loadLocBufPtr;
+ uint8 *_backgroundSpriteDataPtr;
+ int _locationHeight;
+ int _scrollOffset;
+ int _currentGfxBackgroundCounter;
+ uint8 *_currentGfxBackground;
+ int _fadePaletteCounter;
+ uint8 _currentPalette[768];
+ uint8 _backupPalette[768];
+
+ int _updateLocationFadePaletteCounter;
+ int _updateLocationCounter;
+ int _updateLocationPos;
+ int _updateLocationXPosTable[5], _updateLocationYPosTable[5];
+ int _updateLocationFlagsTable[5];
+ int _updateLocationXPosTable2[10], _updateLocationYPosTable2[10];
+ int _updateLocationYMaxTable[3];
+ int _updateLocation14Step[10];
+ int _updateLocation14ObjNum[10];
+ int _updateLocation14Delay[10];
+ int _updateLocationCounter2;
+ int _updateLocationFlag;
+ int _updateLocation70StringLen;
+ uint8 _updateLocation70String[20];
+
+ static const int _locationWidthTable[85];
+ static const uint8 _sprA02LookupTable[88];
+ static const uint8 _sprC02LookupTable[100];
+ static const uint8 _sprC02LookupTable2[100];
+ static const int _staticData3Table[1600];
+ static const int _instructionIdTable[20];
+ static int _locationHeightTable[80];
+ static int _objectKeysPosXTable[80];
+ static int _objectKeysPosYTable[80];
+ static int _objectKeysLocationTable[80];
+ static int _mapSequenceFlagsLocationTable[70];
+ static const int _charWidthCharset2[58];
+};
+
+} // namespace Tucker
+
+#endif