aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2013-04-18 23:35:23 +0200
committerWillem Jan Palenstijn2013-05-08 20:40:58 +0200
commit9c2341678ef4984bf92b3878295250faf980b066 (patch)
tree2fb4805e05e16b9924e80c9947e6bad723b28c4b /engines/mohawk
parent8172d679df5148a4a32f46074b20cb6caf91844f (diff)
parenta5f4ff36ffc386d48f2da49387a9655ce9295a4d (diff)
downloadscummvm-rg350-9c2341678ef4984bf92b3878295250faf980b066.tar.gz
scummvm-rg350-9c2341678ef4984bf92b3878295250faf980b066.tar.bz2
scummvm-rg350-9c2341678ef4984bf92b3878295250faf980b066.zip
Merge branch 'master'
Diffstat (limited to 'engines/mohawk')
-rw-r--r--engines/mohawk/bitmap.cpp2
-rw-r--r--engines/mohawk/console.cpp2
-rw-r--r--engines/mohawk/cstime.h2
-rw-r--r--engines/mohawk/cstime_graphics.cpp64
-rw-r--r--engines/mohawk/cstime_graphics.h51
-rw-r--r--engines/mohawk/detection_tables.h394
-rw-r--r--engines/mohawk/graphics.cpp1002
-rw-r--r--engines/mohawk/graphics.h199
-rw-r--r--engines/mohawk/installer_archive.cpp6
-rw-r--r--engines/mohawk/installer_archive.h6
-rw-r--r--engines/mohawk/livingbooks.cpp306
-rw-r--r--engines/mohawk/livingbooks.h67
-rw-r--r--engines/mohawk/livingbooks_code.cpp483
-rw-r--r--engines/mohawk/livingbooks_code.h49
-rw-r--r--engines/mohawk/livingbooks_graphics.cpp102
-rw-r--r--engines/mohawk/livingbooks_graphics.h52
-rw-r--r--engines/mohawk/livingbooks_lbx.cpp141
-rw-r--r--engines/mohawk/livingbooks_lbx.h47
-rw-r--r--engines/mohawk/module.mk5
-rw-r--r--engines/mohawk/myst.cpp2
-rw-r--r--engines/mohawk/myst.h2
-rw-r--r--engines/mohawk/myst_areas.cpp2
-rw-r--r--engines/mohawk/myst_areas.h8
-rw-r--r--engines/mohawk/myst_graphics.cpp493
-rw-r--r--engines/mohawk/myst_graphics.h102
-rw-r--r--engines/mohawk/myst_scripts.cpp2
-rw-r--r--engines/mohawk/myst_scripts.h2
-rw-r--r--engines/mohawk/myst_stacks/channelwood.cpp2
-rw-r--r--engines/mohawk/myst_stacks/credits.cpp2
-rw-r--r--engines/mohawk/myst_stacks/demo.cpp2
-rw-r--r--engines/mohawk/myst_stacks/intro.cpp2
-rw-r--r--engines/mohawk/myst_stacks/mechanical.cpp2
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp12
-rw-r--r--engines/mohawk/myst_stacks/preview.cpp2
-rw-r--r--engines/mohawk/myst_stacks/slides.cpp2
-rw-r--r--engines/mohawk/myst_stacks/stoneship.cpp8
-rw-r--r--engines/mohawk/riven.cpp2
-rw-r--r--engines/mohawk/riven_external.cpp2
-rw-r--r--engines/mohawk/riven_external.h2
-rw-r--r--engines/mohawk/riven_graphics.cpp445
-rw-r--r--engines/mohawk/riven_graphics.h110
-rw-r--r--engines/mohawk/riven_scripts.cpp2
-rw-r--r--engines/mohawk/riven_scripts.h5
-rw-r--r--engines/mohawk/video.cpp11
-rw-r--r--engines/mohawk/video.h1
45 files changed, 2714 insertions, 1493 deletions
diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp
index f61516c91d..4edde31236 100644
--- a/engines/mohawk/bitmap.cpp
+++ b/engines/mohawk/bitmap.cpp
@@ -887,7 +887,7 @@ void DOSBitmap::expandEGAPlanes(Graphics::Surface *surface, Common::SeekableRead
assert(surface->format.bytesPerPixel == 1);
// Note that the image is in EGA planar form and not just standard 4bpp
- // This seems to contradict the PoP specs which seem to do
+ // This seems to contradict the PoP specs which seem to do something else
byte *dst = (byte *)surface->pixels;
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 0234c86c7e..a7a650d8ed 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -21,7 +21,6 @@
*/
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
#include "mohawk/livingbooks.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -36,6 +35,7 @@
#ifdef ENABLE_MYST
#include "mohawk/myst.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#endif
diff --git a/engines/mohawk/cstime.h b/engines/mohawk/cstime.h
index 0bc236f930..db06b9791e 100644
--- a/engines/mohawk/cstime.h
+++ b/engines/mohawk/cstime.h
@@ -25,7 +25,7 @@
#include "mohawk/mohawk.h"
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
+#include "mohawk/cstime_graphics.h"
#include "common/random.h"
#include "common/list.h"
diff --git a/engines/mohawk/cstime_graphics.cpp b/engines/mohawk/cstime_graphics.cpp
new file mode 100644
index 0000000000..3a1452e67c
--- /dev/null
+++ b/engines/mohawk/cstime_graphics.cpp
@@ -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.
+ *
+ */
+
+#include "mohawk/cstime.h"
+#include "mohawk/cstime_graphics.h"
+#include "mohawk/resource.h"
+
+#include "common/system.h"
+#include "engines/util.h"
+
+namespace Mohawk {
+
+CSTimeGraphics::CSTimeGraphics(MohawkEngine_CSTime *vm) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = new MohawkBitmap();
+
+ initGraphics(640, 480, true);
+}
+
+CSTimeGraphics::~CSTimeGraphics() {
+ delete _bmpDecoder;
+}
+
+void CSTimeGraphics::drawRect(Common::Rect rect, byte color) {
+ rect.clip(Common::Rect(640, 480));
+
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
+ return;
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ screen->frameRect(rect, color);
+
+ _vm->_system->unlockScreen();
+}
+
+MohawkSurface *CSTimeGraphics::decodeImage(uint16 id) {
+ return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+}
+
+Common::Array<MohawkSurface *> CSTimeGraphics::decodeImages(uint16 id) {
+ return _bmpDecoder->decodeImages(_vm->getResource(ID_TBMH, id));
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/cstime_graphics.h b/engines/mohawk/cstime_graphics.h
new file mode 100644
index 0000000000..5f034f47f4
--- /dev/null
+++ b/engines/mohawk/cstime_graphics.h
@@ -0,0 +1,51 @@
+/* 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.
+ *
+ */
+
+#ifndef MOHAWK_CSTIME_GRAPHICS_H
+#define MOHAWK_CSTIME_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_CSTime;
+
+class CSTimeGraphics : public GraphicsManager {
+public:
+ CSTimeGraphics(MohawkEngine_CSTime *vm);
+ ~CSTimeGraphics();
+
+ void drawRect(Common::Rect rect, byte color);
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ Common::Array<MohawkSurface *> decodeImages(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkBitmap *_bmpDecoder;
+ MohawkEngine_CSTime *_vm;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 94f18e134b..08df0a2cbe 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -34,7 +34,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -52,7 +52,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_DEMO,
@@ -70,7 +70,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -88,7 +88,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -106,7 +106,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -124,7 +124,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -142,7 +142,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -160,7 +160,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -178,7 +178,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::JA_JPN,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -196,7 +196,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -214,7 +214,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -232,7 +232,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -250,7 +250,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -268,7 +268,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -286,7 +286,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -304,7 +304,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -322,7 +322,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -340,7 +340,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -358,7 +358,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
@@ -376,7 +376,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DEMO,
@@ -391,7 +391,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSTIME,
0,
@@ -406,7 +406,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSTIME,
GF_DEMO,
@@ -422,7 +422,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -437,7 +437,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -452,7 +452,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -467,7 +467,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -482,7 +482,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_ZOOMBINI,
GF_HASMIDI,
@@ -497,7 +497,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSWORLD,
0,
@@ -512,7 +512,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSWORLD,
0,
@@ -527,7 +527,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSAMTRAK,
0,
@@ -545,7 +545,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -563,7 +563,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -581,7 +581,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -597,7 +597,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -613,7 +613,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -629,7 +629,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -646,7 +646,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -663,7 +663,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -678,7 +678,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV5,
0,
@@ -693,7 +693,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV5,
0,
@@ -709,7 +709,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -724,7 +724,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -739,7 +739,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -754,7 +754,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_JAMESMATH,
GF_HASMIDI,
@@ -770,7 +770,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_JAMESMATH,
GF_HASMIDI,
@@ -785,7 +785,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_TREEHOUSE,
GF_HASMIDI,
@@ -800,7 +800,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -816,7 +816,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -831,7 +831,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -846,7 +846,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -862,7 +862,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -877,7 +877,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -892,7 +892,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
GF_DEMO,
@@ -907,7 +907,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_1STDEGREE,
GF_HASMIDI,
@@ -925,7 +925,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_1STDEGREE,
GF_HASMIDI,
@@ -940,7 +940,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_CSUSA,
0,
@@ -955,7 +955,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -972,7 +972,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -988,7 +988,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1004,7 +1004,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV2,
+ 0,
+ 0,
+ },
+
+ // Tortoise and the Hare Hebrew variant - From georgeqgreg on bug #3441928
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTB.LB", "23135777370cf1ff00aa7247e93642d3"),
+ Common::HE_ISR,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1020,7 +1036,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1036,7 +1052,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1052,7 +1068,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1068,7 +1084,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1083,7 +1099,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1098,7 +1114,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1114,7 +1130,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1129,7 +1145,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1144,7 +1160,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1161,7 +1177,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1177,7 +1193,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1193,7 +1209,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1208,7 +1224,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1223,7 +1239,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1239,7 +1255,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1254,7 +1270,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1269,7 +1285,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1286,7 +1302,24 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // Just Grandma and Me 2.0 Macintosh
+ // From aluff in bug #3461368
+ {
+ {
+ "grandma",
+ "v2.0",
+ AD_ENTRY1("BookOutline", "99fe5c8ace79f0542e6390bc3b58f25a"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1303,7 +1336,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1319,7 +1352,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_LB_10,
@@ -1335,7 +1368,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1351,7 +1384,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1367,7 +1400,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1382,7 +1415,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1397,7 +1430,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1413,7 +1446,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1428,7 +1461,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO | GF_LB_10,
@@ -1443,7 +1476,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1460,7 +1493,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1476,7 +1509,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1491,7 +1524,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1507,7 +1540,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1522,7 +1555,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1538,7 +1571,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1555,7 +1588,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1571,7 +1604,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1586,7 +1619,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1601,7 +1634,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1617,7 +1650,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1632,7 +1665,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1647,7 +1680,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1663,7 +1696,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1678,7 +1711,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1694,7 +1727,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1710,7 +1743,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1726,7 +1759,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1742,7 +1775,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1758,7 +1791,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1775,7 +1808,24 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // Arthur Birthday (English) Version 2.0 Macintosh
+ // From aluff in bug #3461368
+ {
+ {
+ "arthurbday",
+ "",
+ AD_ENTRY1("BookOutline", "8e4fddb5b761c8cf2a3b448dd38422be"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1790,7 +1840,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1806,7 +1856,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1821,7 +1871,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1836,7 +1886,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1851,7 +1901,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -1867,7 +1917,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1883,7 +1933,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1899,7 +1949,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1915,7 +1965,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1931,7 +1981,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1947,7 +1997,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -1963,7 +2013,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DEMO,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "MONSTER.EXE"
+ },
+
+ // From GeorgeQGreg
+ {
+ {
+ "lilmonster",
+ "Demo",
+ AD_ENTRY1("MONSTER.512", "f603f04c1824d1034ec0366416a059c9"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
GF_DEMO,
@@ -1978,7 +2044,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -1993,7 +2059,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2008,7 +2074,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2023,7 +2089,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2041,7 +2107,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2056,7 +2122,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2071,7 +2137,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2086,7 +2152,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2102,7 +2168,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2117,7 +2183,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2132,7 +2198,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2147,7 +2213,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2164,7 +2230,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2179,7 +2245,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV1,
0,
@@ -2195,7 +2261,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2212,7 +2278,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2228,7 +2294,23 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
+ },
+ GType_LIVINGBOOKSV3,
+ 0,
+ 0
+ },
+
+ // From aluff in bug #3461368
+ {
+ {
+ "beardark",
+ "",
+ AD_ENTRY1("BookOutline", "b56746b3b2c062c8588bfb6b28e137c1"),
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV3,
0,
@@ -2243,7 +2325,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2258,7 +2340,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV4,
0,
@@ -2275,7 +2357,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2291,7 +2373,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2307,7 +2389,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2324,7 +2406,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2340,7 +2422,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2356,7 +2438,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2372,7 +2454,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2388,7 +2470,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2404,7 +2486,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::EN_GRB,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2420,7 +2502,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2436,7 +2518,7 @@ static const MohawkGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_LIVINGBOOKSV2,
0,
@@ -2459,7 +2541,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
0,
@@ -2474,7 +2556,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MAKINGOF,
0,
@@ -2489,7 +2571,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_MYST,
GF_ME,
@@ -2504,7 +2586,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
0,
@@ -2519,7 +2601,7 @@ static const MohawkGameDescription fallbackDescs[] = {
Common::UNK_LANG,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GUIO_NONE)
+ GUIO1(GUIO_NOASPECT)
},
GType_RIVEN,
GF_DVD,
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index c4326d175f..a08d034ef7 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -20,30 +20,13 @@
*
*/
+#include "mohawk/mohawk.h"
#include "mohawk/resource.h"
#include "mohawk/graphics.h"
-#include "mohawk/livingbooks.h"
-#include "common/substream.h"
#include "common/system.h"
-#include "common/textconsole.h"
#include "engines/util.h"
#include "graphics/palette.h"
-#include "graphics/primitives.h"
-#include "gui/message.h"
-
-#ifdef ENABLE_CSTIME
-#include "mohawk/cstime.h"
-#endif
-
-#ifdef ENABLE_MYST
-#include "mohawk/myst.h"
-#include "graphics/jpeg.h"
-#endif
-
-#ifdef ENABLE_RIVEN
-#include "mohawk/riven.h"
-#endif
namespace Mohawk {
@@ -108,9 +91,9 @@ GraphicsManager::~GraphicsManager() {
}
void GraphicsManager::clearCache() {
- for (Common::HashMap<uint16, MohawkSurface*>::iterator it = _cache.begin(); it != _cache.end(); it++)
+ for (Common::HashMap<uint16, MohawkSurface *>::iterator it = _cache.begin(); it != _cache.end(); it++)
delete it->_value;
- for (Common::HashMap<uint16, Common::Array<MohawkSurface*> >::iterator it = _subImageCache.begin(); it != _subImageCache.end(); it++) {
+ for (Common::HashMap<uint16, Common::Array<MohawkSurface *> >::iterator it = _subImageCache.begin(); it != _subImageCache.end(); it++) {
Common::Array<MohawkSurface *> &array = it->_value;
for (uint i = 0; i < array.size(); i++)
delete array[i];
@@ -262,983 +245,4 @@ void GraphicsManager::addImageToCache(uint16 id, MohawkSurface *surface) {
_cache[id] = surface;
}
-#ifdef ENABLE_MYST
-
-MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = new MystBitmap();
-
- _viewport = Common::Rect(544, 332);
-
- // The original version of Myst could run in 8bpp color too.
- // However, it dithered videos to 8bpp and they looked considerably
- // worse (than they already did :P). So we're not even going to
- // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
- initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
-
- _pixelFormat = _vm->_system->getScreenFormat();
-
- if (_pixelFormat.bytesPerPixel == 1)
- error("Myst requires greater than 256 colors to run");
-
- if (_vm->getFeatures() & GF_ME) {
- _jpegDecoder = new Graphics::JPEG();
- _pictDecoder = new Graphics::PictDecoder(_pixelFormat);
- } else {
- _jpegDecoder = NULL;
- _pictDecoder = NULL;
- }
-
- _pictureFile.entries = NULL;
-
- // Initialize our buffer
- _backBuffer = new Graphics::Surface();
- _backBuffer->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat);
-
- _nextAllowedDrawTime = _vm->_system->getMillis();
- _enableDrawingTimeSimulation = 0;
-}
-
-MystGraphics::~MystGraphics() {
- delete _bmpDecoder;
- delete _jpegDecoder;
- delete _pictDecoder;
- delete[] _pictureFile.entries;
-
- _backBuffer->free();
- delete _backBuffer;
-}
-
-static const char* picFileNames[] = {
- "CHpics",
- "",
- "DUpics",
- "INpics",
- "MEpics",
- "MYpics",
- "SEpics",
- "STpics",
- ""
-};
-
-void MystGraphics::loadExternalPictureFile(uint16 stack) {
- if (_vm->getPlatform() != Common::kPlatformMacintosh)
- return;
-
- if (_pictureFile.picFile.isOpen())
- _pictureFile.picFile.close();
- delete[] _pictureFile.entries;
-
- if (!scumm_stricmp(picFileNames[stack], ""))
- return;
-
- if (!_pictureFile.picFile.open(picFileNames[stack]))
- error ("Could not open external picture file \'%s\'", picFileNames[stack]);
-
- _pictureFile.pictureCount = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries = new PictureFile::PictureEntry[_pictureFile.pictureCount];
-
- for (uint32 i = 0; i < _pictureFile.pictureCount; i++) {
- _pictureFile.entries[i].offset = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries[i].size = _pictureFile.picFile.readUint32BE();
- _pictureFile.entries[i].id = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].type = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].width = _pictureFile.picFile.readUint16BE();
- _pictureFile.entries[i].height = _pictureFile.picFile.readUint16BE();
- }
-}
-
-MohawkSurface *MystGraphics::decodeImage(uint16 id) {
- MohawkSurface *mhkSurface = 0;
-
- // Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images,
- // though there are a few weird ones that use that format. For further nonsense with images,
- // the Macintosh version stores images in external "picture files." We check them before
- // going to check for a PICT resource.
- if (_vm->getFeatures() & GF_ME && _vm->getPlatform() == Common::kPlatformMacintosh && _pictureFile.picFile.isOpen()) {
- for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
- if (_pictureFile.entries[i].id == id) {
- if (_pictureFile.entries[i].type == 0) {
- Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
-
- if (!_jpegDecoder->read(stream))
- error("Could not decode Myst ME Mac JPEG");
-
- mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
- delete stream;
- } else if (_pictureFile.entries[i].type == 1) {
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
- } else
- error ("Unknown Picture File type %d", _pictureFile.entries[i].type);
- break;
- }
- }
-
- // We're not using the external Mac files, so it's time to delve into the main Mohawk
- // archives. However, we still don't know if it's a PICT or WDIB resource. If it's Myst
- // ME it's most likely a PICT, and if it's original it's definitely a WDIB. However,
- // Myst ME throws us another curve ball in that PICT resources can contain WDIB's instead
- // of PICT's.
- if (!mhkSurface) {
- bool isPict = false;
- Common::SeekableReadStream *dataStream = NULL;
-
- if (_vm->getFeatures() & GF_ME && _vm->hasResource(ID_PICT, id)) {
- // The PICT resource exists. However, it could still contain a MystBitmap
- // instead of a PICT image...
- dataStream = _vm->getResource(ID_PICT, id);
- } else // No PICT, so the WDIB must exist. Let's go grab it.
- dataStream = _vm->getResource(ID_WDIB, id);
-
- if (_vm->getFeatures() & GF_ME) {
- // Here we detect whether it's really a PICT or a WDIB. Since a MystBitmap
- // would be compressed, there's no way to detect for the BM without a hack.
- // So, we search for the PICT version opcode for detection.
- dataStream->seek(512 + 10); // 512 byte pict header
- isPict = (dataStream->readUint32BE() == 0x001102FF);
- dataStream->seek(0);
- }
-
- if (isPict)
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(dataStream));
- else {
- mhkSurface = _bmpDecoder->decodeImage(dataStream);
- mhkSurface->convertToTrueColor();
- }
- }
-
- assert(mhkSurface);
- return mhkSurface;
-}
-
-void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Make sure the image is bottom aligned in the dest rect
- dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
-
- // Convert from bitmap coordinates to surface coordinates
- uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
-
- // Do not draw the top pixels if the image is too tall
- if (dest.height() > _viewport.height())
- top += dest.height() - _viewport.height();
-
- // Clip the destination rect to the screen
- if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
- dest.debugPrint(4, "Clipping destination rect to the screen");
- dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
- dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
-
- uint16 width = MIN<int>(surface->w, dest.width());
- uint16 height = MIN<int>(surface->h, dest.height());
-
- // Clamp Width and Height to within src surface dimensions
- if (src.left + width > surface->w)
- width = surface->w - src.left;
- if (src.top + height > surface->h)
- height = surface->h - src.top;
-
- debug(3, "MystGraphics::copyImageSectionToScreen()");
- debug(3, "\tImage: %d", image);
- debug(3, "\tsrc.left: %d", src.left);
- debug(3, "\tsrc.top: %d", src.top);
- debug(3, "\tdest.left: %d", dest.left);
- debug(3, "\tdest.top: %d", dest.top);
- debug(3, "\twidth: %d", width);
- debug(3, "\theight: %d", height);
-
- simulatePreviousDrawDelay(dest);
-
- _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
-}
-
-void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Make sure the image is bottom aligned in the dest rect
- dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
-
- // Convert from bitmap coordinates to surface coordinates
- uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
-
- // Do not draw the top pixels if the image is too tall
- if (dest.height() > _viewport.height()) {
- top += dest.height() - _viewport.height();
- }
-
- // Clip the destination rect to the screen
- if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
- dest.debugPrint(4, "Clipping destination rect to the screen");
- dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
- dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
-
- uint16 width = MIN<int>(surface->w, dest.width());
- uint16 height = MIN<int>(surface->h, dest.height());
-
- // Clamp Width and Height to within src surface dimensions
- if (src.left + width > surface->w)
- width = surface->w - src.left;
- if (src.top + height > surface->h)
- height = surface->h - src.top;
-
- debug(3, "MystGraphics::copyImageSectionToBackBuffer()");
- debug(3, "\tImage: %d", image);
- debug(3, "\tsrc.left: %d", src.left);
- debug(3, "\tsrc.top: %d", src.top);
- debug(3, "\tdest.left: %d", dest.left);
- debug(3, "\tdest.top: %d", dest.top);
- debug(3, "\twidth: %d", width);
- debug(3, "\theight: %d", height);
-
- for (uint16 i = 0; i < height; i++)
- memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
-}
-
-void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
- copyImageSectionToScreen(image, Common::Rect(544, 333), dest);
-}
-
-void MystGraphics::copyImageToBackBuffer(uint16 image, Common::Rect dest) {
- copyImageSectionToBackBuffer(image, Common::Rect(544, 333), dest);
-}
-
-void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
- r.clip(_viewport);
-
- simulatePreviousDrawDelay(r);
-
- _vm->_system->copyRectToScreen((byte *)_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
-}
-
-void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay) {
-
- // Do not artificially delay during transitions
- int oldEnableDrawingTimeSimulation = _enableDrawingTimeSimulation;
- _enableDrawingTimeSimulation = 0;
-
- switch (type) {
- case 0: {
- debugC(kDebugScript, "Left to Right");
-
- uint16 step = (rect.right - rect.left) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.left = rect.left + step * i;
- area.right = area.left + step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.right < rect.right) {
- area.left = area.right;
- area.right = rect.right;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 1: {
- debugC(kDebugScript, "Right to Left");
-
- uint16 step = (rect.right - rect.left) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.right = rect.right - step * i;
- area.left = area.right - step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.left > rect.left) {
- area.right = area.left;
- area.left = rect.left;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 5: {
- debugC(kDebugScript, "Top to Bottom");
-
- uint16 step = (rect.bottom - rect.top) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.top = rect.top + step * i;
- area.bottom = area.top + step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.bottom < rect.bottom) {
- area.top = area.bottom;
- area.bottom = rect.bottom;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- case 6: {
- debugC(kDebugScript, "Bottom to Top");
-
- uint16 step = (rect.bottom - rect.top) / steps;
- Common::Rect area = rect;
- for (uint i = 0; i < steps; i++) {
- area.bottom = rect.bottom - step * i;
- area.top = area.bottom - step;
-
- _vm->_system->delayMillis(delay);
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- if (area.top > rect.top) {
- area.bottom = area.top;
- area.top = rect.top;
-
- copyBackBufferToScreen(area);
- _vm->_system->updateScreen();
- }
- }
- break;
- default:
- warning("Unknown Update Direction");
-
- //TODO: Replace minimal implementation
- copyBackBufferToScreen(rect);
- _vm->_system->updateScreen();
- break;
- }
-
- _enableDrawingTimeSimulation = oldEnableDrawingTimeSimulation;
-}
-
-void MystGraphics::drawRect(Common::Rect rect, RectState state) {
- rect.clip(_viewport);
-
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
- return;
-
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- if (state == kRectEnabled)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
- else if (state == kRectUnreachable)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
- else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color) {
- _backBuffer->drawLine(p1.x, p1.y, p2.x, p2.y, color);
-}
-
-void MystGraphics::enableDrawingTimeSimulation(bool enable) {
- if (enable)
- _enableDrawingTimeSimulation++;
- else
- _enableDrawingTimeSimulation--;
-
- if (_enableDrawingTimeSimulation < 0)
- _enableDrawingTimeSimulation = 0;
-}
-
-void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
- uint32 time = 0;
-
- if (_enableDrawingTimeSimulation) {
- time = _vm->_system->getMillis();
-
- // Do not draw anything new too quickly after the previous draw call
- // so that images stay at least a little while on screen
- // This is enabled only for scripted draw calls
- if (time < _nextAllowedDrawTime)
- _vm->_system->delayMillis(_nextAllowedDrawTime - time);
- }
-
- // Next draw call allowed at DELAY + AERA * COEFF milliseconds from now
- time = _vm->_system->getMillis();
- _nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
-}
-
-void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- for (uint16 y = 0; y < _viewport.height(); y++)
- for (uint16 x = 0; x < _viewport.width(); x++) {
- uint32 color;
- uint8 r, g, b;
-
- if (_pixelFormat.bytesPerPixel == 2)
- color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- else
- color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
-
- _pixelFormat.colorToRGB(color, r, g, b);
-
- r = CLIP<int16>((int16)r - saturation, 0, 255);
- g = CLIP<int16>((int16)g - saturation, 0, 255);
- b = CLIP<int16>((int16)b - saturation, 0, 255);
-
- color = _pixelFormat.RGBToColor(r, g, b);
-
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = color;
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = color;
- }
- }
-
- _vm->_system->unlockScreen();
- _vm->_system->updateScreen();
-}
-
-void MystGraphics::fadeToBlack() {
- for (int16 i = 0; i < 256; i += 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
-}
-
-void MystGraphics::fadeFromBlack() {
- for (int16 i = 256; i >= 0; i -= 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
-}
-
-#endif // ENABLE_MYST
-
-#ifdef ENABLE_RIVEN
-
-RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm) {
- _bitmapDecoder = new MohawkBitmap();
-
- // Give me the best you've got!
- initGraphics(608, 436, true, NULL);
- _pixelFormat = _vm->_system->getScreenFormat();
-
- if (_pixelFormat.bytesPerPixel == 1)
- error("Riven requires greater than 256 colors to run");
-
- // The actual game graphics only take up the first 392 rows. The inventory
- // occupies the rest of the screen and we don't use the buffer to hold that.
- _mainScreen = new Graphics::Surface();
- _mainScreen->create(608, 392, _pixelFormat);
-
- _updatesEnabled = true;
- _scheduledTransition = -1; // no transition
- _dirtyScreen = false;
- _inventoryDrawn = false;
-
- _creditsImage = 302;
- _creditsPos = 0;
-}
-
-RivenGraphics::~RivenGraphics() {
- _mainScreen->free();
- delete _mainScreen;
- delete _bitmapDecoder;
-}
-
-MohawkSurface *RivenGraphics::decodeImage(uint16 id) {
- MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
- surface->convertToTrueColor();
- return surface;
-}
-
-void RivenGraphics::copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom) {
- Graphics::Surface *surface = findImage(image)->getSurface();
-
- // Clip the width to fit on the screen. Fixes some images.
- if (left + surface->w > 608)
- surface->w = 608 - left;
-
- for (uint16 i = 0; i < surface->h; i++)
- memcpy(_mainScreen->getBasePtr(left, i + top), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
-
- _dirtyScreen = true;
-}
-
-void RivenGraphics::drawPLST(uint16 x) {
- Common::SeekableReadStream* plst = _vm->getResource(ID_PLST, _vm->getCurCard());
- uint16 recordCount = plst->readUint16BE();
-
- for (uint16 i = 0; i < recordCount; i++) {
- uint16 index = plst->readUint16BE();
- uint16 id = plst->readUint16BE();
- uint16 left = plst->readUint16BE();
- uint16 top = plst->readUint16BE();
- uint16 right = plst->readUint16BE();
- uint16 bottom = plst->readUint16BE();
-
- // We are also checking here to make sure we haven't drawn the image yet on screen.
- // This fixes problems with drawing PLST 1 twice and some other images twice. PLST
- // 1 is sometimes not called by the scripts, so some cards don't appear if we don't
- // draw PLST 1 each time. This "hack" is here to catch any PLST attempting to draw
- // twice. There should never be a problem with doing it this way.
- if (index == x && !(Common::find(_activatedPLSTs.begin(), _activatedPLSTs.end(), x) != _activatedPLSTs.end())) {
- debug(0, "Drawing image %d", id);
- copyImageToScreen(id, left, top, right, bottom);
- _activatedPLSTs.push_back(x);
- break;
- }
- }
-
- delete plst;
-}
-
-void RivenGraphics::updateScreen(Common::Rect updateRect) {
- if (_updatesEnabled) {
- _vm->runUpdateScreenScript();
-
- if (_dirtyScreen) {
- _activatedPLSTs.clear();
-
- // Copy to screen if there's no transition. Otherwise transition. ;)
- if (_scheduledTransition < 0)
- _vm->_system->copyRectToScreen((byte *)_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height());
- else
- runScheduledTransition();
-
- // Finally, update the screen.
- _vm->_system->updateScreen();
- _dirtyScreen = false;
- }
- }
-}
-
-void RivenGraphics::scheduleWaterEffect(uint16 sfxeID) {
- Common::SeekableReadStream *sfxeStream = _vm->getResource(ID_SFXE, sfxeID);
-
- if (sfxeStream->readUint16BE() != 'SL')
- error ("Unknown sfxe tag");
-
- // Read in header info
- SFXERecord sfxeRecord;
- sfxeRecord.frameCount = sfxeStream->readUint16BE();
- uint32 offsetTablePosition = sfxeStream->readUint32BE();
- sfxeRecord.rect.left = sfxeStream->readUint16BE();
- sfxeRecord.rect.top = sfxeStream->readUint16BE();
- sfxeRecord.rect.right = sfxeStream->readUint16BE();
- sfxeRecord.rect.bottom = sfxeStream->readUint16BE();
- sfxeRecord.speed = sfxeStream->readUint16BE();
- // Skip the rest of the fields...
-
- // Read in offsets
- sfxeStream->seek(offsetTablePosition);
- uint32 *frameOffsets = new uint32[sfxeRecord.frameCount];
- for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
- frameOffsets[i] = sfxeStream->readUint32BE();
- sfxeStream->seek(frameOffsets[0]);
-
- // Read in the scripts
- for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
- sfxeRecord.frameScripts.push_back(sfxeStream->readStream((i == sfxeRecord.frameCount - 1) ? sfxeStream->size() - frameOffsets[i] : frameOffsets[i + 1] - frameOffsets[i]));
-
- // Set it to the first frame
- sfxeRecord.curFrame = 0;
- sfxeRecord.lastFrameTime = 0;
-
- delete[] frameOffsets;
- delete sfxeStream;
- _waterEffects.push_back(sfxeRecord);
-}
-
-void RivenGraphics::clearWaterEffects() {
- _waterEffects.clear();
-}
-
-bool RivenGraphics::runScheduledWaterEffects() {
- // Don't run the effect if it's disabled
- if (_vm->_vars["waterenabled"] == 0)
- return false;
-
- Graphics::Surface *screen = NULL;
-
- for (uint16 i = 0; i < _waterEffects.size(); i++) {
- if (_vm->_system->getMillis() > _waterEffects[i].lastFrameTime + 1000 / _waterEffects[i].speed) {
- // Lock the screen!
- if (!screen)
- screen = _vm->_system->lockScreen();
-
- // Make sure the script is at the starting point
- Common::SeekableReadStream *script = _waterEffects[i].frameScripts[_waterEffects[i].curFrame];
- if (script->pos() != 0)
- script->seek(0);
-
- // Run script
- uint16 curRow = 0;
- for (uint16 op = script->readUint16BE(); op != 4; op = script->readUint16BE()) {
- if (op == 1) { // Increment Row
- curRow++;
- } else if (op == 3) { // Copy Pixels
- uint16 dstLeft = script->readUint16BE();
- uint16 srcLeft = script->readUint16BE();
- uint16 srcTop = script->readUint16BE();
- uint16 rowWidth = script->readUint16BE();
- memcpy ((byte *)screen->getBasePtr(dstLeft, curRow + _waterEffects[i].rect.top), (byte *)_mainScreen->getBasePtr(srcLeft, srcTop), rowWidth * _pixelFormat.bytesPerPixel);
- } else if (op != 4) { // End of Script
- error ("Unknown SFXE opcode %d", op);
- }
- }
-
- // Increment frame
- _waterEffects[i].curFrame++;
- if (_waterEffects[i].curFrame == _waterEffects[i].frameCount)
- _waterEffects[i].curFrame = 0;
-
- // Set the new time
- _waterEffects[i].lastFrameTime = _vm->_system->getMillis();
- }
- }
-
- // Unlock the screen if it has been locked and return true to update the screen
- if (screen) {
- _vm->_system->unlockScreen();
- return true;
- }
-
- return false;
-}
-
-void RivenGraphics::scheduleTransition(uint16 id, Common::Rect rect) {
- _scheduledTransition = id;
- _transitionRect = rect;
-}
-
-void RivenGraphics::runScheduledTransition() {
- if (_scheduledTransition < 0) // No transition is scheduled
- return;
-
- // TODO: There's a lot to be done here...
-
- // Note: Transitions 0-11 are actual transitions, but none are used in-game.
- // There's no point in implementing them if they're not used. These extra
- // transitions were found by hacking scripts.
-
- switch (_scheduledTransition) {
- case 0: // Swipe Left
- case 1: // Swipe Right
- case 2: // Swipe Up
- case 3: // Swipe Down
- case 12: // Pan Left
- case 13: // Pan Right
- case 14: // Pan Up
- case 15: // Pan Down
- case 16: // Dissolve
- case 17: // Dissolve (tspit CARD 155)
- break;
- default:
- if (_scheduledTransition >= 4 && _scheduledTransition <= 11)
- error("Found unused transition %d", _scheduledTransition);
- else
- error("Found unknown transition %d", _scheduledTransition);
- }
-
- // For now, just copy the image to screen without doing any transition.
- _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
- _vm->_system->updateScreen();
-
- _scheduledTransition = -1; // Clear scheduled transition
-}
-
-void RivenGraphics::clearMainScreen() {
- _mainScreen->fillRect(Common::Rect(0, 0, 608, 392), _pixelFormat.RGBToColor(0, 0, 0));
-}
-
-void RivenGraphics::fadeToBlack() {
- // The transition speed is forced to best here
- setTransitionSpeed(kRivenTransitionSpeedBest);
- scheduleTransition(16);
- clearMainScreen();
- runScheduledTransition();
-}
-
-void RivenGraphics::showInventory() {
- // Don't redraw the inventory
- if (_inventoryDrawn)
- return;
-
- // Clear the inventory area
- clearInventoryArea();
-
- // Draw the demo's exit button
- if (_vm->getFeatures() & GF_DEMO) {
- // extras.mhk tBMP 101 contains "EXIT" instead of Atrus' journal in the demo!
- // The demo's extras.mhk contains all the other inventory/marble/credits image
- // but has hacked tBMP 101 with "EXIT". *sigh*
- drawInventoryImage(101, g_demoExitRect);
- } else {
- // We don't want to show the inventory on setup screens or in other journals.
- if (_vm->getCurStack() == aspit)
- return;
-
- // There are three books and three vars. We have three different
- // combinations. At the start you have just Atrus' journal. Later,
- // you get Catherine's journal and the trap book. Near the end,
- // you lose the trap book and have just the two journals.
-
- bool hasCathBook = _vm->_vars["acathbook"] != 0;
- bool hasTrapBook = _vm->_vars["atrapbook"] != 0;
-
- if (!hasCathBook) {
- drawInventoryImage(101, g_atrusJournalRect1);
- } else if (!hasTrapBook) {
- drawInventoryImage(101, g_atrusJournalRect2);
- drawInventoryImage(102, g_cathJournalRect2);
- } else {
- drawInventoryImage(101, g_atrusJournalRect3);
- drawInventoryImage(102, g_cathJournalRect3);
- drawInventoryImage(100, g_trapBookRect3);
- }
- }
-
- _vm->_system->updateScreen();
- _inventoryDrawn = true;
-}
-
-void RivenGraphics::hideInventory() {
- // Don't hide the inventory twice
- if (!_inventoryDrawn)
- return;
-
- // Clear the area
- clearInventoryArea();
-
- _inventoryDrawn = false;
-}
-
-void RivenGraphics::clearInventoryArea() {
- // Clear the inventory area
- static const Common::Rect inventoryRect = Common::Rect(0, 392, 608, 436);
-
- // Lock the screen
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- // Fill the inventory area with black
- screen->fillRect(inventoryRect, _pixelFormat.RGBToColor(0, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void RivenGraphics::drawInventoryImage(uint16 id, const Common::Rect *rect) {
- MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
- mhkSurface->convertToTrueColor();
- Graphics::Surface *surface = mhkSurface->getSurface();
-
- _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, rect->left, rect->top, surface->w, surface->h);
-
- delete mhkSurface;
-}
-
-void RivenGraphics::drawRect(Common::Rect rect, bool active) {
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- if (active)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
- else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
-
- _vm->_system->unlockScreen();
-}
-
-void RivenGraphics::drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect) {
- // Draw tBMP id from srcRect to dstRect
- Graphics::Surface *surface = findImage(id)->getSurface();
-
- assert(srcRect.width() == dstRect.width() && srcRect.height() == dstRect.height());
-
- for (uint16 i = 0; i < srcRect.height(); i++)
- memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(srcRect.left, i + srcRect.top), srcRect.width() * surface->format.bytesPerPixel);
-
- _dirtyScreen = true;
-}
-
-void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) {
- MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
- mhkSurface->convertToTrueColor();
- Graphics::Surface *surface = mhkSurface->getSurface();
-
- assert(dstRect.width() == surface->w);
-
- for (uint16 i = 0; i < surface->h; i++)
- memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(0, i), surface->pitch);
-
- delete mhkSurface;
- _dirtyScreen = true;
-}
-
-void RivenGraphics::beginCredits() {
- // Clear the old cache
- clearCache();
-
- // Now cache all the credits images
- for (uint16 i = 302; i <= 320; i++) {
- MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, i));
- surface->convertToTrueColor();
- addImageToCache(i, surface);
- }
-
- // And clear our screen too
- clearMainScreen();
-}
-
-void RivenGraphics::updateCredits() {
- if ((_creditsImage == 303 || _creditsImage == 304) && _creditsPos == 0)
- fadeToBlack();
-
- if (_creditsImage < 304) {
- // For the first two credit images, they are faded from black to the image and then out again
- scheduleTransition(16);
-
- Graphics::Surface *frame = findImage(_creditsImage++)->getSurface();
-
- for (int y = 0; y < frame->h; y++)
- memcpy(_mainScreen->getBasePtr(124, y), frame->getBasePtr(0, y), frame->pitch);
-
- runScheduledTransition();
- } else {
- // Otheriwse, we're scrolling
- // Move the screen up one row
- memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
-
- // Only update as long as we're not before the last frame
- // Otherwise, we're just moving up a row (which we already did)
- if (_creditsImage <= 320) {
- // Copy the next row to the bottom of the screen
- Graphics::Surface *frame = findImage(_creditsImage)->getSurface();
- memcpy(_mainScreen->getBasePtr(124, _mainScreen->h - 1), frame->getBasePtr(0, _creditsPos), frame->pitch);
- _creditsPos++;
-
- if (_creditsPos == _mainScreen->h) {
- _creditsImage++;
- _creditsPos = 0;
- }
- }
-
- // Now flush the new screen
- _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
- _vm->_system->updateScreen();
- }
-}
-
-#endif // ENABLE_RIVEN
-
-LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = _vm->isPreMohawk() ? new LivingBooksBitmap_v1() : new MohawkBitmap();
-
- initGraphics(width, height, true);
-}
-
-LBGraphics::~LBGraphics() {
- delete _bmpDecoder;
-}
-
-MohawkSurface *LBGraphics::decodeImage(uint16 id) {
- if (_vm->isPreMohawk())
- return _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, id));
-
- return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
-}
-
-void LBGraphics::copyOffsetAnimImageToScreen(uint16 image, int left, int top) {
- MohawkSurface *mhkSurface = findImage(image);
-
- left -= mhkSurface->getOffsetX();
- top -= mhkSurface->getOffsetY();
-
- GraphicsManager::copyAnimImageToScreen(image, left, top);
-}
-
-bool LBGraphics::imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y) {
- MohawkSurface *mhkSurface = findImage(image);
-
- if (useOffsets) {
- x += mhkSurface->getOffsetX();
- y += mhkSurface->getOffsetY();
- }
-
- if (x < 0 || y < 0)
- return true;
-
- Graphics::Surface *surface = mhkSurface->getSurface();
- if (x >= surface->w || y >= surface->h)
- return true;
-
- return *(byte *)surface->getBasePtr(x, y) == 0;
-}
-
-void LBGraphics::setPalette(uint16 id) {
- // Old Living Books games use the old CTBL-style palette format while newer
- // games use the better tPAL format which can store partial palettes.
- if (_vm->isPreMohawk()) {
- Common::SeekableSubReadStreamEndian *ctblStream = _vm->wrapStreamEndian(ID_CTBL, id);
- uint16 colorCount = ctblStream->readUint16();
- byte *palette = new byte[colorCount * 3];
-
- for (uint16 i = 0; i < colorCount; i++) {
- palette[i * 3 + 0] = ctblStream->readByte();
- palette[i * 3 + 1] = ctblStream->readByte();
- palette[i * 3 + 2] = ctblStream->readByte();
- ctblStream->readByte();
- }
-
- delete ctblStream;
-
- _vm->_system->getPaletteManager()->setPalette(palette, 0, colorCount);
- delete[] palette;
- } else {
- GraphicsManager::setPalette(id);
- }
-}
-
-#ifdef ENABLE_CSTIME
-
-CSTimeGraphics::CSTimeGraphics(MohawkEngine_CSTime *vm) : GraphicsManager(), _vm(vm) {
- _bmpDecoder = new MohawkBitmap();
-
- initGraphics(640, 480, true);
-}
-
-CSTimeGraphics::~CSTimeGraphics() {
- delete _bmpDecoder;
-}
-
-void CSTimeGraphics::drawRect(Common::Rect rect, byte color) {
- rect.clip(Common::Rect(640, 480));
-
- // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
- if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
- return;
-
- Graphics::Surface *screen = _vm->_system->lockScreen();
-
- screen->frameRect(rect, color);
-
- _vm->_system->unlockScreen();
-}
-
-MohawkSurface *CSTimeGraphics::decodeImage(uint16 id) {
- return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
-}
-
-Common::Array<MohawkSurface *> CSTimeGraphics::decodeImages(uint16 id) {
- return _bmpDecoder->decodeImages(_vm->getResource(ID_TBMH, id));
-}
-
-#endif
-
} // End of namespace Mohawk
diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h
index 463608a2aa..51d25db5d9 100644
--- a/engines/mohawk/graphics.h
+++ b/engines/mohawk/graphics.h
@@ -25,12 +25,11 @@
#include "mohawk/bitmap.h"
-#include "common/file.h"
#include "common/hashmap.h"
-#include "graphics/pict.h"
+#include "common/rect.h"
namespace Graphics {
-class JPEG;
+struct Surface;
}
namespace Mohawk {
@@ -99,200 +98,10 @@ protected:
private:
// An image cache that stores images until clearCache() is called
- Common::HashMap<uint16, MohawkSurface*> _cache;
- Common::HashMap<uint16, Common::Array<MohawkSurface*> > _subImageCache;
+ Common::HashMap<uint16, MohawkSurface *> _cache;
+ Common::HashMap<uint16, Common::Array<MohawkSurface *> > _subImageCache;
};
-#ifdef ENABLE_MYST
-
-class MystBitmap;
-class MohawkEngine_Myst;
-
-enum RectState {
- kRectEnabled,
- kRectDisabled,
- kRectUnreachable
-};
-
-class MystGraphics : public GraphicsManager {
-public:
- MystGraphics(MohawkEngine_Myst*);
- ~MystGraphics();
-
- void loadExternalPictureFile(uint16 stack);
- void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
- void copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest);
- void copyImageToScreen(uint16 image, Common::Rect dest);
- void copyImageToBackBuffer(uint16 image, Common::Rect dest);
- void copyBackBufferToScreen(Common::Rect r);
- void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
- void drawRect(Common::Rect rect, RectState state);
- void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
- void enableDrawingTimeSimulation(bool enable);
- void fadeToBlack();
- void fadeFromBlack();
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
- void simulatePreviousDrawDelay(const Common::Rect &dest);
- void copyBackBufferToScreenWithSaturation(int16 saturation);
-
-private:
- MohawkEngine_Myst *_vm;
- MystBitmap *_bmpDecoder;
- Graphics::PictDecoder *_pictDecoder;
- Graphics::JPEG *_jpegDecoder;
-
- struct PictureFile {
- uint32 pictureCount;
- struct PictureEntry {
- uint32 offset;
- uint32 size;
- uint16 id;
- uint16 type;
- uint16 width;
- uint16 height;
- } *entries;
-
- Common::File picFile;
- } _pictureFile;
-
- Graphics::Surface *_backBuffer;
- Graphics::PixelFormat _pixelFormat;
- Common::Rect _viewport;
-
- int _enableDrawingTimeSimulation;
- uint32 _nextAllowedDrawTime;
- static const uint _constantDrawDelay = 10; // ms
- static const uint _proportionalDrawDelay = 500; // pixels per ms
-};
-
-#endif // ENABLE_MYST
-
-#ifdef ENABLE_RIVEN
-
-class MohawkEngine_Riven;
-
-class RivenGraphics : public GraphicsManager {
-public:
- RivenGraphics(MohawkEngine_Riven *vm);
- ~RivenGraphics();
-
- void copyImageToScreen(uint16, uint32, uint32, uint32, uint32);
- void updateScreen(Common::Rect updateRect = Common::Rect(0, 0, 608, 392));
- bool _updatesEnabled;
- Common::Array<uint16> _activatedPLSTs;
- void drawPLST(uint16 x);
- void drawRect(Common::Rect rect, bool active);
- void drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect);
- void drawExtrasImage(uint16 id, Common::Rect dstRect);
-
- // Water Effect
- void scheduleWaterEffect(uint16);
- void clearWaterEffects();
- bool runScheduledWaterEffects();
-
- // Transitions
- void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
- void runScheduledTransition();
- void fadeToBlack();
- void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; }
-
- // Inventory
- void showInventory();
- void hideInventory();
-
- // Credits
- void beginCredits();
- void updateCredits();
- uint getCurCreditsImage() { return _creditsImage; }
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkEngine_Riven *_vm;
- MohawkBitmap *_bitmapDecoder;
-
- // Water Effects
- struct SFXERecord {
- // Record values
- uint16 frameCount;
- Common::Rect rect;
- uint16 speed;
- Common::Array<Common::SeekableReadStream*> frameScripts;
-
- // Cur frame
- uint16 curFrame;
- uint32 lastFrameTime;
- };
- Common::Array<SFXERecord> _waterEffects;
-
- // Transitions
- int16 _scheduledTransition;
- Common::Rect _transitionRect;
- uint32 _transitionSpeed;
-
- // Inventory
- void clearInventoryArea();
- void drawInventoryImage(uint16 id, const Common::Rect *rect);
- bool _inventoryDrawn;
-
- // Screen Related
- Graphics::Surface *_mainScreen;
- bool _dirtyScreen;
- Graphics::PixelFormat _pixelFormat;
- void clearMainScreen();
-
- // Credits
- uint _creditsImage, _creditsPos;
-};
-
-#endif // ENABLE_RIVEN
-
-class LBGraphics : public GraphicsManager {
-public:
- LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height);
- ~LBGraphics();
-
- void setPalette(uint16 id);
- void copyOffsetAnimImageToScreen(uint16 image, int left = 0, int top = 0);
- bool imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y);
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkBitmap *_bmpDecoder;
- MohawkEngine_LivingBooks *_vm;
-};
-
-#ifdef ENABLE_CSTIME
-
-class MohawkEngine_CSTime;
-
-class CSTimeGraphics : public GraphicsManager {
-public:
- CSTimeGraphics(MohawkEngine_CSTime *vm);
- ~CSTimeGraphics();
-
- void drawRect(Common::Rect rect, byte color);
-
-protected:
- MohawkSurface *decodeImage(uint16 id);
- Common::Array<MohawkSurface *> decodeImages(uint16 id);
- MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
-
-private:
- MohawkBitmap *_bmpDecoder;
- MohawkEngine_CSTime *_vm;
-};
-
-#endif
-
} // End of namespace Mohawk
#endif
diff --git a/engines/mohawk/installer_archive.cpp b/engines/mohawk/installer_archive.cpp
index 83796158a6..636b7ae476 100644
--- a/engines/mohawk/installer_archive.cpp
+++ b/engines/mohawk/installer_archive.cpp
@@ -107,18 +107,18 @@ void InstallerArchive::close() {
_map.clear();
}
-bool InstallerArchive::hasFile(const Common::String &name) {
+bool InstallerArchive::hasFile(const Common::String &name) const {
return _map.contains(name);
}
-int InstallerArchive::listMembers(Common::ArchiveMemberList &list) {
+int InstallerArchive::listMembers(Common::ArchiveMemberList &list) const {
for (FileMap::const_iterator it = _map.begin(); it != _map.end(); it++)
list.push_back(getMember(it->_key));
return _map.size();
}
-Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) {
+const Common::ArchiveMemberPtr InstallerArchive::getMember(const Common::String &name) const {
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
}
diff --git a/engines/mohawk/installer_archive.h b/engines/mohawk/installer_archive.h
index 27877d69f9..89d2d85f8d 100644
--- a/engines/mohawk/installer_archive.h
+++ b/engines/mohawk/installer_archive.h
@@ -43,9 +43,9 @@ public:
bool isOpen() const { return _stream != 0; }
// Common::Archive API implementation
- bool hasFile(const Common::String &name);
- int listMembers(Common::ArchiveMemberList &list);
- Common::ArchiveMemberPtr getMember(const Common::String &name);
+ bool hasFile(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
private:
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 65073bd970..708478a6d8 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -102,6 +102,14 @@ void LBPage::open(Archive *mhk, uint16 baseId) {
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->init();
+
+ for (uint32 i = 0; i < _items.size(); i++)
+ _items[i]->startPhase(kLBPhaseLoad);
+}
+
+void LBPage::addClonedItem(LBItem *item) {
+ _vm->addItem(item);
+ _items.push_back(item);
}
void LBPage::itemDestroyed(LBItem *item) {
@@ -138,8 +146,12 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa
const Common::FSNode gameDataDir(ConfMan.get("path"));
// Rugrats
- SearchMan.addSubDirectoryMatching(gameDataDir, "program");
- SearchMan.addSubDirectoryMatching(gameDataDir, "Rugrats Adventure Game");
+ const Common::FSNode ProgPath = gameDataDir.getChild("program");
+ if (ProgPath.exists())
+ SearchMan.addDirectory(ProgPath.getPath(), ProgPath, 0, 2);
+ const Common::FSNode RugPath = gameDataDir.getChild("Rugrats Adventure Game");
+ if (RugPath.exists())
+ SearchMan.addDirectory(RugPath.getPath(), RugPath, 0, 2);
// CarmenTQ
const Common::FSNode CTQPath = gameDataDir.getChild("95instal");
if (CTQPath.exists())
@@ -304,8 +316,9 @@ void MohawkEngine_LivingBooks::loadBookInfo(const Common::String &filename) {
const Common::ConfigFile::SectionKeyList globals = _bookInfoFile.getKeys("Globals");
for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
- debug("global: %s", command.c_str());
- // TODO: run command
+ LBCode tempCode(this, 0);
+ uint offset = tempCode.parseCode(command);
+ tempCode.runCode(NULL, offset);
}
}
}
@@ -375,10 +388,13 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
}
// TODO: fading between pages
+#if 0
bool fade = false;
if (leftover.contains("fade")) {
fade = true;
}
+#endif
+
if (leftover.contains("read")) {
_readOnly = true;
}
@@ -436,12 +452,9 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
void MohawkEngine_LivingBooks::updatePage() {
switch (_phase) {
- case 0:
- for (uint32 i = 0; i < _items.size(); i++)
- _items[i]->startPhase(0xFFFE);
-
+ case kLBPhaseInit:
for (uint32 i = 0; i < _items.size(); i++)
- _items[i]->startPhase(0xFFFF);
+ _items[i]->startPhase(kLBPhaseCreate);
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->startPhase(_phase);
@@ -537,7 +550,7 @@ void MohawkEngine_LivingBooks::updatePage() {
_phase++;
break;
- case 1:
+ case kLBPhaseIntro:
for (uint32 i = 0; i < _items.size(); i++)
_items[i]->startPhase(_phase);
@@ -550,7 +563,7 @@ void MohawkEngine_LivingBooks::updatePage() {
_phase++;
break;
- case 2:
+ case kLBPhaseMain:
if (!_introDone)
break;
@@ -593,8 +606,8 @@ void MohawkEngine_LivingBooks::updatePage() {
_items[i]->update();
if (_needsRedraw) {
- for (uint16 i = 0; i < _items.size(); i++)
- _items[i]->draw();
+ for (Common::List<LBItem *>::const_iterator i = _orderedItems.reverse_begin(); i != _orderedItems.end(); --i)
+ (*i)->draw();
_needsRedraw = false;
_needsUpdate = true;
@@ -1854,6 +1867,35 @@ void LBAnimation::seek(uint16 pos) {
}
}
+void LBAnimation::seekToTime(uint32 time) {
+ _lastTime = 0;
+ _currentFrame = 0;
+
+ if (_currentSound != 0xffff) {
+ _vm->_sound->stopSound(_currentSound);
+ _currentSound = 0xffff;
+ }
+
+ for (uint32 i = 0; i < _nodes.size(); i++)
+ _nodes[i]->reset();
+
+ uint32 elapsed = 0;
+ while (elapsed <= time) {
+ bool ranSomething = false;
+ // nodes don't wait while seeking
+ for (uint32 i = 0; i < _nodes.size(); i++)
+ ranSomething |= (_nodes[i]->update(true) != kLBNodeDone);
+
+ elapsed += _tempo;
+ _currentFrame++;
+
+ if (!ranSomething) {
+ _running = false;
+ break;
+ }
+ }
+}
+
void LBAnimation::stop() {
_running = false;
if (_currentSound != 0xffff) {
@@ -1920,7 +1962,10 @@ LBScriptEntry::~LBScriptEntry() {
}
LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : _vm(vm), _page(page), _rect(rect) {
- _phase = 0;
+ if (_vm->getGameType() == GType_LIVINGBOOKSV1 || _vm->getGameType() == GType_LIVINGBOOKSV2)
+ _phase = kLBPhaseInit;
+ else
+ _phase = kLBPhaseLoad;
_loopMode = 0;
_delayMin = 0;
@@ -1931,7 +1976,7 @@ LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) :
_controlMode = kLBControlNone;
_soundMode = 0;
- _neverEnabled = true;
+ _loaded = false;
_enabled = false;
_visible = true;
_playing = false;
@@ -2338,6 +2383,22 @@ void LBItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *
}
break;
+ case kLBSetRolloverData:
+ {
+ assert(size == 2);
+ uint16 flag = stream->readUint16();
+ warning("ignoring kLBSetRolloverData: item %s, flag %d", _desc.c_str(), flag);
+ }
+ break;
+
+ case kLBSetParent:
+ {
+ assert(size == 2);
+ uint16 parent = stream->readUint16();
+ warning("ignoring kLBSetParent: item %s, parent id %d", _desc.c_str(), parent);
+ }
+ break;
+
case kLBUnknown194:
{
assert(size == 4);
@@ -2365,25 +2426,27 @@ void LBItem::destroySelf() {
}
void LBItem::setEnabled(bool enabled) {
- if (enabled && _neverEnabled && !_playing) {
+ if (enabled && !_loaded && !_playing) {
if (_timingMode == kLBAutoUserIdle) {
setNextTime(_periodMin, _periodMax);
debug(2, "Enable time startup");
}
}
- _neverEnabled = false;
_enabled = enabled;
}
void LBItem::setGlobalEnabled(bool enabled) {
- bool wasEnabled = !_neverEnabled && _enabled && _globalEnabled;
+ bool wasEnabled = _loaded && _enabled && _globalEnabled;
_globalEnabled = enabled;
- if (wasEnabled != (!_neverEnabled && _enabled && _globalEnabled))
+ if (wasEnabled != (_loaded && _enabled && _globalEnabled))
setEnabled(enabled);
}
bool LBItem::contains(Common::Point point) {
+ if (!_loaded)
+ return false;
+
if (_playing && _loopMode == 0xFFFF)
stop();
@@ -2394,7 +2457,7 @@ bool LBItem::contains(Common::Point point) {
}
void LBItem::update() {
- if (_phase != 0x7FFF && (_neverEnabled || !_enabled || !_globalEnabled))
+ if (_phase != kLBPhaseNone && (!_loaded || !_enabled || !_globalEnabled))
return;
if (_nextTime == 0 || _nextTime > (uint32)(_vm->_system->getMillis() / 16))
@@ -2409,7 +2472,7 @@ void LBItem::update() {
}
void LBItem::handleMouseDown(Common::Point pos) {
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return;
_vm->setFocus(this);
@@ -2432,7 +2495,7 @@ bool LBItem::togglePlaying(bool playing, bool restart) {
_vm->queueDelayedEvent(DelayedEvent(this, kLBDelayedEventDone));
return true;
}
- if (((!_neverEnabled && _enabled && _globalEnabled) || _phase == 0x7FFF) && !_playing) {
+ if (((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) && !_playing) {
_playing = togglePlaying(true, restart);
if (_playing) {
_nextTime = 0;
@@ -2501,6 +2564,10 @@ void LBItem::done(bool onlyNotify) {
notify(0xFFFF, _itemId);
}
+void LBItem::init() {
+ runScript(kLBEventInit);
+}
+
void LBItem::setVisible(bool visible) {
if (visible == _visible)
return;
@@ -2517,38 +2584,40 @@ void LBItem::setGlobalVisible(bool visible) {
}
void LBItem::startPhase(uint phase) {
- if (_phase == phase)
- setEnabled(true);
+ if (_phase == phase) {
+ if (_phase != kLBPhaseNone) {
+ setEnabled(true);
+ }
+
+ load();
+ }
switch (phase) {
- case 0xFFFE:
- if (_timingMode == kLBAutoLoad) {
- debug(2, "Phase load: time startup");
- setNextTime(_periodMin, _periodMax);
- }
+ case kLBPhaseLoad:
+ runScript(kLBEventListLoad);
break;
- case 0xFFFF:
+ case kLBPhaseCreate:
runScript(kLBEventPhaseCreate);
if (_timingMode == kLBAutoCreate) {
debug(2, "Phase create: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 0:
+ case kLBPhaseInit:
runScript(kLBEventPhaseInit);
if (_timingMode == kLBAutoInit) {
debug(2, "Phase init: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 1:
+ case kLBPhaseIntro:
runScript(kLBEventPhaseIntro);
if (_timingMode == kLBAutoIntro || _timingMode == kLBAutoUserIdle) {
debug(2, "Phase intro: time startup");
setNextTime(_periodMin, _periodMax);
}
break;
- case 2:
+ case kLBPhaseMain:
runScript(kLBEventPhaseMain);
if (_timingMode == kLBAutoUserIdle || _timingMode == kLBAutoMain) {
debug(2, "Phase main: time startup");
@@ -2579,6 +2648,54 @@ void LBItem::notify(uint16 data, uint16 from) {
runScript(kLBEventNotified, data, from);
}
+void LBItem::load() {
+ if (_loaded)
+ return;
+
+ _loaded = true;
+
+ // FIXME: events etc
+ if (_timingMode == kLBAutoLoad) {
+ debug(2, "Load: time startup");
+ setNextTime(_periodMin, _periodMax);
+ }
+}
+
+void LBItem::unload() {
+ if (!_loaded)
+ return;
+
+ _loaded = false;
+
+ // FIXME: stuff
+}
+
+void LBItem::moveBy(const Common::Point &pos) {
+ _rect.translate(pos.x, pos.y);
+}
+
+void LBItem::moveTo(const Common::Point &pos) {
+ _rect.moveTo(pos);
+}
+
+LBItem *LBItem::clone(uint16 newId, const Common::String &newName) {
+ LBItem *item = createClone();
+
+ item->_itemId = newId;
+ item->_desc = newName;
+
+ item->_resourceId = _resourceId;
+ // FIXME: the rest
+
+ _page->addClonedItem(item);
+ // FIXME: zorder?
+ return item;
+}
+
+LBItem *LBItem::createClone() {
+ return new LBItem(_vm, _page, _rect);
+}
+
void LBItem::runScript(uint event, uint16 data, uint16 from) {
for (uint i = 0; i < _scriptEntries.size(); i++) {
LBScriptEntry *entry = _scriptEntries[i];
@@ -2819,9 +2936,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
break;
case kLBOpLoad:
- // FIXME
- warning("ignoring kLBOpLoad (event 0x%04x, param 0x%04x, target '%s')",
- entry->event, entry->param, target->_desc.c_str());
+ target->load();
break;
case kLBOpPreload:
@@ -2831,9 +2946,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
break;
case kLBOpUnload:
- // FIXME
- warning("ignoring kLBOpUnload (event 0x%04x, param 0x%04x, target '%s')",
- entry->event, entry->param, target->_desc.c_str());
+ target->unload();
break;
case kLBOpSeekToPrev:
@@ -2882,6 +2995,7 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
case kLBOpBreakExpression:
debug(2, "BreakExpression");
i = entry->subentries.size();
+ break;
case kLBOpJumpToExpression:
debug(2, "JumpToExpression got %d (on %d, of %d)", e, i, entry->subentries.size());
i = e - 1;
@@ -2969,7 +3083,7 @@ bool LBSoundItem::togglePlaying(bool playing, bool restart) {
_vm->_sound->stopSound(_resourceId);
}
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return false;
_running = true;
@@ -2987,6 +3101,10 @@ void LBSoundItem::stop() {
LBItem::stop();
}
+LBItem *LBSoundItem::createClone() {
+ return new LBSoundItem(_vm, _page, _rect);
+}
+
LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBGroupItem");
_starting = false;
@@ -3102,6 +3220,44 @@ void LBGroupItem::stop() {
}
}
+void LBGroupItem::load() {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->load();
+ }
+}
+
+void LBGroupItem::unload() {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->unload();
+ }
+}
+
+void LBGroupItem::moveBy(const Common::Point &pos) {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->moveBy(pos);
+ }
+}
+
+void LBGroupItem::moveTo(const Common::Point &pos) {
+ for (uint i = 0; i < _groupEntries.size(); i++) {
+ LBItem *item = _vm->getItemById(_groupEntries[i].entryId);
+ if (item)
+ item->moveTo(pos);
+ }
+}
+
+LBItem *LBGroupItem::createClone() {
+ // TODO: needed?
+ error("LBGroupItem::createClone unimplemented");
+ return new LBGroupItem(_vm, _page, _rect);
+}
+
LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPaletteItem");
@@ -3187,6 +3343,10 @@ void LBPaletteItem::update() {
LBItem::update();
}
+LBItem *LBPaletteItem::createClone() {
+ error("can't clone LBPaletteItem");
+}
+
LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_currentPhrase = 0xFFFF;
_currentWord = 0xFFFF;
@@ -3350,7 +3510,7 @@ void LBLiveTextItem::drawWord(uint word, uint yPos) {
}
void LBLiveTextItem::handleMouseDown(Common::Point pos) {
- if (_neverEnabled || !_enabled || !_globalEnabled || _playing)
+ if (!_loaded || !_enabled || !_globalEnabled || _playing)
return LBItem::handleMouseDown(pos);
pos.x -= _rect.left;
@@ -3381,7 +3541,7 @@ void LBLiveTextItem::handleMouseDown(Common::Point pos) {
bool LBLiveTextItem::togglePlaying(bool playing, bool restart) {
if (!playing)
return LBItem::togglePlaying(playing, restart);
- if (_neverEnabled || !_enabled || !_globalEnabled)
+ if (!_loaded || !_enabled || !_globalEnabled)
return _playing;
// TODO: handle this properly
@@ -3400,7 +3560,7 @@ void LBLiveTextItem::stop() {
}
void LBLiveTextItem::notify(uint16 data, uint16 from) {
- if (_neverEnabled || !_enabled || !_globalEnabled || !_playing)
+ if (!_loaded || !_enabled || !_globalEnabled || !_playing)
return LBItem::notify(data, from);
if (_currentWord != 0xFFFF) {
@@ -3434,6 +3594,10 @@ void LBLiveTextItem::notify(uint16 data, uint16 from) {
LBItem::notify(data, from);
}
+LBItem *LBLiveTextItem::createClone() {
+ error("can't clone LBLiveTextItem");
+}
+
LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPictureItem");
}
@@ -3468,15 +3632,21 @@ bool LBPictureItem::contains(Common::Point point) {
void LBPictureItem::init() {
_vm->_gfx->preloadImage(_resourceId);
+
+ LBItem::init();
}
void LBPictureItem::draw() {
- if (!_visible || !_globalVisible)
+ if (!_loaded || !_visible || !_globalVisible)
return;
_vm->_gfx->copyAnimImageToScreen(_resourceId, _rect.left, _rect.top);
}
+LBItem *LBPictureItem::createClone() {
+ return new LBPictureItem(_vm, _page, _rect);
+}
+
LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_anim = NULL;
_running = false;
@@ -3489,9 +3659,9 @@ LBAnimationItem::~LBAnimationItem() {
void LBAnimationItem::setEnabled(bool enabled) {
if (_running) {
- if (enabled && _globalEnabled && _neverEnabled)
+ if (enabled && _globalEnabled && !_loaded)
_anim->start();
- else if (!_neverEnabled && !enabled && _enabled && _globalEnabled)
+ else if (_loaded && !enabled && _enabled && _globalEnabled)
_anim->stop();
}
@@ -3509,7 +3679,7 @@ bool LBAnimationItem::contains(Common::Point point) {
}
void LBAnimationItem::update() {
- if (!_neverEnabled && _enabled && _globalEnabled && _running) {
+ if (_loaded && _enabled && _globalEnabled && _running) {
bool wasDone = _anim->update();
if (wasDone) {
_running = false;
@@ -3522,7 +3692,7 @@ void LBAnimationItem::update() {
bool LBAnimationItem::togglePlaying(bool playing, bool restart) {
if (playing) {
- if (!_neverEnabled && _enabled && _globalEnabled) {
+ if (_loaded && _enabled && _globalEnabled) {
if (restart)
seek(1);
_running = true;
@@ -3545,6 +3715,8 @@ void LBAnimationItem::done(bool onlyNotify) {
void LBAnimationItem::init() {
_anim = new LBAnimation(_vm, this, _resourceId);
+
+ LBItem::init();
}
void LBAnimationItem::stop() {
@@ -3562,6 +3734,10 @@ void LBAnimationItem::seek(uint16 pos) {
_anim->seek(pos);
}
+void LBAnimationItem::seekToTime(uint32 time) {
+ _anim->seekToTime(time);
+}
+
void LBAnimationItem::startPhase(uint phase) {
if (phase == _phase)
seek(1);
@@ -3576,6 +3752,12 @@ void LBAnimationItem::draw() {
_anim->draw();
}
+LBItem *LBAnimationItem::createClone() {
+ LBAnimationItem *item = new LBAnimationItem(_vm, _page, _rect);
+ item->_anim = new LBAnimation(_vm, item, _resourceId);
+ return item;
+}
+
LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMovieItem");
}
@@ -3595,7 +3777,7 @@ void LBMovieItem::update() {
bool LBMovieItem::togglePlaying(bool playing, bool restart) {
if (playing) {
- if ((!_neverEnabled && _enabled && _globalEnabled) || _phase == 0x7FFF) {
+ if ((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) {
_vm->_video->playMovie(_resourceId, _rect.left, _rect.top);
return true;
@@ -3605,6 +3787,10 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) {
return LBItem::togglePlaying(playing, restart);
}
+LBItem *LBMovieItem::createClone() {
+ return new LBMovieItem(_vm, _page, _rect);
+}
+
LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMiniGameItem");
}
@@ -3640,6 +3826,10 @@ bool LBMiniGameItem::togglePlaying(bool playing, bool restart) {
return false;
}
+LBItem *LBMiniGameItem::createClone() {
+ error("can't clone LBMiniGameItem");
+}
+
LBProxyItem::LBProxyItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBProxyItem");
@@ -3650,7 +3840,10 @@ LBProxyItem::~LBProxyItem() {
delete _page;
}
-void LBProxyItem::init() {
+void LBProxyItem::load() {
+ if (_loaded)
+ return;
+
Common::String leftover;
Common::String filename = _vm->getFileNameFromConfig("Proxies", _desc.c_str(), leftover);
if (!leftover.empty())
@@ -3669,6 +3862,19 @@ void LBProxyItem::init() {
error("failed to open archive '%s' (for proxy '%s')", filename.c_str(), _desc.c_str());
_page = new LBPage(_vm);
_page->open(pageArchive, baseId);
+
+ LBItem::load();
+}
+
+void LBProxyItem::unload() {
+ delete _page;
+ _page = NULL;
+
+ LBItem::unload();
+}
+
+LBItem *LBProxyItem::createClone() {
+ return new LBProxyItem(_vm, _page, _rect);
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index 008a7dbf23..91d6a8cd30 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -25,7 +25,7 @@
#include "mohawk/mohawk.h"
#include "mohawk/console.h"
-#include "mohawk/graphics.h"
+#include "mohawk/livingbooks_graphics.h"
#include "mohawk/sound.h"
#include "common/config-file.h"
@@ -68,6 +68,15 @@ enum LBMode {
kLBPlayMode = 6
};
+enum {
+ kLBPhaseInit = 0x0,
+ kLBPhaseIntro = 0x1,
+ kLBPhaseMain = 0x2,
+ kLBPhaseNone = 0x7fff,
+ kLBPhaseLoad = 0xfffe,
+ kLBPhaseCreate = 0xffff
+};
+
// automatic modes used in _timingMode
enum {
kLBAutoNone = 0,
@@ -178,10 +187,10 @@ enum {
kLBGlobalSetNotVisible = 0x79,
kLBGlobalSetVisible = 0x7a, // unused?
kLBSetAmbient = 0x7b,
- kLBUnknown7C = 0x7c, // unused?
+ kLBSetDragParams = 0x7c,
kLBSetKeyEvent = 0x7d,
- kLBUnknown7E = 0x7e, // unused? (rect flag)
- kLBSetParent = 0x7f, // unused?
+ kLBSetRolloverData = 0x7e,
+ kLBSetParent = 0x7f,
kLBSetHitTest = 0x80,
// from here, rugrats
kLBUnknown194 = 0x194
@@ -331,6 +340,7 @@ public:
void start();
void seek(uint16 pos);
+ void seekToTime(uint32 time);
void stop();
void playSound(uint16 resourceId);
@@ -391,23 +401,34 @@ public:
virtual void handleMouseUp(Common::Point pos); // 0xD
virtual bool togglePlaying(bool playing, bool restart = false); // 0xF
virtual void done(bool onlyNotify); // 0x10
- virtual void init() { } // 0x11
+ virtual void init(); // 0x11
virtual void seek(uint16 pos) { } // 0x13
+ virtual void seekToTime(uint32 time) { }
virtual void setFocused(bool focused) { } // 0x14
virtual void setVisible(bool visible); // 0x17
virtual void setGlobalVisible(bool enabled);
virtual void startPhase(uint phase); // 0x18
virtual void stop(); // 0x19
virtual void notify(uint16 data, uint16 from); // 0x1A
+ virtual void load();
+ virtual void unload();
+ virtual void moveBy(const Common::Point &pos);
+ virtual void moveTo(const Common::Point &pos);
+
+ LBItem *clone(uint16 newId, const Common::String &newName);
uint16 getId() { return _itemId; }
const Common::String &getName() { return _desc; }
const Common::Rect &getRect() { return _rect; }
uint16 getSoundPriority() { return _soundMode; }
+ bool isLoaded() { return _loaded; }
bool isAmbient() { return _isAmbient; }
Common::List<LBItem *>::iterator _iterator;
+ // TODO: make private
+ Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables;
+
protected:
MohawkEngine_LivingBooks *_vm;
LBPage *_page;
@@ -420,7 +441,7 @@ protected:
uint16 _resourceId;
uint16 _itemId;
- bool _visible, _globalVisible, _playing, _enabled, _neverEnabled, _globalEnabled;
+ bool _loaded, _visible, _globalVisible, _playing, _enabled, _globalEnabled;
uint32 _nextTime, _startTime;
uint16 _loops;
@@ -433,6 +454,8 @@ protected:
bool _isAmbient;
bool _doHitTest;
+ virtual LBItem *createClone();
+
Common::Array<LBScriptEntry *> _scriptEntries;
void runScript(uint event, uint16 data = 0, uint16 from = 0);
int runScriptEntry(LBScriptEntry *entry);
@@ -453,6 +476,8 @@ public:
void stop();
protected:
+ LBItem *createClone();
+
bool _running;
};
@@ -478,8 +503,14 @@ public:
void setGlobalVisible(bool visible);
void startPhase(uint phase);
void stop();
+ void load();
+ void unload();
+ void moveBy(const Common::Point &pos);
+ void moveTo(const Common::Point &pos);
protected:
+ LBItem *createClone();
+
bool _starting;
Common::Array<GroupEntry> _groupEntries;
@@ -496,6 +527,8 @@ public:
void update();
protected:
+ LBItem *createClone();
+
uint16 _fadeInPeriod, _fadeInStep, _drawStart, _drawCount;
uint32 _fadeInStart, _fadeInCurrent;
byte *_palette;
@@ -527,6 +560,8 @@ public:
void notify(uint16 data, uint16 from);
protected:
+ LBItem *createClone();
+
void paletteUpdate(uint16 word, bool on);
void drawWord(uint word, uint yPos);
@@ -550,6 +585,9 @@ public:
bool contains(Common::Point point);
void draw();
void init();
+
+protected:
+ LBItem *createClone();
};
class LBAnimationItem : public LBItem {
@@ -565,10 +603,13 @@ public:
void done(bool onlyNotify);
void init();
void seek(uint16 pos);
+ void seekToTime(uint32 time);
void startPhase(uint phase);
void stop();
protected:
+ LBItem *createClone();
+
LBAnimation *_anim;
bool _running;
};
@@ -580,6 +621,9 @@ public:
void update();
bool togglePlaying(bool playing, bool restart);
+
+protected:
+ LBItem *createClone();
};
class LBMiniGameItem : public LBItem {
@@ -588,6 +632,9 @@ public:
~LBMiniGameItem();
bool togglePlaying(bool playing, bool restart);
+
+protected:
+ LBItem *createClone();
};
class LBProxyItem : public LBItem {
@@ -595,9 +642,12 @@ public:
LBProxyItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBProxyItem();
- void init();
+ void load();
+ void unload();
protected:
+ LBItem *createClone();
+
class LBPage *_page;
};
@@ -634,6 +684,7 @@ public:
void open(Archive *mhk, uint16 baseId);
uint16 getResourceVersion();
+ void addClonedItem(LBItem *item);
void itemDestroyed(LBItem *item);
LBCode *_code;
@@ -697,7 +748,7 @@ public:
void nextPage();
// TODO: make private
- Common::HashMap<Common::String, LBValue> _variables;
+ Common::HashMap<Common::String, LBValue, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _variables;
// helper functions, also used by LBProxyItem
Common::String getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp
index 80b5fe9660..bb8f7a0d05 100644
--- a/engines/mohawk/livingbooks_code.cpp
+++ b/engines/mohawk/livingbooks_code.cpp
@@ -21,8 +21,10 @@
*/
#include "mohawk/livingbooks.h"
+#include "mohawk/livingbooks_lbx.h"
#include "mohawk/resource.h"
+#include "common/events.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -99,12 +101,17 @@ double LBValue::toDouble() const {
Common::Point LBValue::toPoint() const {
switch (type) {
case kLBValueString:
- // FIXME
- return Common::Point();
+ {
+ Common::Point ret;
+ sscanf(string.c_str(), "%hd , %hd", &ret.x, &ret.y);
+ return ret;
+ }
case kLBValueInteger:
return Common::Point(integer, integer);
case kLBValuePoint:
return point;
+ case kLBValueRect:
+ return Common::Point(rect.left, rect.top);
default:
error("failed to convert to point");
}
@@ -113,10 +120,15 @@ Common::Point LBValue::toPoint() const {
Common::Rect LBValue::toRect() const {
switch (type) {
case kLBValueString:
- // FIXME
- return Common::Rect();
+ {
+ Common::Rect ret;
+ sscanf(string.c_str(), "%hd , %hd , %hd , %hd", &ret.left, &ret.top, &ret.right, &ret.bottom);
+ return ret;
+ }
case kLBValueInteger:
return Common::Rect(integer, integer, integer, integer);
+ case kLBValuePoint:
+ return Common::Rect(point.x, point.y, point.x, point.y);
case kLBValueRect:
return rect;
case kLBValueItemPtr:
@@ -476,26 +488,84 @@ void LBCode::parseMain() {
if (_currToken == kTokenAssign)
error("attempted assignment to self");
break;
- } else if (_currToken == kTokenAssign) {
+ }
+ bool indexing = false;
+ Common::Array<LBValue> index;
+ while (_currToken == kTokenListStart) {
+ debugN("[");
+ nextToken();
+ parseStatement();
+ if (_currToken != kTokenListEnd)
+ error("expected list end");
+ debugN("]");
+ nextToken();
+ if (!_stack.size())
+ error("index failed");
+ indexing = true;
+ index.push_back(_stack.pop());
+ }
+ if (_currToken == kTokenAssign) {
debugN(" = ");
nextToken();
parseStatement();
if (!_stack.size())
error("assignment failed");
- LBValue *val = &_vm->_variables[varname];
- *val = _stack.pop();
- _stack.push(*val);
+ LBValue *val;
+ if (indexing)
+ val = getIndexedVar(varname, index);
+ else
+ val = &_vm->_variables[varname];
+ if (val) {
+ *val = _stack.pop();
+ _stack.push(*val);
+ } else
+ _stack.push(LBValue());
+ } else if (_currToken == kTokenAndEquals) {
+ debugN(" &= ");
+ nextToken();
+ parseStatement();
+ if (!_stack.size())
+ error("assignment failed");
+ LBValue *val;
+ if (indexing)
+ val = getIndexedVar(varname, index);
+ else
+ val = &_vm->_variables[varname];
+ if (val) {
+ if (val->type != kLBValueString)
+ error("operator &= used on non-string");
+ val->string = val->string + _stack.pop().toString();
+ _stack.push(*val);
+ } else
+ _stack.push(LBValue());
} else {
- _stack.push(_vm->_variables[varname]);
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ _stack.push(*val);
+ else
+ _stack.push(LBValue());
+ } else
+ _stack.push(_vm->_variables[varname]);
}
// FIXME: pre/postincrement for non-integers
if (_currToken == kTokenPlusPlus) {
debugN("++");
- _vm->_variables[varname].integer++;
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ val->integer++;
+ } else
+ _vm->_variables[varname].integer++;
nextToken();
} else if (_currToken == kTokenMinusMinus) {
debugN("--");
- _vm->_variables[varname].integer--;
+ if (indexing) {
+ LBValue *val = getIndexedVar(varname, index);
+ if (val)
+ val->integer--;
+ } else
+ _vm->_variables[varname].integer--;
nextToken();
}
}
@@ -567,6 +637,28 @@ void LBCode::parseMain() {
nextToken();
break;
+ case kTokenListStart:
+ debugN("[");
+ nextToken();
+ {
+ Common::SharedPtr<LBList> list = Common::SharedPtr<LBList>(new LBList);
+ while (_currToken != kTokenListEnd) {
+ parseStatement();
+ if (!_stack.size())
+ error("unexpected empty stack during literal list evaluation");
+ list->array.push_back(_stack.pop());
+ if (_currToken == kTokenComma) {
+ debugN(", ");
+ nextToken();
+ } else if (_currToken != kTokenListEnd)
+ error("encountered unexpected token %02x during literal list", _currToken);
+ }
+ debugN("]");
+ nextToken();
+ _stack.push(list);
+ }
+ break;
+
case kTokenNot:
debugN("!");
nextToken();
@@ -607,6 +699,20 @@ void LBCode::parseMain() {
}
}
+LBValue *LBCode::getIndexedVar(Common::String varname, const Common::Array<LBValue> &index) {
+ LBValue *var = &_vm->_variables[varname];
+ for (uint i = 0; i < index.size(); i++) {
+ if (var->type != kLBValueList)
+ error("variable '%s' was indexed, but isn't a list after %d indexes", varname.c_str(), i);
+ if (index[i].type != kLBValueInteger)
+ error("index %d wasn't an integer", i);
+ if (index[i].integer < 1 || index[i].integer > (int)var->list->array.size())
+ return NULL;
+ var = &var->list->array[index[i].integer - 1];
+ }
+ return var;
+}
+
LBItem *LBCode::resolveItem(const LBValue &value) {
if (value.type == kLBValueItemPtr)
return value.item;
@@ -626,7 +732,7 @@ Common::Array<LBValue> LBCode::readParams() {
byte numParams = _data[_currOffset++];
if (!numParams) {
- debugN("()\n");
+ debugN("()");
nextToken();
return params;
}
@@ -688,14 +794,14 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "random", &LBCode::cmdRandom },
{ "stringLen", &LBCode::cmdStringLen },
{ "substring", &LBCode::cmdSubstring },
- { "max", 0 },
- { "min", 0 },
- { "abs", 0 },
+ { "max", &LBCode::cmdMax },
+ { "min", &LBCode::cmdMin },
+ { "abs", &LBCode::cmdAbs },
{ "getRect", &LBCode::cmdGetRect }, // also "makeRect"
- { "makePt", 0 }, // also "makePair"
+ { "makePt", &LBCode::cmdMakePoint }, // also "makePair"
{ "topLeft", &LBCode::cmdTopLeft },
{ "bottomRight", &LBCode::cmdBottomRight },
- { "mousePos", 0 },
+ { "mousePos", &LBCode::cmdMousePos },
{ "top", &LBCode::cmdTop },
{ "left", &LBCode::cmdLeft },
{ "bottom", &LBCode::cmdBottom },
@@ -704,7 +810,7 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "xpos", 0 },
{ "ypos", 0 },
{ "playFrom", 0 },
- { "move", 0 },
+ { "move", &LBCode::cmdMove },
{ 0, 0 },
{ 0, 0 },
{ "setDragParams", &LBCode::cmdSetDragParams },
@@ -727,26 +833,26 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "getPage", 0 },
{ "getWorldRect", 0 },
{ "isWorldWrap", 0 },
- { "newList", 0 },
+ { "newList", &LBCode::cmdNewList },
{ "deleteList", 0 },
- { "add", 0 },
+ { "add", &LBCode::cmdAdd },
{ 0, 0 },
- { "addAt", 0 },
+ { "addAt", &LBCode::cmdAddAt },
{ "getAt", 0 },
// 0x30
{ 0, 0 },
{ "getIndex", 0 },
- { "setAt", 0 },
- { "listLen", 0 },
- { "deleteAt", 0 },
- { "clearList", 0 },
+ { "setAt", &LBCode::cmdSetAt },
+ { "listLen", &LBCode::cmdListLen },
+ { "deleteAt", &LBCode::cmdDeleteAt },
+ { "clearList", &LBCode::cmdUnimplemented },
{ "setWorld", 0 },
- { "setProperty", 0 },
- { "getProperty", 0 },
+ { "setProperty", &LBCode::cmdSetProperty },
+ { "getProperty", &LBCode::cmdGetProperty },
{ "copyList", 0 },
{ "invoke", 0 },
- { "exec", 0 },
- { "return", 0 },
+ { "exec", &LBCode::cmdExec },
+ { "return", &LBCode::cmdReturn },
{ "sendSync", 0 },
{ "moveViewOrigin", 0 },
{ "addToGroup", 0 },
@@ -775,8 +881,8 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "setDisplay", &LBCode::cmdUnimplemented },
{ "getDisplay", 0 },
{ 0, 0 },
- { "lbxCreate", 0 },
- { "lbxFunc", 0 },
+ { "lbxCreate", &LBCode::cmdLBXCreate },
+ { "lbxFunc", &LBCode::cmdLBXFunc },
{ "waitCursor", 0 },
{ "debugBreak", 0 },
{ "menuItemEnable", 0 },
@@ -886,6 +992,35 @@ void LBCode::cmdSubstring(const Common::Array<LBValue> &params) {
_stack.push(substring);
}
+void LBCode::cmdMax(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to max", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ int b = params[1].toInt();
+ _stack.push(MAX(a, b));
+}
+
+void LBCode::cmdMin(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to min", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ int b = params[1].toInt();
+ _stack.push(MIN(a, b));
+}
+
+void LBCode::cmdAbs(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to abs", params.size());
+
+ // FIXME: fp
+ int a = params[0].toInt();
+ _stack.push(ABS(a));
+}
+
void LBCode::cmdGetRect(const Common::Array<LBValue> &params) {
if (params.size() < 2) {
_stack.push(getRectFromParams(params));
@@ -899,6 +1034,12 @@ void LBCode::cmdGetRect(const Common::Array<LBValue> &params) {
error("incorrect number of parameters (%d) to getRect", params.size());
}
+void LBCode::cmdMakePoint(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to makePoint", params.size());
+ _stack.push(Common::Point(params[0].toInt(), params[1].toInt()));
+}
+
void LBCode::cmdTopLeft(const Common::Array<LBValue> &params) {
if (params.size() > 1)
error("too many parameters (%d) to topLeft", params.size());
@@ -915,6 +1056,14 @@ void LBCode::cmdBottomRight(const Common::Array<LBValue> &params) {
_stack.push(Common::Point(rect.bottom, rect.right));
}
+void LBCode::cmdMousePos(const Common::Array<LBValue> &params) {
+ if (params.size() != 0)
+ error("too many parameters (%d) to mousePos", params.size());
+
+ Common::Point pt = _vm->_system->getEventManager()->getMousePos();
+ _stack.push(pt);
+}
+
void LBCode::cmdTop(const Common::Array<LBValue> &params) {
if (params.size() > 1)
error("too many parameters (%d) to top", params.size());
@@ -947,10 +1096,170 @@ void LBCode::cmdRight(const Common::Array<LBValue> &params) {
_stack.push(rect.right);
}
+void LBCode::cmdMove(const Common::Array<LBValue> &params) {
+ if (params.size() != 1 && params.size() != 2)
+ error("incorrect number of parameters (%d) to move", params.size());
+
+ LBItem *target = _currSource;
+ Common::Point pt;
+ if (params.size() == 1) {
+ pt = params[0].toPoint();
+ } else {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted move on invalid item (%s)", params[0].toString().c_str());
+ pt = params[1].toPoint();
+ }
+
+ target->moveBy(pt);
+}
+
void LBCode::cmdSetDragParams(const Common::Array<LBValue> &params) {
warning("ignoring setDragParams");
}
+void LBCode::cmdNewList(const Common::Array<LBValue> &params) {
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to newList", params.size());
+
+ _stack.push(Common::SharedPtr<LBList>(new LBList));
+}
+
+void LBCode::cmdAdd(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to add", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to add");
+
+ params[0].list->array.push_back(params[1]);
+}
+
+void LBCode::cmdAddAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 3)
+ error("incorrect number of parameters (%d) to addAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to addAt");
+
+ if (params[1].type != kLBValueInteger || params[1].integer < 1)
+ error("invalid index passed to addAt");
+
+ if ((uint)params[1].integer > params[0].list->array.size())
+ params[0].list->array.resize(params[1].integer);
+ params[0].list->array.insert_at(params[1].integer - 1, params[2]);
+}
+
+void LBCode::cmdSetAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 3)
+ error("incorrect number of parameters (%d) to setAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to setAt");
+
+ if (params[1].type != kLBValueInteger || params[1].integer < 1)
+ error("invalid index passed to setAt");
+
+ if ((uint)params[1].integer > params[0].list->array.size())
+ params[0].list->array.resize(params[1].integer);
+ params[0].list->array[params[1].integer - 1] = params[2];
+}
+
+void LBCode::cmdListLen(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to listLen", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to lbxFunc");
+
+ _stack.push(params[0].list->array.size());
+}
+
+void LBCode::cmdDeleteAt(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to deleteAt", params.size());
+
+ if (params[0].type != kLBValueList || !params[0].list)
+ error("invalid lbx object passed to deleteAt");
+
+ if (params[1].type != kLBValueInteger)
+ error("invalid index passed to deleteAt");
+ if (params[1].integer < 1 || params[1].integer > (int)params[0].list->array.size())
+ return;
+ params[0].list->array.remove_at(params[1].integer - 1);
+}
+
+void LBCode::cmdSetProperty(const Common::Array<LBValue> &params) {
+ if (params.size() < 2 || params.size() > 3)
+ error("incorrect number of parameters (%d) to setProperty", params.size());
+
+ Common::String name;
+ LBValue val;
+ LBItem *target = _currSource;
+ if (params.size() == 3) {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted setProperty on invalid item (%s)", params[0].toString().c_str());
+ name = params[1].toString();
+ val = params[2];
+ } else {
+ name = params[0].toString();
+ val = params[1];
+ }
+
+ target->_variables[name] = val;
+}
+
+void LBCode::cmdGetProperty(const Common::Array<LBValue> &params) {
+ if (params.size() < 1 || params.size() > 2)
+ error("incorrect number of parameters (%d) to getProperty", params.size());
+
+ Common::String name;
+ LBItem *target = _currSource;
+ if (params.size() == 2) {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted getProperty on invalid item (%s)", params[0].toString().c_str());
+ name = params[1].toString();
+ } else {
+ name = params[0].toString();
+ }
+
+ _stack.push(target->_variables[name]);
+}
+
+void LBCode::cmdExec(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to exec", params.size());
+ if (params[0].type != kLBValueInteger || params[0].integer < 0)
+ error("invalid offset passed to exec");
+ uint offset = (uint)params[0].integer;
+
+ uint32 oldOffset = _currOffset;
+ byte oldToken = _currToken;
+ LBValue val = runCode(_currSource, offset);
+ _currOffset = oldOffset;
+ _currToken = oldToken;
+
+ _stack.push(val);
+ _stack.push(val);
+}
+
+void LBCode::cmdReturn(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to return", params.size());
+
+ if (!_stack.size())
+ error("empty stack on entry to return");
+
+ if (params[0] == _stack.top()) {
+ _stack.pop();
+ _stack.push(params[1]);
+ _currToken = kTokenEndOfFile;
+ } else
+ _stack.push(_stack.top());
+}
+
void LBCode::cmdSetPlayParams(const Common::Array<LBValue> &params) {
if (params.size() > 8)
error("too many parameters (%d) to setPlayParams", params.size());
@@ -994,6 +1303,32 @@ void LBCode::cmdSetHitTest(const Common::Array<LBValue> &params) {
warning("ignoring setHitTest");
}
+void LBCode::cmdLBXCreate(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to lbxCreate", params.size());
+
+ _stack.push(createLBXObject(_vm, params[0].toInt()));
+}
+
+void LBCode::cmdLBXFunc(const Common::Array<LBValue> &params) {
+ if (params.size() < 2)
+ error("incorrect number of parameters (%d) to lbxFunc", params.size());
+
+ if (params[0].type != kLBValueLBX || !params[0].lbx)
+ error("invalid lbx object passed to lbxFunc");
+
+ Common::SharedPtr<LBXObject> lbx = params[0].lbx;
+ uint callId = params[1].toInt();
+
+ Common::Array<LBValue> callParams;
+ for (uint i = 0; i < params.size() - 2; i++)
+ callParams.push_back(params[i + 2]);
+
+ LBValue result;
+ if (lbx->call(callId, callParams, result))
+ _stack.push(result);
+}
+
void LBCode::cmdKey(const Common::Array<LBValue> &params) {
_stack.push(0); // FIXME
warning("ignoring Key");
@@ -1001,7 +1336,7 @@ void LBCode::cmdKey(const Common::Array<LBValue> &params) {
#define NUM_ITEM_COMMANDS 34
CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = {
- { "clone", 0 },
+ { "clone", &LBCode::itemClone },
{ "destroy", 0 },
{ "dragBeginFrom", 0 },
{ "dragEnd", 0 },
@@ -1022,14 +1357,14 @@ CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = {
{ "isMuted", 0 },
{ "isPlaying", &LBCode::itemIsPlaying },
{ "isVisible", 0 },
- { "isLoaded", 0 },
+ { "isLoaded", &LBCode::itemIsLoaded },
{ "isDragging", 0 },
{ "load", 0 },
{ "moveTo", &LBCode::itemMoveTo },
{ "mute", 0 },
{ "play", 0 },
{ "seek", &LBCode::itemSeek },
- { "seekToFrame", 0 },
+ { "seekToFrame", &LBCode::itemSeekToFrame },
{ "setParent", &LBCode::itemSetParent },
{ "setZOrder", 0 },
{ "setText", 0 },
@@ -1054,14 +1389,50 @@ void LBCode::runItemCommand() {
(this->*(info.func))(params);
}
+void LBCode::itemClone(const Common::Array<LBValue> &params) {
+ // TODO: first param can be target?
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to setParent", params.size());
+
+ uint id = params[0].toInt();
+ const Common::String &name = params[1].toString();
+
+ _currSource->clone(id, name);
+}
+
void LBCode::itemIsPlaying(const Common::Array<LBValue> &params) {
// TODO
warning("ignoring isPlaying");
_stack.push(0);
}
+void LBCode::itemIsLoaded(const Common::Array<LBValue> &params) {
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to isLoaded", params.size());
+
+ LBItem *item = resolveItem(params[0]);
+ if (!item || !item->isLoaded())
+ _stack.push(0);
+ else
+ _stack.push(1);
+}
+
void LBCode::itemMoveTo(const Common::Array<LBValue> &params) {
- warning("ignoring moveTo");
+ if (params.size() != 1 && params.size() != 2)
+ error("incorrect number of parameters (%d) to moveTo", params.size());
+
+ LBItem *target = _currSource;
+ Common::Point pt;
+ if (params.size() == 1) {
+ pt = params[0].toPoint();
+ } else {
+ target = resolveItem(params[0]);
+ if (!target)
+ error("attempted moveTo on invalid item (%s)", params[0].toString().c_str());
+ pt = params[1].toPoint();
+ }
+
+ target->moveTo(pt);
}
void LBCode::itemSeek(const Common::Array<LBValue> &params) {
@@ -1072,6 +1443,17 @@ void LBCode::itemSeek(const Common::Array<LBValue> &params) {
if (!item)
error("attempted seek on invalid item (%s)", params[0].toString().c_str());
uint seekTo = params[1].toInt();
+ item->seekToTime(seekTo);
+}
+
+void LBCode::itemSeekToFrame(const Common::Array<LBValue> &params) {
+ if (params.size() != 2)
+ error("incorrect number of parameters (%d) to seekToFrame", params.size());
+
+ LBItem *item = resolveItem(params[0]);
+ if (!item)
+ error("attempted seekToFrame on invalid item (%s)", params[0].toString().c_str());
+ uint seekTo = params[1].toInt();
item->seek(seekTo);
}
@@ -1091,7 +1473,7 @@ void LBCode::runNotifyCommand() {
debugN("goto");
Common::Array<LBValue> params = readParams();
// TODO: type-checking
- NotifyEvent notifyEvent(kLBNotifyChangePage, 0);
+ NotifyEvent notifyEvent(kLBNotifyChangePage, 1);
switch (params.size()) {
case 4:
notifyEvent.type = kLBNotifyChangeMode; // FIXME: type 8?
@@ -1327,6 +1709,8 @@ uint LBCode::parseCode(const Common::String &source) {
break;
// open bracket
case '(':
+ bool parameterless;
+ parameterless = false;
if (wasFunction) {
// function call parameters
wasFunction = false;
@@ -1342,6 +1726,7 @@ uint LBCode::parseCode(const Common::String &source) {
continue;
if (source[i] != ')')
break;
+ parameterless = true;
code[code.size() - 1] = 0;
break;
}
@@ -1349,14 +1734,20 @@ uint LBCode::parseCode(const Common::String &source) {
// brackets around expression
counterPositions.push_back(0);
}
- code.push_back(kTokenOpenBracket);
+ if (!parameterless)
+ code.push_back(kTokenOpenBracket);
break;
// close bracket
case ')':
if (counterPositions.empty())
error("while parsing script '%s', encountered unmatched )", source.c_str());
+
+ // don't push a kTokenCloseBracket for a parameterless function call
+ uint counterPos2;
+ counterPos2 = counterPositions.back();
+ if (!counterPos2 || code[counterPos2])
+ code.push_back(kTokenCloseBracket);
counterPositions.pop_back();
- code.push_back(kTokenCloseBracket);
break;
// comma (seperating function params)
case ',':
@@ -1375,7 +1766,7 @@ uint LBCode::parseCode(const Common::String &source) {
{
Common::String tempString;
while (pos < source.size()) {
- if (!isalpha(source[pos]) && !isdigit(source[pos]))
+ if (!Common::isAlpha(source[pos]) && !Common::isDigit(source[pos]))
break;
tempString += source[pos++];
}
@@ -1386,7 +1777,7 @@ uint LBCode::parseCode(const Common::String &source) {
}
break;
default:
- if (isdigit(token)) {
+ if (Common::isDigit(token)) {
const char *in = source.c_str() + pos - 1;
// FIXME: handle floats?
char *endptr;
@@ -1401,15 +1792,21 @@ uint LBCode::parseCode(const Common::String &source) {
WRITE_BE_UINT16(tmp, (int16)intValue);
code.push_back(tmp[0]);
code.push_back(tmp[1]);
- } else if (isalpha(token)) {
+ } else if (Common::isAlpha(token)) {
Common::String tempString;
tempString += token;
while (pos < source.size()) {
- if (!isalpha(source[pos]) && !isdigit(source[pos]))
+ if (!Common::isAlpha(source[pos]) && !Common::isDigit(source[pos]))
break;
tempString += source[pos++];
}
- wasFunction = parseCodeSymbol(tempString, pos, code);
+ if (tempString.equalsIgnoreCase("true")) {
+ code.push_back(kTokenTrue);
+ } else if (tempString.equalsIgnoreCase("false")) {
+ code.push_back(kTokenFalse);
+ } else {
+ wasFunction = parseCodeSymbol(tempString, pos, code);
+ }
} else {
error("while parsing script '%s', couldn't parse '%c'", source.c_str(), token);
}
diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h
index 79c9af94f7..47dd90f814 100644
--- a/engines/mohawk/livingbooks_code.h
+++ b/engines/mohawk/livingbooks_code.h
@@ -23,6 +23,7 @@
#ifndef MOHAWK_LIVINGBOOKS_CODE_H
#define MOHAWK_LIVINGBOOKS_CODE_H
+#include "common/ptr.h"
#include "common/rect.h"
#include "common/stack.h"
#include "common/substream.h"
@@ -31,6 +32,8 @@ namespace Mohawk {
class MohawkEngine_LivingBooks;
class LBItem;
+class LBXObject;
+struct LBList;
enum LBValueType {
kLBValueString,
@@ -38,7 +41,9 @@ enum LBValueType {
kLBValueReal,
kLBValuePoint,
kLBValueRect,
- kLBValueItemPtr
+ kLBValueItemPtr,
+ kLBValueLBX,
+ kLBValueList
};
struct LBValue {
@@ -66,6 +71,14 @@ struct LBValue {
type = kLBValueItemPtr;
item = itm;
}
+ LBValue(Common::SharedPtr<LBXObject> l) {
+ type = kLBValueLBX;
+ lbx = l;
+ }
+ LBValue(Common::SharedPtr<LBList> l) {
+ type = kLBValueList;
+ list = l;
+ }
LBValue(const LBValue &val) {
type = val.type;
switch (type) {
@@ -87,6 +100,12 @@ struct LBValue {
case kLBValueItemPtr:
item = val.item;
break;
+ case kLBValueLBX:
+ lbx = val.lbx;
+ break;
+ case kLBValueList:
+ list = val.list;
+ break;
}
}
@@ -97,6 +116,8 @@ struct LBValue {
Common::Point point;
Common::Rect rect;
LBItem *item;
+ Common::SharedPtr<LBXObject> lbx;
+ Common::SharedPtr<LBList> list;
bool operator==(const LBValue &x) const;
bool operator!=(const LBValue &x) const;
@@ -111,6 +132,10 @@ struct LBValue {
Common::Rect toRect() const;
};
+struct LBList {
+ Common::Array<LBValue> array;
+};
+
enum {
kLBCodeLiteralInteger = 0x1
};
@@ -207,6 +232,7 @@ protected:
void parseArithmetic2();
void parseMain();
+ LBValue *getIndexedVar(Common::String varname, const Common::Array<LBValue> &index);
LBItem *resolveItem(const LBValue &value);
Common::Array<LBValue> readParams();
Common::Rect getRectFromParams(const Common::Array<LBValue> &params);
@@ -224,22 +250,43 @@ public:
void cmdRandom(const Common::Array<LBValue> &params);
void cmdStringLen(const Common::Array<LBValue> &params);
void cmdSubstring(const Common::Array<LBValue> &params);
+ void cmdMax(const Common::Array<LBValue> &params);
+ void cmdMin(const Common::Array<LBValue> &params);
+ void cmdAbs(const Common::Array<LBValue> &params);
void cmdGetRect(const Common::Array<LBValue> &params);
+ void cmdMakePoint(const Common::Array<LBValue> &params);
void cmdTopLeft(const Common::Array<LBValue> &params);
void cmdBottomRight(const Common::Array<LBValue> &params);
+ void cmdMousePos(const Common::Array<LBValue> &params);
void cmdTop(const Common::Array<LBValue> &params);
void cmdLeft(const Common::Array<LBValue> &params);
void cmdBottom(const Common::Array<LBValue> &params);
void cmdRight(const Common::Array<LBValue> &params);
+ void cmdMove(const Common::Array<LBValue> &params);
void cmdSetDragParams(const Common::Array<LBValue> &params);
+ void cmdNewList(const Common::Array<LBValue> &params);
+ void cmdAdd(const Common::Array<LBValue> &params);
+ void cmdAddAt(const Common::Array<LBValue> &params);
+ void cmdSetAt(const Common::Array<LBValue> &params);
+ void cmdListLen(const Common::Array<LBValue> &params);
+ void cmdDeleteAt(const Common::Array<LBValue> &params);
+ void cmdSetProperty(const Common::Array<LBValue> &params);
+ void cmdGetProperty(const Common::Array<LBValue> &params);
+ void cmdExec(const Common::Array<LBValue> &params);
+ void cmdReturn(const Common::Array<LBValue> &params);
void cmdSetPlayParams(const Common::Array<LBValue> &params);
void cmdSetKeyEvent(const Common::Array<LBValue> &params);
void cmdSetHitTest(const Common::Array<LBValue> &params);
+ void cmdLBXCreate(const Common::Array<LBValue> &params);
+ void cmdLBXFunc(const Common::Array<LBValue> &params);
void cmdKey(const Common::Array<LBValue> &params);
+ void itemClone(const Common::Array<LBValue> &params);
void itemIsPlaying(const Common::Array<LBValue> &params);
+ void itemIsLoaded(const Common::Array<LBValue> &params);
void itemMoveTo(const Common::Array<LBValue> &params);
void itemSeek(const Common::Array<LBValue> &params);
+ void itemSeekToFrame(const Common::Array<LBValue> &params);
void itemSetParent(const Common::Array<LBValue> &params);
};
diff --git a/engines/mohawk/livingbooks_graphics.cpp b/engines/mohawk/livingbooks_graphics.cpp
new file mode 100644
index 0000000000..fb764fa15b
--- /dev/null
+++ b/engines/mohawk/livingbooks_graphics.cpp
@@ -0,0 +1,102 @@
+/* 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.
+ *
+ */
+
+#include "mohawk/resource.h"
+#include "mohawk/livingbooks.h"
+#include "mohawk/livingbooks_graphics.h"
+
+#include "common/substream.h"
+#include "common/system.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+
+namespace Mohawk {
+
+LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = _vm->isPreMohawk() ? new LivingBooksBitmap_v1() : new MohawkBitmap();
+
+ initGraphics(width, height, true);
+}
+
+LBGraphics::~LBGraphics() {
+ delete _bmpDecoder;
+}
+
+MohawkSurface *LBGraphics::decodeImage(uint16 id) {
+ if (_vm->isPreMohawk())
+ return _bmpDecoder->decodeImage(_vm->wrapStreamEndian(ID_BMAP, id));
+
+ return _bmpDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+}
+
+void LBGraphics::copyOffsetAnimImageToScreen(uint16 image, int left, int top) {
+ MohawkSurface *mhkSurface = findImage(image);
+
+ left -= mhkSurface->getOffsetX();
+ top -= mhkSurface->getOffsetY();
+
+ GraphicsManager::copyAnimImageToScreen(image, left, top);
+}
+
+bool LBGraphics::imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y) {
+ MohawkSurface *mhkSurface = findImage(image);
+
+ if (useOffsets) {
+ x += mhkSurface->getOffsetX();
+ y += mhkSurface->getOffsetY();
+ }
+
+ if (x < 0 || y < 0)
+ return true;
+
+ Graphics::Surface *surface = mhkSurface->getSurface();
+ if (x >= surface->w || y >= surface->h)
+ return true;
+
+ return *(byte *)surface->getBasePtr(x, y) == 0;
+}
+
+void LBGraphics::setPalette(uint16 id) {
+ // Old Living Books games use the old CTBL-style palette format while newer
+ // games use the better tPAL format which can store partial palettes.
+ if (_vm->isPreMohawk()) {
+ Common::SeekableSubReadStreamEndian *ctblStream = _vm->wrapStreamEndian(ID_CTBL, id);
+ uint16 colorCount = ctblStream->readUint16();
+ byte *palette = new byte[colorCount * 3];
+
+ for (uint16 i = 0; i < colorCount; i++) {
+ palette[i * 3 + 0] = ctblStream->readByte();
+ palette[i * 3 + 1] = ctblStream->readByte();
+ palette[i * 3 + 2] = ctblStream->readByte();
+ ctblStream->readByte();
+ }
+
+ delete ctblStream;
+
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, colorCount);
+ delete[] palette;
+ } else {
+ GraphicsManager::setPalette(id);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks_graphics.h b/engines/mohawk/livingbooks_graphics.h
new file mode 100644
index 0000000000..3e2609750a
--- /dev/null
+++ b/engines/mohawk/livingbooks_graphics.h
@@ -0,0 +1,52 @@
+/* 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.
+ *
+ */
+
+#ifndef MOHAWK_LIVINGBOOKS_GRAPHICS_H
+#define MOHAWK_LIVINGBOOKS_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_LivingBooks;
+
+class LBGraphics : public GraphicsManager {
+public:
+ LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height);
+ ~LBGraphics();
+
+ void setPalette(uint16 id);
+ void copyOffsetAnimImageToScreen(uint16 image, int left = 0, int top = 0);
+ bool imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y);
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkBitmap *_bmpDecoder;
+ MohawkEngine_LivingBooks *_vm;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/livingbooks_lbx.cpp b/engines/mohawk/livingbooks_lbx.cpp
new file mode 100644
index 0000000000..9628e06294
--- /dev/null
+++ b/engines/mohawk/livingbooks_lbx.cpp
@@ -0,0 +1,141 @@
+/* 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.
+ *
+ */
+
+#include "engines/mohawk/livingbooks.h"
+#include "engines/mohawk/livingbooks_lbx.h"
+
+namespace Mohawk {
+
+class LBXDataFile : public LBXObject {
+public:
+ LBXDataFile(MohawkEngine_LivingBooks *vm);
+ ~LBXDataFile();
+
+ bool call(uint callId, const Common::Array<LBValue> &params, LBValue &result);
+
+protected:
+ Common::ConfigFile _dataFile;
+ Common::String _curSection;
+
+ void open(const Common::String &filename);
+ bool sectionExists(const Common::String &section);
+};
+
+LBXDataFile::LBXDataFile(MohawkEngine_LivingBooks *vm) : LBXObject(vm) {
+}
+
+LBXDataFile::~LBXDataFile() {
+}
+
+enum {
+ kLBXDataFileOpen = 1,
+ kLBXDataFileGetSectionList = 4,
+ kLBXDataFileSetCurSection = 5,
+ kLBXDataFileLoadCurSectionVars = 8,
+ kLBXDataFileDeleteCurSection = 10,
+ kLBXDataFileSectionExists = 14
+};
+
+bool LBXDataFile::call(uint callId, const Common::Array<LBValue> &params, LBValue &result) {
+ switch (callId) {
+ case kLBXDataFileOpen:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::open", params.size());
+
+ open(params[0].toString());
+ return false;
+
+ case kLBXDataFileGetSectionList:
+ {
+ Common::SharedPtr<LBList> list = Common::SharedPtr<LBList>(new LBList);
+ Common::ConfigFile::SectionList sections = _dataFile.getSections();
+ for (Common::List<Common::ConfigFile::Section>::const_iterator i = sections.begin(); i != sections.end(); ++i)
+ list->array.push_back(LBValue(i->name));
+ result = LBValue(list);
+ }
+ return true;
+
+ case kLBXDataFileSetCurSection:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::setCurSection", params.size());
+
+ _curSection = params[0].toString();
+ return false;
+
+ case kLBXDataFileLoadCurSectionVars:
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to LBXDataFile::loadCurSectionVars", params.size());
+
+ {
+ const Common::ConfigFile::SectionKeyList globals = _dataFile.getKeys(_curSection);
+ for (Common::ConfigFile::SectionKeyList::const_iterator i = globals.begin(); i != globals.end(); i++) {
+ Common::String command = Common::String::format("%s = %s", i->key.c_str(), i->value.c_str());
+ LBCode tempCode(_vm, 0);
+ uint offset = tempCode.parseCode(command);
+ tempCode.runCode(NULL, offset);
+ }
+ }
+ return false;
+
+ case kLBXDataFileDeleteCurSection:
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to LBXDataFile::deleteCurSection", params.size());
+
+ _dataFile.removeSection(_curSection);
+ return false;
+
+ case kLBXDataFileSectionExists:
+ if (params.size() != 1)
+ error("incorrect number of parameters (%d) to LBXDataFile::sectionExists", params.size());
+ if (_dataFile.hasSection(params[0].toString()))
+ result = 1;
+ else
+ result = 0;
+ return true;
+
+ default:
+ error("LBXDataFile call %d is unknown", callId);
+ }
+}
+
+void LBXDataFile::open(const Common::String &filename) {
+ _dataFile.clear();
+
+ if (_dataFile.loadFromFile(filename))
+ return;
+
+ // FIXME: try savegames
+
+ error("LBXDataFile::open: couldn't open '%s'", filename.c_str());
+}
+
+Common::SharedPtr<LBXObject> createLBXObject(MohawkEngine_LivingBooks *vm, uint16 type) {
+ switch (type) {
+ case 1001:
+ return Common::SharedPtr<LBXObject>(new LBXDataFile(vm));
+
+ default:
+ error("unknown LBX object type %d", type);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks_lbx.h b/engines/mohawk/livingbooks_lbx.h
new file mode 100644
index 0000000000..3cca0a8e82
--- /dev/null
+++ b/engines/mohawk/livingbooks_lbx.h
@@ -0,0 +1,47 @@
+/* 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.
+ *
+ */
+
+#ifndef MOHAWK_LIVINGBOOKS_LBX_H
+#define MOHAWK_LIVINGBOOKS_LBX_H
+
+#include "engines/mohawk/livingbooks_code.h"
+
+#include "common/ptr.h"
+
+namespace Mohawk {
+
+class LBXObject {
+public:
+ LBXObject(MohawkEngine_LivingBooks *vm) : _vm(vm) { }
+ virtual ~LBXObject() { }
+
+ virtual bool call(uint callId, const Common::Array<LBValue> &params, LBValue &result) = 0;
+
+protected:
+ MohawkEngine_LivingBooks *_vm;
+};
+
+Common::SharedPtr<LBXObject> createLBXObject(MohawkEngine_LivingBooks *vm, uint16 type);
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk
index 30f1d40fdb..83e541e3e4 100644
--- a/engines/mohawk/module.mk
+++ b/engines/mohawk/module.mk
@@ -10,6 +10,8 @@ MODULE_OBJS = \
installer_archive.o \
livingbooks.o \
livingbooks_code.o \
+ livingbooks_graphics.o \
+ livingbooks_lbx.o \
mohawk.o \
resource.o \
sound.o \
@@ -21,6 +23,7 @@ MODULE_OBJS += \
cstime.o \
cstime_cases.o \
cstime_game.o \
+ cstime_graphics.o \
cstime_ui.o \
cstime_view.o
endif
@@ -29,6 +32,7 @@ ifdef ENABLE_MYST
MODULE_OBJS += \
myst.o \
myst_areas.o \
+ myst_graphics.o \
myst_scripts.o \
myst_state.o \
resource_cache.o \
@@ -50,6 +54,7 @@ ifdef ENABLE_RIVEN
MODULE_OBJS += \
riven.o \
riven_external.o \
+ riven_graphics.o \
riven_saveload.o \
riven_scripts.o \
riven_vars.o
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index eeb4594f3c..c22b30ad4d 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -27,9 +27,9 @@
#include "common/textconsole.h"
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/myst_state.h"
#include "mohawk/dialogs.h"
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 02f0a46e3f..30770f7ec9 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -173,7 +173,7 @@ public:
MystGraphics *_gfx;
MystGameState *_gameState;
MystScriptParser *_scriptParser;
- Common::Array<MystResource*> _resources;
+ Common::Array<MystResource *> _resources;
MystResource *_dragResource;
Common::RandomSource *_rnd;
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 294fcea2f1..fe33ceaa9b 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_areas.h b/engines/mohawk/myst_areas.h
index 136356ea4f..62af5ec4cf 100644
--- a/engines/mohawk/myst_areas.h
+++ b/engines/mohawk/myst_areas.h
@@ -20,11 +20,13 @@
*
*/
+#ifndef MYST_AREAS_H
+#define MYST_AREAS_H
+
#include "mohawk/myst.h"
#include "mohawk/video.h"
-#ifndef MYST_AREAS_H
-#define MYST_AREAS_H
+#include "common/rect.h"
namespace Mohawk {
@@ -137,7 +139,7 @@ public:
protected:
uint16 _var7;
uint16 _numSubResources;
- Common::Array<MystResource*> _subResources;
+ Common::Array<MystResource *> _subResources;
};
class MystResourceType8 : public MystResourceType7 {
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
new file mode 100644
index 0000000000..151390580f
--- /dev/null
+++ b/engines/mohawk/myst_graphics.cpp
@@ -0,0 +1,493 @@
+/* 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.
+ *
+ */
+
+#include "mohawk/myst.h"
+#include "mohawk/myst_graphics.h"
+#include "mohawk/resource.h"
+
+#include "common/substream.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "engines/util.h"
+#include "graphics/jpeg.h"
+#include "graphics/pict.h"
+
+namespace Mohawk {
+
+MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
+ _bmpDecoder = new MystBitmap();
+
+ _viewport = Common::Rect(544, 332);
+
+ // The original version of Myst could run in 8bpp color too.
+ // However, it dithered videos to 8bpp and they looked considerably
+ // worse (than they already did :P). So we're not even going to
+ // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
+ initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
+
+ _pixelFormat = _vm->_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1)
+ error("Myst requires greater than 256 colors to run");
+
+ if (_vm->getFeatures() & GF_ME) {
+ _jpegDecoder = new Graphics::JPEG();
+ _pictDecoder = new Graphics::PictDecoder(_pixelFormat);
+ } else {
+ _jpegDecoder = NULL;
+ _pictDecoder = NULL;
+ }
+
+ _pictureFile.entries = NULL;
+
+ // Initialize our buffer
+ _backBuffer = new Graphics::Surface();
+ _backBuffer->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat);
+
+ _nextAllowedDrawTime = _vm->_system->getMillis();
+ _enableDrawingTimeSimulation = 0;
+}
+
+MystGraphics::~MystGraphics() {
+ delete _bmpDecoder;
+ delete _jpegDecoder;
+ delete _pictDecoder;
+ delete[] _pictureFile.entries;
+
+ _backBuffer->free();
+ delete _backBuffer;
+}
+
+static const char *s_picFileNames[] = {
+ "CHpics",
+ "",
+ "",
+ "DUpics",
+ "INpics",
+ "",
+ "MEpics",
+ "MYpics",
+ "SEpics",
+ "",
+ "",
+ "STpics"
+};
+
+void MystGraphics::loadExternalPictureFile(uint16 stack) {
+ if (_vm->getPlatform() != Common::kPlatformMacintosh)
+ return;
+
+ if (_pictureFile.picFile.isOpen())
+ _pictureFile.picFile.close();
+ delete[] _pictureFile.entries;
+
+ if (!scumm_stricmp(s_picFileNames[stack], ""))
+ return;
+
+ if (!_pictureFile.picFile.open(s_picFileNames[stack]))
+ error ("Could not open external picture file \'%s\'", s_picFileNames[stack]);
+
+ _pictureFile.pictureCount = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries = new PictureFile::PictureEntry[_pictureFile.pictureCount];
+
+ for (uint32 i = 0; i < _pictureFile.pictureCount; i++) {
+ _pictureFile.entries[i].offset = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries[i].size = _pictureFile.picFile.readUint32BE();
+ _pictureFile.entries[i].id = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].type = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].width = _pictureFile.picFile.readUint16BE();
+ _pictureFile.entries[i].height = _pictureFile.picFile.readUint16BE();
+ }
+}
+
+MohawkSurface *MystGraphics::decodeImage(uint16 id) {
+ MohawkSurface *mhkSurface = 0;
+
+ // Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images,
+ // though there are a few weird ones that use that format. For further nonsense with images,
+ // the Macintosh version stores images in external "picture files." We check them before
+ // going to check for a PICT resource.
+ if (_vm->getFeatures() & GF_ME && _vm->getPlatform() == Common::kPlatformMacintosh && _pictureFile.picFile.isOpen()) {
+ for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
+ if (_pictureFile.entries[i].id == id) {
+ if (_pictureFile.entries[i].type == 0) {
+ Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
+
+ if (!_jpegDecoder->read(stream))
+ error("Could not decode Myst ME Mac JPEG");
+
+ mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
+ delete stream;
+ } else if (_pictureFile.entries[i].type == 1) {
+ mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
+ } else
+ error ("Unknown Picture File type %d", _pictureFile.entries[i].type);
+ break;
+ }
+ }
+
+ // We're not using the external Mac files, so it's time to delve into the main Mohawk
+ // archives. However, we still don't know if it's a PICT or WDIB resource. If it's Myst
+ // ME it's most likely a PICT, and if it's original it's definitely a WDIB. However,
+ // Myst ME throws us another curve ball in that PICT resources can contain WDIB's instead
+ // of PICT's.
+ if (!mhkSurface) {
+ bool isPict = false;
+ Common::SeekableReadStream *dataStream = NULL;
+
+ if (_vm->getFeatures() & GF_ME && _vm->hasResource(ID_PICT, id)) {
+ // The PICT resource exists. However, it could still contain a MystBitmap
+ // instead of a PICT image...
+ dataStream = _vm->getResource(ID_PICT, id);
+ } else // No PICT, so the WDIB must exist. Let's go grab it.
+ dataStream = _vm->getResource(ID_WDIB, id);
+
+ if (_vm->getFeatures() & GF_ME) {
+ // Here we detect whether it's really a PICT or a WDIB. Since a MystBitmap
+ // would be compressed, there's no way to detect for the BM without a hack.
+ // So, we search for the PICT version opcode for detection.
+ dataStream->seek(512 + 10); // 512 byte pict header
+ isPict = (dataStream->readUint32BE() == 0x001102FF);
+ dataStream->seek(0);
+ }
+
+ if (isPict)
+ mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(dataStream));
+ else {
+ mhkSurface = _bmpDecoder->decodeImage(dataStream);
+ mhkSurface->convertToTrueColor();
+ }
+ }
+
+ assert(mhkSurface);
+ return mhkSurface;
+}
+
+void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Make sure the image is bottom aligned in the dest rect
+ dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
+
+ // Convert from bitmap coordinates to surface coordinates
+ uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
+
+ // Do not draw the top pixels if the image is too tall
+ if (dest.height() > _viewport.height())
+ top += dest.height() - _viewport.height();
+
+ // Clip the destination rect to the screen
+ if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
+ dest.debugPrint(4, "Clipping destination rect to the screen");
+ dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
+ dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
+
+ uint16 width = MIN<int>(surface->w, dest.width());
+ uint16 height = MIN<int>(surface->h, dest.height());
+
+ // Clamp Width and Height to within src surface dimensions
+ if (src.left + width > surface->w)
+ width = surface->w - src.left;
+ if (src.top + height > surface->h)
+ height = surface->h - src.top;
+
+ debug(3, "MystGraphics::copyImageSectionToScreen()");
+ debug(3, "\tImage: %d", image);
+ debug(3, "\tsrc.left: %d", src.left);
+ debug(3, "\tsrc.top: %d", src.top);
+ debug(3, "\tdest.left: %d", dest.left);
+ debug(3, "\tdest.top: %d", dest.top);
+ debug(3, "\twidth: %d", width);
+ debug(3, "\theight: %d", height);
+
+ simulatePreviousDrawDelay(dest);
+
+ _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
+}
+
+void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Make sure the image is bottom aligned in the dest rect
+ dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
+
+ // Convert from bitmap coordinates to surface coordinates
+ uint16 top = surface->h - (src.top + MIN<int>(surface->h, dest.height()));
+
+ // Do not draw the top pixels if the image is too tall
+ if (dest.height() > _viewport.height()) {
+ top += dest.height() - _viewport.height();
+ }
+
+ // Clip the destination rect to the screen
+ if (dest.right > _vm->_system->getWidth() || dest.bottom > _vm->_system->getHeight())
+ dest.debugPrint(4, "Clipping destination rect to the screen");
+ dest.right = CLIP<int>(dest.right, 0, _vm->_system->getWidth());
+ dest.bottom = CLIP<int>(dest.bottom, 0, _vm->_system->getHeight());
+
+ uint16 width = MIN<int>(surface->w, dest.width());
+ uint16 height = MIN<int>(surface->h, dest.height());
+
+ // Clamp Width and Height to within src surface dimensions
+ if (src.left + width > surface->w)
+ width = surface->w - src.left;
+ if (src.top + height > surface->h)
+ height = surface->h - src.top;
+
+ debug(3, "MystGraphics::copyImageSectionToBackBuffer()");
+ debug(3, "\tImage: %d", image);
+ debug(3, "\tsrc.left: %d", src.left);
+ debug(3, "\tsrc.top: %d", src.top);
+ debug(3, "\tdest.left: %d", dest.left);
+ debug(3, "\tdest.top: %d", dest.top);
+ debug(3, "\twidth: %d", width);
+ debug(3, "\theight: %d", height);
+
+ for (uint16 i = 0; i < height; i++)
+ memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
+}
+
+void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
+ copyImageSectionToScreen(image, Common::Rect(544, 333), dest);
+}
+
+void MystGraphics::copyImageToBackBuffer(uint16 image, Common::Rect dest) {
+ copyImageSectionToBackBuffer(image, Common::Rect(544, 333), dest);
+}
+
+void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
+ r.clip(_viewport);
+
+ simulatePreviousDrawDelay(r);
+
+ _vm->_system->copyRectToScreen((byte *)_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
+}
+
+void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay) {
+
+ // Do not artificially delay during transitions
+ int oldEnableDrawingTimeSimulation = _enableDrawingTimeSimulation;
+ _enableDrawingTimeSimulation = 0;
+
+ switch (type) {
+ case 0: {
+ debugC(kDebugScript, "Left to Right");
+
+ uint16 step = (rect.right - rect.left) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.left = rect.left + step * i;
+ area.right = area.left + step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.right < rect.right) {
+ area.left = area.right;
+ area.right = rect.right;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 1: {
+ debugC(kDebugScript, "Right to Left");
+
+ uint16 step = (rect.right - rect.left) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.right = rect.right - step * i;
+ area.left = area.right - step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.left > rect.left) {
+ area.right = area.left;
+ area.left = rect.left;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 5: {
+ debugC(kDebugScript, "Top to Bottom");
+
+ uint16 step = (rect.bottom - rect.top) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.top = rect.top + step * i;
+ area.bottom = area.top + step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.bottom < rect.bottom) {
+ area.top = area.bottom;
+ area.bottom = rect.bottom;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ case 6: {
+ debugC(kDebugScript, "Bottom to Top");
+
+ uint16 step = (rect.bottom - rect.top) / steps;
+ Common::Rect area = rect;
+ for (uint i = 0; i < steps; i++) {
+ area.bottom = rect.bottom - step * i;
+ area.top = area.bottom - step;
+
+ _vm->_system->delayMillis(delay);
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ if (area.top > rect.top) {
+ area.bottom = area.top;
+ area.top = rect.top;
+
+ copyBackBufferToScreen(area);
+ _vm->_system->updateScreen();
+ }
+ }
+ break;
+ default:
+ warning("Unknown Update Direction");
+
+ //TODO: Replace minimal implementation
+ copyBackBufferToScreen(rect);
+ _vm->_system->updateScreen();
+ break;
+ }
+
+ _enableDrawingTimeSimulation = oldEnableDrawingTimeSimulation;
+}
+
+void MystGraphics::drawRect(Common::Rect rect, RectState state) {
+ rect.clip(_viewport);
+
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
+ return;
+
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ if (state == kRectEnabled)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ else if (state == kRectUnreachable)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
+ else
+ screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color) {
+ _backBuffer->drawLine(p1.x, p1.y, p2.x, p2.y, color);
+}
+
+void MystGraphics::enableDrawingTimeSimulation(bool enable) {
+ if (enable)
+ _enableDrawingTimeSimulation++;
+ else
+ _enableDrawingTimeSimulation--;
+
+ if (_enableDrawingTimeSimulation < 0)
+ _enableDrawingTimeSimulation = 0;
+}
+
+void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
+ uint32 time = 0;
+
+ if (_enableDrawingTimeSimulation) {
+ time = _vm->_system->getMillis();
+
+ // Do not draw anything new too quickly after the previous draw call
+ // so that images stay at least a little while on screen
+ // This is enabled only for scripted draw calls
+ if (time < _nextAllowedDrawTime)
+ _vm->_system->delayMillis(_nextAllowedDrawTime - time);
+ }
+
+ // Next draw call allowed at DELAY + AERA * COEFF milliseconds from now
+ time = _vm->_system->getMillis();
+ _nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
+}
+
+void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ for (uint16 y = 0; y < _viewport.height(); y++)
+ for (uint16 x = 0; x < _viewport.width(); x++) {
+ uint32 color;
+ uint8 r, g, b;
+
+ if (_pixelFormat.bytesPerPixel == 2)
+ color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
+ else
+ color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+
+ _pixelFormat.colorToRGB(color, r, g, b);
+
+ r = CLIP<int16>((int16)r - saturation, 0, 255);
+ g = CLIP<int16>((int16)g - saturation, 0, 255);
+ b = CLIP<int16>((int16)b - saturation, 0, 255);
+
+ color = _pixelFormat.RGBToColor(r, g, b);
+
+ if (_pixelFormat.bytesPerPixel == 2) {
+ uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
+ *dst = color;
+ } else {
+ uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
+ *dst = color;
+ }
+ }
+
+ _vm->_system->unlockScreen();
+ _vm->_system->updateScreen();
+}
+
+void MystGraphics::fadeToBlack() {
+ for (int16 i = 0; i < 256; i += 32) {
+ copyBackBufferToScreenWithSaturation(i);
+ }
+}
+
+void MystGraphics::fadeFromBlack() {
+ for (int16 i = 256; i >= 0; i -= 32) {
+ copyBackBufferToScreenWithSaturation(i);
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
new file mode 100644
index 0000000000..e2b02db5fc
--- /dev/null
+++ b/engines/mohawk/myst_graphics.h
@@ -0,0 +1,102 @@
+/* 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.
+ *
+ */
+
+#ifndef MOHAWK_MYST_GRAPHICS_H
+#define MOHAWK_MYST_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+#include "common/file.h"
+
+namespace Graphics {
+class JPEG;
+class PictDecoder;
+}
+
+namespace Mohawk {
+
+class MystBitmap;
+class MohawkEngine_Myst;
+
+enum RectState {
+ kRectEnabled,
+ kRectDisabled,
+ kRectUnreachable
+};
+
+class MystGraphics : public GraphicsManager {
+public:
+ MystGraphics(MohawkEngine_Myst*);
+ ~MystGraphics();
+
+ void loadExternalPictureFile(uint16 stack);
+ void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
+ void copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest);
+ void copyImageToScreen(uint16 image, Common::Rect dest);
+ void copyImageToBackBuffer(uint16 image, Common::Rect dest);
+ void copyBackBufferToScreen(Common::Rect r);
+ void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
+ void drawRect(Common::Rect rect, RectState state);
+ void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
+ void enableDrawingTimeSimulation(bool enable);
+ void fadeToBlack();
+ void fadeFromBlack();
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+ void simulatePreviousDrawDelay(const Common::Rect &dest);
+ void copyBackBufferToScreenWithSaturation(int16 saturation);
+
+private:
+ MohawkEngine_Myst *_vm;
+ MystBitmap *_bmpDecoder;
+ Graphics::PictDecoder *_pictDecoder;
+ Graphics::JPEG *_jpegDecoder;
+
+ struct PictureFile {
+ uint32 pictureCount;
+ struct PictureEntry {
+ uint32 offset;
+ uint32 size;
+ uint16 id;
+ uint16 type;
+ uint16 width;
+ uint16 height;
+ } *entries;
+
+ Common::File picFile;
+ } _pictureFile;
+
+ Graphics::Surface *_backBuffer;
+ Graphics::PixelFormat _pixelFormat;
+ Common::Rect _viewport;
+
+ int _enableDrawingTimeSimulation;
+ uint32 _nextAllowedDrawTime;
+ static const uint _constantDrawDelay = 10; // ms
+ static const uint _proportionalDrawDelay = 500; // pixels per ms
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index ca8e985491..b9353312c7 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 18f5b27a6d..ccb76e0dc8 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -143,7 +143,7 @@ protected:
const char *desc;
};
- Common::Array<MystOpcode*> _opcodes;
+ Common::Array<MystOpcode *> _opcodes;
MystResource *_invokingResource;
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 9ca47cc92a..069281f5dc 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index ad593e3542..192e55d5e3 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/credits.h"
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index fbad7dc384..29a12571fd 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_stacks/demo.h"
#include "common/system.h"
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index 7d3179fa24..0af386f51f 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -21,8 +21,8 @@
*/
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 12d9dc7e2f..79de03308c 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index b67b333a85..c1ddc74c82 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -2138,7 +2138,7 @@ void Myst::rocketSliderMove() {
}
uint16 Myst::rocketSliderGetSound(uint16 pos) {
- return (uint16)(9530 + (pos - 216) * 35.0 * 0.01639344262295082);
+ return (uint16)(9530 + (pos - 216) * 35.0 / 61.0);
}
void Myst::rocketCheckSolution() {
@@ -2978,15 +2978,17 @@ void Myst::clockReset() {
}
void Myst::clockResetWeight() {
- // Set video bounds, weight going up
+ _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
+
if (!(_vm->getFeatures() & GF_ME)) {
- _clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
+ // Set video bounds, weight going up
_vm->_video->setVideoBounds(_clockWeightVideo,
Audio::Timestamp(0, 2214 * 2 - _clockWeightPosition, 600),
Audio::Timestamp(0, 2214 * 2, 600));
} else {
- //FIXME: Needs QT backwards playing
+ //FIXME: Needs QT backwards playing, for now just display the weight up
warning("Weight going back up not implemented");
+ _vm->_video->drawVideoFrame(_clockWeightVideo, Audio::Timestamp(0, 0, 600));
}
// Reset position
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 31e22bb8c5..0b8dcf897a 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/preview.h"
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index 794793e49c..c0bb400db1 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
#include "mohawk/myst_stacks/slides.h"
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index e0c374a926..ef228e62f3 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -22,8 +22,8 @@
#include "mohawk/cursors.h"
#include "mohawk/myst.h"
-#include "mohawk/graphics.h"
#include "mohawk/myst_areas.h"
+#include "mohawk/myst_graphics.h"
#include "mohawk/myst_state.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -623,7 +623,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
uint16 selectionPos = position * 1500 / 243;
VideoHandle handleMovie = _hologramSelection->playMovie();
- _vm->_video->setVideoBounds(handleMovie, Audio::Timestamp(0, selectionPos, 600), Audio::Timestamp(0, selectionPos, 600));
+ _vm->_video->drawVideoFrame(handleMovie, Audio::Timestamp(0, selectionPos, 600));
_hologramDisplayPos = position * 1450 / 243 + 350;
@@ -631,7 +631,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
if (_hologramTurnedOn) {
_hologramDisplay->setBlocking(false);
VideoHandle displayMovie = _hologramDisplay->playMovie();
- _vm->_video->setVideoBounds(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600), Audio::Timestamp(0, _hologramDisplayPos, 600));
+ _vm->_video->drawVideoFrame(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600));
}
}
}
@@ -655,7 +655,7 @@ void Stoneship::o_compassButton(uint16 op, uint16 var, uint16 argc, uint16 *argv
_state.generatorPowerAvailable = 2;
_state.lightState = 0;
_state.generatorDepletionTime = 0;
- _state.generatorDepletionTime = 0;
+ _state.generatorDuration = 0;
_batteryDepleting = false;
}
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 3e2fa4f979..38b38d2c56 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -27,11 +27,11 @@
#include "common/system.h"
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/installer_archive.h"
#include "mohawk/resource.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/riven_saveload.h"
#include "mohawk/dialogs.h"
#include "mohawk/sound.h"
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 9e1365f8da..8dfc74ebf0 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -21,9 +21,9 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/riven_external.h b/engines/mohawk/riven_external.h
index 5f5d0cb0b2..9f076325a2 100644
--- a/engines/mohawk/riven_external.h
+++ b/engines/mohawk/riven_external.h
@@ -53,7 +53,7 @@ private:
ExternalCmd proc;
};
- Common::Array<RivenExternalCmd*> _externalCommands;
+ Common::Array<RivenExternalCmd *> _externalCommands;
void setupCommands();
// Supplementary Functions
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
new file mode 100644
index 0000000000..9415e51412
--- /dev/null
+++ b/engines/mohawk/riven_graphics.cpp
@@ -0,0 +1,445 @@
+/* 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.
+ *
+ */
+
+#include "mohawk/resource.h"
+#include "mohawk/riven.h"
+#include "mohawk/riven_graphics.h"
+
+#include "common/system.h"
+#include "engines/util.h"
+
+namespace Mohawk {
+
+RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm) {
+ _bitmapDecoder = new MohawkBitmap();
+
+ // Give me the best you've got!
+ initGraphics(608, 436, true, NULL);
+ _pixelFormat = _vm->_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1)
+ error("Riven requires greater than 256 colors to run");
+
+ // The actual game graphics only take up the first 392 rows. The inventory
+ // occupies the rest of the screen and we don't use the buffer to hold that.
+ _mainScreen = new Graphics::Surface();
+ _mainScreen->create(608, 392, _pixelFormat);
+
+ _updatesEnabled = true;
+ _scheduledTransition = -1; // no transition
+ _dirtyScreen = false;
+ _inventoryDrawn = false;
+
+ _creditsImage = 302;
+ _creditsPos = 0;
+}
+
+RivenGraphics::~RivenGraphics() {
+ _mainScreen->free();
+ delete _mainScreen;
+ delete _bitmapDecoder;
+}
+
+MohawkSurface *RivenGraphics::decodeImage(uint16 id) {
+ MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getResource(ID_TBMP, id));
+ surface->convertToTrueColor();
+ return surface;
+}
+
+void RivenGraphics::copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom) {
+ Graphics::Surface *surface = findImage(image)->getSurface();
+
+ // Clip the width to fit on the screen. Fixes some images.
+ if (left + surface->w > 608)
+ surface->w = 608 - left;
+
+ for (uint16 i = 0; i < surface->h; i++)
+ memcpy(_mainScreen->getBasePtr(left, i + top), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
+
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::drawPLST(uint16 x) {
+ Common::SeekableReadStream* plst = _vm->getResource(ID_PLST, _vm->getCurCard());
+ uint16 recordCount = plst->readUint16BE();
+
+ for (uint16 i = 0; i < recordCount; i++) {
+ uint16 index = plst->readUint16BE();
+ uint16 id = plst->readUint16BE();
+ uint16 left = plst->readUint16BE();
+ uint16 top = plst->readUint16BE();
+ uint16 right = plst->readUint16BE();
+ uint16 bottom = plst->readUint16BE();
+
+ // We are also checking here to make sure we haven't drawn the image yet on screen.
+ // This fixes problems with drawing PLST 1 twice and some other images twice. PLST
+ // 1 is sometimes not called by the scripts, so some cards don't appear if we don't
+ // draw PLST 1 each time. This "hack" is here to catch any PLST attempting to draw
+ // twice. There should never be a problem with doing it this way.
+ if (index == x && !(Common::find(_activatedPLSTs.begin(), _activatedPLSTs.end(), x) != _activatedPLSTs.end())) {
+ debug(0, "Drawing image %d", id);
+ copyImageToScreen(id, left, top, right, bottom);
+ _activatedPLSTs.push_back(x);
+ break;
+ }
+ }
+
+ delete plst;
+}
+
+void RivenGraphics::updateScreen(Common::Rect updateRect) {
+ if (_updatesEnabled) {
+ _vm->runUpdateScreenScript();
+
+ if (_dirtyScreen) {
+ _activatedPLSTs.clear();
+
+ // Copy to screen if there's no transition. Otherwise transition. ;)
+ if (_scheduledTransition < 0)
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height());
+ else
+ runScheduledTransition();
+
+ // Finally, update the screen.
+ _vm->_system->updateScreen();
+ _dirtyScreen = false;
+ }
+ }
+}
+
+void RivenGraphics::scheduleWaterEffect(uint16 sfxeID) {
+ Common::SeekableReadStream *sfxeStream = _vm->getResource(ID_SFXE, sfxeID);
+
+ if (sfxeStream->readUint16BE() != 'SL')
+ error ("Unknown sfxe tag");
+
+ // Read in header info
+ SFXERecord sfxeRecord;
+ sfxeRecord.frameCount = sfxeStream->readUint16BE();
+ uint32 offsetTablePosition = sfxeStream->readUint32BE();
+ sfxeRecord.rect.left = sfxeStream->readUint16BE();
+ sfxeRecord.rect.top = sfxeStream->readUint16BE();
+ sfxeRecord.rect.right = sfxeStream->readUint16BE();
+ sfxeRecord.rect.bottom = sfxeStream->readUint16BE();
+ sfxeRecord.speed = sfxeStream->readUint16BE();
+ // Skip the rest of the fields...
+
+ // Read in offsets
+ sfxeStream->seek(offsetTablePosition);
+ uint32 *frameOffsets = new uint32[sfxeRecord.frameCount];
+ for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
+ frameOffsets[i] = sfxeStream->readUint32BE();
+ sfxeStream->seek(frameOffsets[0]);
+
+ // Read in the scripts
+ for (uint16 i = 0; i < sfxeRecord.frameCount; i++)
+ sfxeRecord.frameScripts.push_back(sfxeStream->readStream((i == sfxeRecord.frameCount - 1) ? sfxeStream->size() - frameOffsets[i] : frameOffsets[i + 1] - frameOffsets[i]));
+
+ // Set it to the first frame
+ sfxeRecord.curFrame = 0;
+ sfxeRecord.lastFrameTime = 0;
+
+ delete[] frameOffsets;
+ delete sfxeStream;
+ _waterEffects.push_back(sfxeRecord);
+}
+
+void RivenGraphics::clearWaterEffects() {
+ _waterEffects.clear();
+}
+
+bool RivenGraphics::runScheduledWaterEffects() {
+ // Don't run the effect if it's disabled
+ if (_vm->_vars["waterenabled"] == 0)
+ return false;
+
+ Graphics::Surface *screen = NULL;
+
+ for (uint16 i = 0; i < _waterEffects.size(); i++) {
+ if (_vm->_system->getMillis() > _waterEffects[i].lastFrameTime + 1000 / _waterEffects[i].speed) {
+ // Lock the screen!
+ if (!screen)
+ screen = _vm->_system->lockScreen();
+
+ // Make sure the script is at the starting point
+ Common::SeekableReadStream *script = _waterEffects[i].frameScripts[_waterEffects[i].curFrame];
+ if (script->pos() != 0)
+ script->seek(0);
+
+ // Run script
+ uint16 curRow = 0;
+ for (uint16 op = script->readUint16BE(); op != 4; op = script->readUint16BE()) {
+ if (op == 1) { // Increment Row
+ curRow++;
+ } else if (op == 3) { // Copy Pixels
+ uint16 dstLeft = script->readUint16BE();
+ uint16 srcLeft = script->readUint16BE();
+ uint16 srcTop = script->readUint16BE();
+ uint16 rowWidth = script->readUint16BE();
+ memcpy ((byte *)screen->getBasePtr(dstLeft, curRow + _waterEffects[i].rect.top), (byte *)_mainScreen->getBasePtr(srcLeft, srcTop), rowWidth * _pixelFormat.bytesPerPixel);
+ } else if (op != 4) { // End of Script
+ error ("Unknown SFXE opcode %d", op);
+ }
+ }
+
+ // Increment frame
+ _waterEffects[i].curFrame++;
+ if (_waterEffects[i].curFrame == _waterEffects[i].frameCount)
+ _waterEffects[i].curFrame = 0;
+
+ // Set the new time
+ _waterEffects[i].lastFrameTime = _vm->_system->getMillis();
+ }
+ }
+
+ // Unlock the screen if it has been locked and return true to update the screen
+ if (screen) {
+ _vm->_system->unlockScreen();
+ return true;
+ }
+
+ return false;
+}
+
+void RivenGraphics::scheduleTransition(uint16 id, Common::Rect rect) {
+ _scheduledTransition = id;
+ _transitionRect = rect;
+}
+
+void RivenGraphics::runScheduledTransition() {
+ if (_scheduledTransition < 0) // No transition is scheduled
+ return;
+
+ // TODO: There's a lot to be done here...
+
+ // Note: Transitions 0-11 are actual transitions, but none are used in-game.
+ // There's no point in implementing them if they're not used. These extra
+ // transitions were found by hacking scripts.
+
+ switch (_scheduledTransition) {
+ case 0: // Swipe Left
+ case 1: // Swipe Right
+ case 2: // Swipe Up
+ case 3: // Swipe Down
+ case 12: // Pan Left
+ case 13: // Pan Right
+ case 14: // Pan Up
+ case 15: // Pan Down
+ case 16: // Dissolve
+ case 17: // Dissolve (tspit CARD 155)
+ break;
+ default:
+ if (_scheduledTransition >= 4 && _scheduledTransition <= 11)
+ error("Found unused transition %d", _scheduledTransition);
+ else
+ error("Found unknown transition %d", _scheduledTransition);
+ }
+
+ // For now, just copy the image to screen without doing any transition.
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->updateScreen();
+
+ _scheduledTransition = -1; // Clear scheduled transition
+}
+
+void RivenGraphics::clearMainScreen() {
+ _mainScreen->fillRect(Common::Rect(0, 0, 608, 392), _pixelFormat.RGBToColor(0, 0, 0));
+}
+
+void RivenGraphics::fadeToBlack() {
+ // The transition speed is forced to best here
+ setTransitionSpeed(kRivenTransitionSpeedBest);
+ scheduleTransition(16);
+ clearMainScreen();
+ runScheduledTransition();
+}
+
+void RivenGraphics::showInventory() {
+ // Don't redraw the inventory
+ if (_inventoryDrawn)
+ return;
+
+ // Clear the inventory area
+ clearInventoryArea();
+
+ // Draw the demo's exit button
+ if (_vm->getFeatures() & GF_DEMO) {
+ // extras.mhk tBMP 101 contains "EXIT" instead of Atrus' journal in the demo!
+ // The demo's extras.mhk contains all the other inventory/marble/credits image
+ // but has hacked tBMP 101 with "EXIT". *sigh*
+ drawInventoryImage(101, g_demoExitRect);
+ } else {
+ // We don't want to show the inventory on setup screens or in other journals.
+ if (_vm->getCurStack() == aspit)
+ return;
+
+ // There are three books and three vars. We have three different
+ // combinations. At the start you have just Atrus' journal. Later,
+ // you get Catherine's journal and the trap book. Near the end,
+ // you lose the trap book and have just the two journals.
+
+ bool hasCathBook = _vm->_vars["acathbook"] != 0;
+ bool hasTrapBook = _vm->_vars["atrapbook"] != 0;
+
+ if (!hasCathBook) {
+ drawInventoryImage(101, g_atrusJournalRect1);
+ } else if (!hasTrapBook) {
+ drawInventoryImage(101, g_atrusJournalRect2);
+ drawInventoryImage(102, g_cathJournalRect2);
+ } else {
+ drawInventoryImage(101, g_atrusJournalRect3);
+ drawInventoryImage(102, g_cathJournalRect3);
+ drawInventoryImage(100, g_trapBookRect3);
+ }
+ }
+
+ _vm->_system->updateScreen();
+ _inventoryDrawn = true;
+}
+
+void RivenGraphics::hideInventory() {
+ // Don't hide the inventory twice
+ if (!_inventoryDrawn)
+ return;
+
+ // Clear the area
+ clearInventoryArea();
+
+ _inventoryDrawn = false;
+}
+
+void RivenGraphics::clearInventoryArea() {
+ // Clear the inventory area
+ static const Common::Rect inventoryRect = Common::Rect(0, 392, 608, 436);
+
+ // Lock the screen
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ // Fill the inventory area with black
+ screen->fillRect(inventoryRect, _pixelFormat.RGBToColor(0, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void RivenGraphics::drawInventoryImage(uint16 id, const Common::Rect *rect) {
+ MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
+ mhkSurface->convertToTrueColor();
+ Graphics::Surface *surface = mhkSurface->getSurface();
+
+ _vm->_system->copyRectToScreen((byte *)surface->pixels, surface->pitch, rect->left, rect->top, surface->w, surface->h);
+
+ delete mhkSurface;
+}
+
+void RivenGraphics::drawRect(Common::Rect rect, bool active) {
+ // Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+
+ if (active)
+ screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ else
+ screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+
+ _vm->_system->unlockScreen();
+}
+
+void RivenGraphics::drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect) {
+ // Draw tBMP id from srcRect to dstRect
+ Graphics::Surface *surface = findImage(id)->getSurface();
+
+ assert(srcRect.width() == dstRect.width() && srcRect.height() == dstRect.height());
+
+ for (uint16 i = 0; i < srcRect.height(); i++)
+ memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(srcRect.left, i + srcRect.top), srcRect.width() * surface->format.bytesPerPixel);
+
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) {
+ MohawkSurface *mhkSurface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, id));
+ mhkSurface->convertToTrueColor();
+ Graphics::Surface *surface = mhkSurface->getSurface();
+
+ assert(dstRect.width() == surface->w);
+
+ for (uint16 i = 0; i < surface->h; i++)
+ memcpy(_mainScreen->getBasePtr(dstRect.left, i + dstRect.top), surface->getBasePtr(0, i), surface->pitch);
+
+ delete mhkSurface;
+ _dirtyScreen = true;
+}
+
+void RivenGraphics::beginCredits() {
+ // Clear the old cache
+ clearCache();
+
+ // Now cache all the credits images
+ for (uint16 i = 302; i <= 320; i++) {
+ MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, i));
+ surface->convertToTrueColor();
+ addImageToCache(i, surface);
+ }
+
+ // And clear our screen too
+ clearMainScreen();
+}
+
+void RivenGraphics::updateCredits() {
+ if ((_creditsImage == 303 || _creditsImage == 304) && _creditsPos == 0)
+ fadeToBlack();
+
+ if (_creditsImage < 304) {
+ // For the first two credit images, they are faded from black to the image and then out again
+ scheduleTransition(16);
+
+ Graphics::Surface *frame = findImage(_creditsImage++)->getSurface();
+
+ for (int y = 0; y < frame->h; y++)
+ memcpy(_mainScreen->getBasePtr(124, y), frame->getBasePtr(0, y), frame->pitch);
+
+ runScheduledTransition();
+ } else {
+ // Otheriwse, we're scrolling
+ // Move the screen up one row
+ memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
+
+ // Only update as long as we're not before the last frame
+ // Otherwise, we're just moving up a row (which we already did)
+ if (_creditsImage <= 320) {
+ // Copy the next row to the bottom of the screen
+ Graphics::Surface *frame = findImage(_creditsImage)->getSurface();
+ memcpy(_mainScreen->getBasePtr(124, _mainScreen->h - 1), frame->getBasePtr(0, _creditsPos), frame->pitch);
+ _creditsPos++;
+
+ if (_creditsPos == _mainScreen->h) {
+ _creditsImage++;
+ _creditsPos = 0;
+ }
+ }
+
+ // Now flush the new screen
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->updateScreen();
+ }
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_graphics.h b/engines/mohawk/riven_graphics.h
new file mode 100644
index 0000000000..48dda28afd
--- /dev/null
+++ b/engines/mohawk/riven_graphics.h
@@ -0,0 +1,110 @@
+/* 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.
+ *
+ */
+
+#ifndef MOHAWK_RIVEN_GRAPHICS_H
+#define MOHAWK_RIVEN_GRAPHICS_H
+
+#include "mohawk/graphics.h"
+
+namespace Mohawk {
+
+class MohawkEngine_Riven;
+
+class RivenGraphics : public GraphicsManager {
+public:
+ RivenGraphics(MohawkEngine_Riven *vm);
+ ~RivenGraphics();
+
+ void copyImageToScreen(uint16, uint32, uint32, uint32, uint32);
+ void updateScreen(Common::Rect updateRect = Common::Rect(0, 0, 608, 392));
+ bool _updatesEnabled;
+ Common::Array<uint16> _activatedPLSTs;
+ void drawPLST(uint16 x);
+ void drawRect(Common::Rect rect, bool active);
+ void drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect);
+ void drawExtrasImage(uint16 id, Common::Rect dstRect);
+
+ // Water Effect
+ void scheduleWaterEffect(uint16);
+ void clearWaterEffects();
+ bool runScheduledWaterEffects();
+
+ // Transitions
+ void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
+ void runScheduledTransition();
+ void fadeToBlack();
+ void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; }
+
+ // Inventory
+ void showInventory();
+ void hideInventory();
+
+ // Credits
+ void beginCredits();
+ void updateCredits();
+ uint getCurCreditsImage() { return _creditsImage; }
+
+protected:
+ MohawkSurface *decodeImage(uint16 id);
+ MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
+
+private:
+ MohawkEngine_Riven *_vm;
+ MohawkBitmap *_bitmapDecoder;
+
+ // Water Effects
+ struct SFXERecord {
+ // Record values
+ uint16 frameCount;
+ Common::Rect rect;
+ uint16 speed;
+ Common::Array<Common::SeekableReadStream *> frameScripts;
+
+ // Cur frame
+ uint16 curFrame;
+ uint32 lastFrameTime;
+ };
+ Common::Array<SFXERecord> _waterEffects;
+
+ // Transitions
+ int16 _scheduledTransition;
+ Common::Rect _transitionRect;
+ uint32 _transitionSpeed;
+
+ // Inventory
+ void clearInventoryArea();
+ void drawInventoryImage(uint16 id, const Common::Rect *rect);
+ bool _inventoryDrawn;
+
+ // Screen Related
+ Graphics::Surface *_mainScreen;
+ bool _dirtyScreen;
+ Graphics::PixelFormat _pixelFormat;
+ void clearMainScreen();
+
+ // Credits
+ uint _creditsImage, _creditsPos;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 6e3e9a34dc..352a018990 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -21,9 +21,9 @@
*/
#include "mohawk/cursors.h"
-#include "mohawk/graphics.h"
#include "mohawk/riven.h"
#include "mohawk/riven_external.h"
+#include "mohawk/riven_graphics.h"
#include "mohawk/riven_scripts.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index 2932ba5939..6df4a2e523 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -27,8 +27,6 @@
#include "common/ptr.h"
#include "common/textconsole.h"
-class MohawkEngine_Riven;
-
#define DECLARE_OPCODE(x) void x(uint16 op, uint16 argc, uint16 *argv)
namespace Mohawk {
@@ -50,6 +48,7 @@ enum {
kStoredOpcodeScript // This is ScummVM-only to denote the script from a storeMovieOpcode() call
};
+class MohawkEngine_Riven;
class RivenScript;
class RivenScript {
@@ -125,7 +124,7 @@ private:
DECLARE_OPCODE(activateMLST);
};
-typedef Common::Array<RivenScript*> RivenScriptList;
+typedef Common::Array<RivenScript *> RivenScriptList;
class RivenScriptManager {
public:
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index cd8fc8ef80..8d72fa3f72 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -261,7 +261,7 @@ bool VideoManager::updateMovies() {
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);
- _vm->_system->copyRectToScreen((byte*)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
// We've drawn something to the screen, make sure we update it
updateScreen = true;
@@ -529,6 +529,15 @@ void VideoManager::setVideoBounds(VideoHandle handle, Audio::Timestamp start, Au
_videoStreams[handle]->seekToTime(start);
}
+void VideoManager::drawVideoFrame(VideoHandle handle, Audio::Timestamp time) {
+ assert(handle != NULL_VID_HANDLE);
+ _videoStreams[handle].end = Audio::Timestamp(0xffffffff, 1);
+ _videoStreams[handle]->seekToTime(time);
+ updateMovies();
+ delete _videoStreams[handle].video;
+ _videoStreams[handle].clear();
+}
+
void VideoManager::seekToTime(VideoHandle handle, Audio::Timestamp time) {
assert(handle != NULL_VID_HANDLE);
_videoStreams[handle]->seekToTime(time);
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index efa81edfbd..34c287497f 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -104,6 +104,7 @@ public:
uint32 getDuration(VideoHandle videoHandle);
bool endOfVideo(VideoHandle handle);
void setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end);
+ void drawVideoFrame(VideoHandle handle, Audio::Timestamp time);
void seekToTime(VideoHandle handle, Audio::Timestamp time);
void setVideoLooping(VideoHandle handle, bool loop);
void waitUntilMovieEnds(VideoHandle videoHandle);