aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp80
-rw-r--r--devtools/create_kyradat/create_kyradat.h28
-rw-r--r--devtools/create_kyradat/games.cpp37
-rw-r--r--devtools/create_kyradat/tables.cpp159
-rw-r--r--dists/engine-data/kyra.datbin463146 -> 464892 bytes
-rw-r--r--engines/kyra/chargen.cpp6
-rw-r--r--engines/kyra/eob1.cpp42
-rw-r--r--engines/kyra/eob1.h38
-rw-r--r--engines/kyra/eob2.cpp10
-rw-r--r--engines/kyra/eobcommon.cpp68
-rw-r--r--engines/kyra/eobcommon.h40
-rw-r--r--engines/kyra/gui_eob.cpp2
-rw-r--r--engines/kyra/magic_eob.cpp145
-rw-r--r--engines/kyra/resource.h28
-rw-r--r--engines/kyra/scene_eob.cpp4
-rw-r--r--engines/kyra/screen_eob.cpp259
-rw-r--r--engines/kyra/screen_eob.h5
-rw-r--r--engines/kyra/script_eob.cpp38
-rw-r--r--engines/kyra/script_eob.h6
-rw-r--r--engines/kyra/sequences_eob1.cpp937
-rw-r--r--engines/kyra/sequences_eob2.cpp1
-rw-r--r--engines/kyra/sprites_eob.cpp10
-rw-r--r--engines/kyra/staticres_eob.cpp27
-rw-r--r--engines/kyra/text_eob.cpp5
24 files changed, 1778 insertions, 197 deletions
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 8bd5baeb2a..a8531dd470 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -404,9 +404,37 @@ const ExtractFilename extractFilenames[] = {
{ kEobBaseMagicFlightProps, kTypeRawData, false },
{ kEobBaseTurnUndeadEffect, kTypeRawData, false },
{ kEobBaseBurningHandsDest, kTypeRawData, false },
+ { kEobBaseConeOfColdDest1, kTypeRawData, false },
+ { kEobBaseConeOfColdDest2, kTypeRawData, false },
+ { kEobBaseConeOfColdDest3, kTypeRawData, false },
+ { kEobBaseConeOfColdDest4, kTypeRawData, false },
+ { kEobBaseConeOfColdGfxTbl, k3TypeRaw16to8, false },
// EYE OF THE BEHOLDER I
{ kEob1MainMenuStrings, kTypeStringList, true },
+ { kEob1BonusStrings, kTypeStringList, true },
+
+ { kEob1IntroFilesOpening, kTypeStringList, false },
+ { kEob1IntroFilesTower, kTypeStringList, false },
+ { kEob1IntroFilesOrb, kTypeStringList, false },
+ { kEob1IntroFilesWdEntry, kTypeStringList, false },
+ { kEob1IntroFilesKing, kTypeStringList, false },
+ { kEob1IntroFilesHands, kTypeStringList, false },
+ { kEob1IntroFilesWdExit, kTypeStringList, false },
+ { kEob1IntroFilesTunnel, kTypeStringList, false },
+ { kEob1IntroOpeningFrmDelay, k3TypeRaw16to8, false },
+ { kEob1IntroWdEncodeX, kTypeRawData, false },
+ { kEob1IntroWdEncodeY, kTypeRawData, false },
+ { kEob1IntroWdEncodeWH, kTypeRawData, false },
+ { kEob1IntroWdDsX, kLolTypeRaw16, false },
+ { kEob1IntroWdDsY, kTypeRawData, false },
+ { kEob1IntroTvlX1, kTypeRawData, false },
+ { kEob1IntroTvlY1, kTypeRawData, false },
+ { kEob1IntroTvlX2, kTypeRawData, false },
+ { kEob1IntroTvlY2, kTypeRawData, false },
+ { kEob1IntroTvlW, kTypeRawData, false },
+ { kEob1IntroTvlH, kTypeRawData, false },
+
{ kEob1DoorShapeDefs, kTypeRawData, false },
{ kEob1DoorSwitchShapeDefs, kTypeRawData, false },
{ kEob1DoorSwitchCoords, kTypeRawData, false },
@@ -1644,8 +1672,60 @@ const char *getIdString(const int id) {
return "kEobBaseTurnUndeadEffect";
case kEobBaseBurningHandsDest:
return "kEobBaseBurningHandsDest";
+ case kEobBaseConeOfColdDest1:
+ return "kEobBaseConeOfColdDest1";
+ case kEobBaseConeOfColdDest2:
+ return "kEobBaseConeOfColdDest2";
+ case kEobBaseConeOfColdDest3:
+ return "kEobBaseConeOfColdDest3";
+ case kEobBaseConeOfColdDest4:
+ return "kEobBaseConeOfColdDest4";
+ case kEobBaseConeOfColdGfxTbl:
+ return "kEobBaseConeOfColdGfxTbl";
case kEob1MainMenuStrings:
return "kEob1MainMenuStrings";
+ case kEob1BonusStrings:
+ return "kEob1BonusStrings";
+ case kEob1IntroFilesOpening:
+ return "kEob1IntroFilesOpening";
+ case kEob1IntroFilesTower:
+ return "kEob1IntroFilesTower";
+ case kEob1IntroFilesOrb:
+ return "kEob1IntroFilesOrb";
+ case kEob1IntroFilesWdEntry:
+ return "kEob1IntroFilesWdEntry";
+ case kEob1IntroFilesKing:
+ return "kEob1IntroFilesKing";
+ case kEob1IntroFilesHands:
+ return "kEob1IntroFilesHands";
+ case kEob1IntroFilesWdExit:
+ return "kEob1IntroFilesWdExit";
+ case kEob1IntroFilesTunnel:
+ return "kEob1IntroFilesTunnel";
+ case kEob1IntroOpeningFrmDelay:
+ return "kEob1IntroOpeningFrmDelay";
+ case kEob1IntroWdEncodeX:
+ return "kEob1IntroWdEncodeX";
+ case kEob1IntroWdEncodeY:
+ return "kEob1IntroWdEncodeY";
+ case kEob1IntroWdEncodeWH:
+ return "kEob1IntroWdEncodeWH";
+ case kEob1IntroWdDsX:
+ return "kEob1IntroWdDsX";
+ case kEob1IntroWdDsY:
+ return "kEob1IntroWdDsY";
+ case kEob1IntroTvlX1:
+ return "kEob1IntroTvlX1";
+ case kEob1IntroTvlY1:
+ return "kEob1IntroTvlY1";
+ case kEob1IntroTvlX2:
+ return "kEob1IntroTvlX2";
+ case kEob1IntroTvlY2:
+ return "kEob1IntroTvlY2";
+ case kEob1IntroTvlW:
+ return "kEob1IntroTvlW";
+ case kEob1IntroTvlH:
+ return "kEob1IntroTvlH";
case kEob1DoorShapeDefs:
return "kEob1DoorShapeDefs";
case kEob1DoorSwitchCoords:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 7cacbb5122..44fa93a174 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -405,8 +405,36 @@ enum kExtractID {
kEobBaseMagicFlightProps,
kEobBaseTurnUndeadEffect,
kEobBaseBurningHandsDest,
+ kEobBaseConeOfColdDest1,
+ kEobBaseConeOfColdDest2,
+ kEobBaseConeOfColdDest3,
+ kEobBaseConeOfColdDest4,
+ kEobBaseConeOfColdGfxTbl,
kEob1MainMenuStrings,
+ kEob1BonusStrings,
+
+ kEob1IntroFilesOpening,
+ kEob1IntroFilesTower,
+ kEob1IntroFilesOrb,
+ kEob1IntroFilesWdEntry,
+ kEob1IntroFilesKing,
+ kEob1IntroFilesHands,
+ kEob1IntroFilesWdExit,
+ kEob1IntroFilesTunnel,
+ kEob1IntroOpeningFrmDelay,
+ kEob1IntroWdEncodeX,
+ kEob1IntroWdEncodeY,
+ kEob1IntroWdEncodeWH,
+ kEob1IntroWdDsX,
+ kEob1IntroWdDsY,
+ kEob1IntroTvlX1,
+ kEob1IntroTvlY1,
+ kEob1IntroTvlX2,
+ kEob1IntroTvlY2,
+ kEob1IntroTvlW,
+ kEob1IntroTvlH,
+
kEob1DoorShapeDefs,
kEob1DoorSwitchShapeDefs,
kEob1DoorSwitchCoords,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 31f6dd6300..9ecbf0144c 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -97,8 +97,8 @@ const Game kyra3Games[] = {
};
const Game eob1Games[] = {
- { kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", 0 } },
- { kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", 0 } },
+ { kEob1, { EN_ANY, -1, -1 }, kPlatformPC, kNoSpecial, { "1bde1dd37b40ab6de8ad11be33a44c5a", "d760a605d1a1302d06975a1f209fdd72" } },
+ { kEob1, { DE_DEU, -1, -1 }, kPlatformPC, kNoSpecial, { "0fa3c6e00a81171b9f2adb3fdeb8eea3", "756f300c62aabf1dbd3c26b3b04f8c00" } },
GAME_DUMMY_ENTRY
};
@@ -1055,6 +1055,29 @@ const int eob1FloppyNeed[] = {
kEobBaseConstModExt,
kEob1MainMenuStrings,
+ kEob1BonusStrings,
+
+ kEob1IntroFilesOpening,
+ kEob1IntroFilesTower,
+ kEob1IntroFilesOrb,
+ kEob1IntroFilesWdEntry,
+ kEob1IntroFilesKing,
+ kEob1IntroFilesHands,
+ kEob1IntroFilesWdExit,
+ kEob1IntroFilesTunnel,
+ kEob1IntroOpeningFrmDelay,
+ kEob1IntroWdEncodeX,
+ kEob1IntroWdEncodeY,
+ kEob1IntroWdEncodeWH,
+ kEob1IntroWdDsX,
+ kEob1IntroWdDsY,
+ kEob1IntroTvlX1,
+ kEob1IntroTvlY1,
+ kEob1IntroTvlX2,
+ kEob1IntroTvlY2,
+ kEob1IntroTvlW,
+ kEob1IntroTvlH,
+
kEob1DoorShapeDefs,
kEob1DoorSwitchShapeDefs,
kEob1DoorSwitchCoords,
@@ -1190,6 +1213,11 @@ const int eob1FloppyNeed[] = {
kEobBaseMagicFlightProps,
kEobBaseTurnUndeadEffect,
kEobBaseBurningHandsDest,
+ kEobBaseConeOfColdDest1,
+ kEobBaseConeOfColdDest2,
+ kEobBaseConeOfColdDest3,
+ kEobBaseConeOfColdDest4,
+ kEobBaseConeOfColdGfxTbl,
kLolEobCommonDscDoorShapeIndex,
kEobBaseWllFlagPreset,
@@ -1411,6 +1439,11 @@ const int eob2FloppyNeed[] = {
kEobBaseMagicFlightProps,
kEobBaseTurnUndeadEffect,
kEobBaseBurningHandsDest,
+ kEobBaseConeOfColdDest1,
+ kEobBaseConeOfColdDest2,
+ kEobBaseConeOfColdDest3,
+ kEobBaseConeOfColdDest4,
+ kEobBaseConeOfColdGfxTbl,
kLolEobCommonDscDoorShapeIndex,
kEobBaseWllFlagPreset,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index d846372b77..ab75baf91c 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2362,12 +2362,143 @@ const ExtractEntrySearchData kEobBaseBurningHandsDestProvider[] = {
EXTRACT_END_ENTRY
};
+const ExtractEntrySearchData kEobBaseConeOfColdDest1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000500, { { 0x48, 0xF1, 0xFE, 0x48, 0xEC, 0x64, 0x17, 0x51, 0x5C, 0x9A, 0x91, 0x35, 0x95, 0xC3, 0x73, 0x8E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000210, { { 0xBA, 0x62, 0xA0, 0x4F, 0x50, 0x0C, 0x02, 0xC3, 0xAD, 0x7C, 0x39, 0x63, 0x5F, 0x41, 0xB4, 0xFB } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest3Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x00000200, { { 0xA0, 0x1F, 0xAC, 0x3A, 0x2D, 0x25, 0x1F, 0x5C, 0xD2, 0x04, 0xAC, 0xAB, 0x97, 0x8B, 0x61, 0xD7 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdDest4Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000007, 0x000004F0, { { 0xB3, 0x9A, 0x2B, 0x3A, 0x51, 0x24, 0x95, 0xBE, 0xDE, 0x0F, 0xD5, 0xE9, 0xE9, 0x21, 0x96, 0x04 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEobBaseConeOfColdGfxTblProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000010, 0x0000003E, { { 0x0A, 0xBA, 0xFD, 0x3F, 0xD8, 0x49, 0x3F, 0xD2, 0x26, 0x1B, 0x19, 0x53, 0x4F, 0x84, 0xB9, 0x4F } } } },
+ EXTRACT_END_ENTRY
+};
+
const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
EXTRACT_END_ENTRY
};
+const ExtractEntrySearchData kEob1BonusStringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000093, 0x000031B6, { { 0xC1, 0x54, 0x1D, 0x02, 0x4A, 0x35, 0x7F, 0x5D, 0x84, 0x2D, 0x2C, 0x9C, 0x06, 0x97, 0x29, 0x8D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000093, 0x000031CD, { { 0x3E, 0x0F, 0x52, 0x02, 0xC7, 0x9E, 0x83, 0xB3, 0xB1, 0xAB, 0x03, 0x3A, 0x18, 0xE2, 0x87, 0x2E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesOpeningProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000003F, 0x00001044, { { 0xF5, 0x8C, 0xC8, 0x39, 0x38, 0xBB, 0x0B, 0xCA, 0x34, 0x38, 0x1D, 0x11, 0x46, 0x91, 0xEF, 0x7E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesTowerProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E6, { { 0xBD, 0x06, 0x3B, 0x7D, 0x24, 0x79, 0xD6, 0xC2, 0xFA, 0xDA, 0x31, 0x15, 0x3E, 0xE2, 0x75, 0xF8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesOrbProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000015, 0x00000565, { { 0xA7, 0x91, 0x97, 0x5B, 0x29, 0xE8, 0x27, 0x90, 0xB3, 0x8F, 0xD5, 0x13, 0x77, 0x4A, 0x93, 0x37 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesWdEntryProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000002C, 0x00000B42, { { 0x5C, 0xDF, 0xB1, 0x2A, 0x83, 0x03, 0x73, 0x47, 0x1E, 0x29, 0x7C, 0x16, 0x2E, 0x5D, 0x0F, 0xA4 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesKingProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000016, 0x000005AE, { { 0xB5, 0xB5, 0x80, 0xD3, 0xC0, 0xF4, 0x9F, 0xE1, 0x12, 0x3C, 0xCB, 0xD6, 0xF2, 0x7F, 0x15, 0x5B } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesHandsProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000027C, { { 0x90, 0xC7, 0x36, 0xE6, 0x7D, 0x6D, 0xCB, 0x77, 0xA0, 0x03, 0x45, 0x48, 0x46, 0xF3, 0x80, 0xC8 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesWdExitProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000033, 0x00000D2A, { { 0xA8, 0xF0, 0x36, 0x0E, 0x37, 0xC6, 0xCC, 0xDB, 0x9B, 0xB8, 0x52, 0x64, 0x02, 0x1E, 0x9D, 0x1C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroFilesTunnelProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001A, 0x000006E2, { { 0xA1, 0xDD, 0x20, 0x50, 0x7A, 0xB6, 0x89, 0x67, 0x13, 0xAA, 0x47, 0x6B, 0xC0, 0xA0, 0x8A, 0xFD } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroOpeningFrmDelayProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000000A, 0x000001E0, { { 0xDA, 0xE3, 0x06, 0xA2, 0x41, 0xF6, 0x5A, 0x6A, 0xBD, 0x0B, 0xA6, 0x09, 0x69, 0x03, 0x1D, 0x2C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x000001BB, { { 0x00, 0x50, 0x8E, 0xF5, 0x51, 0xA6, 0xF5, 0x57, 0x0D, 0x55, 0x6C, 0x14, 0x62, 0xCD, 0xD0, 0x7E } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x0000000B, { { 0x39, 0x38, 0x02, 0xCE, 0x9D, 0x89, 0x1E, 0xBF, 0x32, 0x86, 0xA0, 0x79, 0xA4, 0xBE, 0xC5, 0x81 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdEncodeWHProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000027, { { 0xA8, 0x6C, 0x13, 0x2B, 0x4C, 0x26, 0x38, 0x3D, 0xDA, 0xC2, 0x90, 0xB3, 0x97, 0xA9, 0x45, 0x84 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdDsXProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000003E, 0x0000104A, { { 0xAC, 0x1F, 0xA6, 0x20, 0xD0, 0x02, 0xF0, 0x9D, 0x75, 0x93, 0x6C, 0x12, 0x0A, 0x76, 0x1B, 0x3F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroWdDsYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000001F, 0x00000655, { { 0xF3, 0xF7, 0x65, 0xEC, 0xEA, 0x5C, 0x08, 0xCF, 0xAD, 0x48, 0x35, 0xA2, 0x5B, 0x82, 0xB0, 0xC5 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlX1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000027, { { 0x7F, 0x14, 0x7D, 0x8C, 0x20, 0x49, 0xDB, 0xC3, 0x31, 0x1A, 0xC3, 0x95, 0xA4, 0x8C, 0x96, 0xDC } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlY1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x000000EC, { { 0x29, 0xB4, 0x8D, 0xE1, 0xDF, 0x36, 0x39, 0x27, 0xC8, 0xF6, 0x32, 0x1A, 0x3B, 0x74, 0xA1, 0x4F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlX2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x51, 0x33, 0x0A, 0x55, 0x76, 0xA2, 0x91, 0xDA, 0x59, 0xD6, 0x09, 0xD9, 0x3D, 0xD4, 0xB8, 0xFE } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlY2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000016A, { { 0xD5, 0xA3, 0xF6, 0x12, 0x90, 0x87, 0xF2, 0xC7, 0x6A, 0x22, 0x77, 0xB5, 0x48, 0xB2, 0xCB, 0xCA } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlWProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000004E, { { 0xCF, 0xC7, 0xA8, 0x59, 0x6A, 0x5B, 0x35, 0x7F, 0xC9, 0xEC, 0x59, 0x7E, 0x88, 0x31, 0x32, 0xA6 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1IntroTvlHProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x0000013D, { { 0x26, 0x7B, 0x3D, 0x5F, 0x64, 0x97, 0xF9, 0x1B, 0xB6, 0x65, 0x99, 0x95, 0x0A, 0x98, 0x38, 0x92 } } } },
+ EXTRACT_END_ENTRY
+};
+
const ExtractEntrySearchData kEob1DoorShapeDefsProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x00000060, 0x00000F8A, { { 0x95, 0x53, 0x1B, 0x07, 0x64, 0x81, 0x0E, 0x04, 0xC0, 0xDA, 0xB5, 0x74, 0x57, 0x04, 0x10, 0xE2 } } } },
EXTRACT_END_ENTRY
@@ -3863,8 +3994,36 @@ const ExtractEntry extractProviders[] = {
{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
{ kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
{ kEobBaseBurningHandsDest, kEobBaseBurningHandsDestProvider },
+ { kEobBaseConeOfColdDest1, kEobBaseConeOfColdDest1Provider },
+ { kEobBaseConeOfColdDest2, kEobBaseConeOfColdDest2Provider },
+ { kEobBaseConeOfColdDest3, kEobBaseConeOfColdDest3Provider },
+ { kEobBaseConeOfColdDest4, kEobBaseConeOfColdDest4Provider },
+ { kEobBaseConeOfColdGfxTbl, kEobBaseConeOfColdGfxTblProvider },
{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
+ { kEob1BonusStrings, kEob1BonusStringsProvider },
+
+ { kEob1IntroFilesOpening, kEob1IntroFilesOpeningProvider },
+ { kEob1IntroFilesTower, kEob1IntroFilesTowerProvider },
+ { kEob1IntroFilesOrb, kEob1IntroFilesOrbProvider },
+ { kEob1IntroFilesWdEntry, kEob1IntroFilesWdEntryProvider },
+ { kEob1IntroFilesKing, kEob1IntroFilesKingProvider },
+ { kEob1IntroFilesHands, kEob1IntroFilesHandsProvider },
+ { kEob1IntroFilesWdExit, kEob1IntroFilesWdExitProvider },
+ { kEob1IntroFilesTunnel, kEob1IntroFilesTunnelProvider },
+ { kEob1IntroOpeningFrmDelay, kEob1IntroOpeningFrmDelayProvider },
+ { kEob1IntroWdEncodeX, kEob1IntroWdEncodeXProvider },
+ { kEob1IntroWdEncodeY, kEob1IntroWdEncodeYProvider },
+ { kEob1IntroWdEncodeWH, kEob1IntroWdEncodeWHProvider },
+ { kEob1IntroWdDsX, kEob1IntroWdDsXProvider },
+ { kEob1IntroWdDsY, kEob1IntroWdDsYProvider },
+ { kEob1IntroTvlX1, kEob1IntroTvlX1Provider },
+ { kEob1IntroTvlY1, kEob1IntroTvlY1Provider },
+ { kEob1IntroTvlX2, kEob1IntroTvlX2Provider },
+ { kEob1IntroTvlY2, kEob1IntroTvlY2Provider },
+ { kEob1IntroTvlW, kEob1IntroTvlWProvider },
+ { kEob1IntroTvlH, kEob1IntroTvlHProvider },
+
{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
{ kEob1DoorSwitchShapeDefs, kEob1DoorSwitchShapeDefsProvider },
{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 494a39591a..aa3d62b84d 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 681412915d..e97b7a1b2d 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -144,7 +144,7 @@ CharacterGenerator::~CharacterGenerator() {
}
if (_chargenButtonLabels) {
- for (int i = 0; i < 10; i++)
+ for (int i = 0; i < 17; i++)
delete[] _chargenButtonLabels[i];
delete[] _chargenButtonLabels;
}
@@ -516,7 +516,7 @@ int CharacterGenerator::classMenu(int raceSex) {
toggleSpecialButton(5, 0, 0);
- itemsMask &=_classMenuMasks[raceSex / 2];
+ itemsMask &= _classMenuMasks[raceSex / 2];
_vm->_gui->simpleMenu_setup(2, 15, _chargenClassStrings, itemsMask, 0, 0);
_vm->_mouseX = _vm->_mouseY = 0;
@@ -565,7 +565,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
toggleSpecialButton(5, 0, 0);
- itemsMask &=_alignmentMenuMasks[cClass];
+ itemsMask &= _alignmentMenuMasks[cClass];
_vm->_gui->simpleMenu_setup(3, 9, _chargenAlignmentStrings, itemsMask, 0, 0);
_vm->_mouseX = _vm->_mouseY = 0;
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index 6491dfa135..71644c5a87 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -172,23 +172,23 @@ void EobEngine::runNpcDialogue(int npcIndex) {
case 0:
for (r = 1; r == 1; ) {
gui_drawDialogueBox();
- r = DLG2A3(checkScriptFlag(0x2000), 8, 12, 11);
+ r = DLG2A3(checkScriptFlags(0x2000), 8, 12, 11);
if (r == 1) {
TXT(1);
- setScriptFlag(0x2000);
+ setScriptFlags(0x2000);
} else if (r == 0) {
npcJoinDialogue(6, 12, 23, 2);
- setScriptFlag(0x4000);
+ setScriptFlags(0x4000);
}
}
break;
case 1:
- if (!checkScriptFlag(0x10000)) {
- if (checkScriptFlag(0x8000)) {
+ if (!checkScriptFlags(0x10000)) {
+ if (checkScriptFlags(0x8000)) {
a = 1;
} else {
- setScriptFlag(0x8000);
+ setScriptFlags(0x8000);
r = DLG2(3, 21);
}
if (!r)
@@ -198,7 +198,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
for (a = 0; a < 6; a++)
createItemOnCurrentBlock(55);
createItemOnCurrentBlock(62);
- setScriptFlag(0x10000);
+ setScriptFlags(0x10000);
TXT(6);
npcJoinDialogue(7, 7, 29, 30);
} else {
@@ -207,7 +207,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
r = 1;
}
- if (!checkScriptFlag(0x80000)) {
+ if (!checkScriptFlags(0x80000)) {
for (a = 0; a < 6; a++) {
if (testCharacter(a, 1) && _characters[a].portrait == -9)
break;
@@ -215,18 +215,18 @@ void EobEngine::runNpcDialogue(int npcIndex) {
if (a != 6) {
TXT(25);
TXT(26);
- setScriptFlag(0x80000);
+ setScriptFlags(0x80000);
r = 1;
}
}
- if (!checkScriptFlag(0x100000)) {
+ if (!checkScriptFlags(0x100000)) {
if (deletePartyItems(6, -1)) {
//_npcSequenceSub = 0;
//drawNpcScene(npcIndex);
TXT(28);
createItemOnCurrentBlock(32);
- setScriptFlag(0x100000);
+ setScriptFlags(0x100000);
r = 1;
}
}
@@ -237,8 +237,8 @@ void EobEngine::runNpcDialogue(int npcIndex) {
break;
case 2:
- if (checkScriptFlag(0x10000)) {
- if (checkScriptFlag(0x20000)) {
+ if (checkScriptFlags(0x10000)) {
+ if (checkScriptFlags(0x20000)) {
TXT(11);
} else {
r = DLG2A3(!countResurrectionCandidates(), 9, 31, 32);
@@ -247,7 +247,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
healParty();
else
resurrectionSelectDialogue();
- setScriptFlag(0x20000);
+ setScriptFlags(0x20000);
}
}
} else {
@@ -257,14 +257,14 @@ void EobEngine::runNpcDialogue(int npcIndex) {
case 3:
if (!DLG2(18, 4)) {
- setScriptFlag(0x8400000);
+ setScriptFlags(0x8400000);
for (a = 0; a < 30; a++) {
if (_monsters[a].mode == 8)
_monsters[a].mode = 5;
}
} else if (deletePartyItems(49, -1)) {
TXT(20);
- setScriptFlag(0x400000);
+ setScriptFlags(0x400000);
} else {
TXT(19);
}
@@ -273,10 +273,10 @@ void EobEngine::runNpcDialogue(int npcIndex) {
case 4:
r = DLG3(14, 5);
if (r == 0)
- setScriptFlag(0x200000);
+ setScriptFlags(0x200000);
else if (r == 1)
TXT(15);
- setScriptFlag(0x800000);
+ setScriptFlags(0x800000);
break;
case 5:
@@ -292,12 +292,12 @@ void EobEngine::runNpcDialogue(int npcIndex) {
}
}
}
- setScriptFlag(0x2000000);
+ setScriptFlags(0x2000000);
break;
case 6:
TXT(21);
- setScriptFlag(0x1000000);
+ setScriptFlags(0x1000000);
break;
case 7:
@@ -307,7 +307,7 @@ void EobEngine::runNpcDialogue(int npcIndex) {
npcJoinDialogue(8, 27, 44, 45);
else
TXT(31);
- setScriptFlag(0x4000000);
+ setScriptFlags(0x4000000);
}
break;
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 21543ddfa5..227db4f916 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -55,6 +55,44 @@ private:
void seq_playIntro();
void seq_playFinale();
+ void seq_tower();
+ void seq_orb();
+ void seq_waterdeepEntry();
+ void seq_king();
+ void seq_hands();
+ void seq_waterdeepExit();
+ void seq_tunnel();
+
+ void seq_xdeath();
+
+ void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
+
+ void boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH);
+ void whirlTransition();
+
+ const char *const *_introFilesOpening;
+ const char *const *_introFilesTower;
+ const char *const *_introFilesOrb;
+ const char *const *_introFilesWdEntry;
+ const char *const *_introFilesKing;
+ const char *const *_introFilesHands;
+ const char *const *_introFilesWdExit;
+ const char *const *_introFilesTunnel;
+ const uint8 *_introOpeningFrmDelay;
+ const uint8 *_introWdEncodeX;
+ const uint8 *_introWdEncodeY;
+ const uint8 *_introWdEncodeWH;
+ const uint16 *_introWdDsX;
+ const uint8 *_introWdDsY;
+ const uint8 *_introTvlX1;
+ const uint8 *_introTvlY1;
+ const uint8 *_introTvlX2;
+ const uint8 *_introTvlY2;
+ const uint8 *_introTvlW;
+ const uint8 *_introTvlH;
+
+ const char *const *_finBonusStrings;
+
// characters
void drawNpcScene(int npcIndex);
void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index 9efc558b7f..0ecdba0fd3 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -106,7 +106,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
if (npcIndex == 0) {
snd_playSoundEffect(57);
if (npcJoinDialogue(0, 1, 3, 2))
- setScriptFlag(0x40);
+ setScriptFlags(0x40);
} else if (npcIndex == 1) {
snd_playSoundEffect(53);
gui_drawDialogueBox();
@@ -120,7 +120,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
snd_playSoundEffect(91);
npcJoinDialogue(1, 5, 6, 7);
} else if (r == 1) {
- setScriptFlag(0x20);
+ setScriptFlags(0x20);
}
} else if (npcIndex == 2) {
@@ -135,7 +135,7 @@ void DarkMoonEngine::runNpcDialogue(int npcIndex) {
_txt->printDialogueText(9, _okStrings[0]);
else
npcJoinDialogue(2, 102, 103, 104);
- setScriptFlag(8);
+ setScriptFlags(8);
} else if (r == 1) {
_currentDirection = 0;
}
@@ -357,7 +357,7 @@ void DarkMoonEngine::restParty_npc() {
if (insalId < 4)
exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
- clearScriptFlag(6);
+ clearScriptFlags(6);
if (!stripPartyItems(1, 1, 1, 1))
stripPartyItems(2, 1, 1, 1);
@@ -391,7 +391,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
}
bool DarkMoonEngine::checkPartyStatusExtra() {
- if (checkScriptFlag(0x100000))
+ if (checkScriptFlags(0x100000))
seq_dranFools();
return _gui->confirmDialogue2(14, 67, 1);
}
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index b9406ff05d..dc987c1533 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -133,6 +133,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_activeSpellCharId = 0;
_activeSpellCharacterPos = 0;
_activeSpell = 0;
+ _characterSpellTarget = 0;
_returnAfterSpellCallback = false;
_spells = 0;
_spellAnimBuffer = 0;
@@ -447,6 +448,9 @@ void EobCoreEngine::runLoop() {
checkInput(_activeButtons, true, 0);
removeInputTop();
+ if (!_runFlag)
+ break;
+
_timer->update();
updateScriptTimers();
@@ -1499,10 +1503,6 @@ int EobCoreEngine::countResurrectionCandidates() {
}
void EobCoreEngine::seq_portal() {
- releaseDoorShapes();
- releaseMonsterShapes(0, 36);
- releaseDecorations();
-
uint8 *shapes1[5];
uint8 *shapes2[5];
uint8 *shapes3[5];
@@ -1686,7 +1686,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
flg |= 1;
_dstMonsterIndex = r;
- return calcCloseDistanceMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
+ return calcMonsterDamage(&_monsters[r], charIndex, item, 1, flg, 5, 3);
}
return 0;
@@ -1770,38 +1770,38 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
m->dest = _currentBlock;
}
-void EobCoreEngine::calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
- int dmg = calcCloseDistanceMonsterDamage(m, times, pips, offs, flags, b, damageType);
+void EobCoreEngine::calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
+ int dmg = calcMonsterDamage(m, times, pips, offs, flags, savingThrowType, savingThrowEffect);
if (dmg > 0)
inflictMonsterDamage(m, dmg, flags & 0x800 ? true : false);
}
-void EobCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
- int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flg, a, damageType);
+void EobCoreEngine::calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+ int dmg = calcCharacterDamage(charIndex, times, itemOrPips, useStrModifierOrBase, flags, savingThrowType, savingThrowEffect);
if (dmg)
inflictCharacterDamage(charIndex, dmg);
}
-int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) {
- int s = (flg & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
+int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect) {
+ int s = (flags & 0x100) ? calcDamageModifers(times, 0, itemOrPips, _items[itemOrPips].type, useStrModifierOrBase) : rollDice(times, itemOrPips, useStrModifierOrBase);
EobCharacter *c = &_characters[charIndex];
- if (a != 5) {
- if (checkMonsterLevelConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
- s = recalcDamageModifier(damageType, s);
+ if (savingThrowType != 5) {
+ if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex))
+ s = savingThrowReduceDamage(savingThrowEffect, s);
}
- if ((flg & 0x110) == 0x110) {
+ if ((flags & 0x110) == 0x110) {
if (!calcDamageCheckItemType(_items[itemOrPips].type))
s = 1;
}
- if (flg & 4) {
+ if (flags & 4) {
if (checkInventoryForRings(charIndex, 3))
s = 0;
}
- if (flg & 0x400) {
+ if (flags & 0x400) {
if (c->effectFlags & 0x2000)
s = 0;
else
@@ -2016,14 +2016,14 @@ void EobCoreEngine::monsterSpellCast(EobMonsterInPlay *m, int type) {
snd_processEnvironmentalSoundEffect(_spells[_magicFlightObjectProperties[type << 2]].sound, m->block);
}
-void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh) {
+void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh) {
EobCharacter *c = &_characters[charIndex];
if ((c->flags & attackStatusFlags) && noRefresh)
return;
if (!testCharacter(charIndex, 3))
return;
- if (a != 5 && specialAttackConstTest(charIndex, a))
+ if (savingThrowType != 5 && specialAttackSavingThrow(charIndex, savingThrowType))
return;
if (attackStatusFlags & 8) {
@@ -2045,13 +2045,13 @@ void EobCoreEngine::statusAttack(int charIndex, int attackStatusFlags, const cha
_txt->printMessage(_characterStatusStrings13[0], -1, c->name, attackStatusString);
}
-int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType) {
+int EobCoreEngine::calcMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect) {
int s = flags & 0x100 ? calcDamageModifers(times, m, pips, _items[pips].type, offs) : rollDice(times, pips, offs);
EobMonsterProperty *p = &_monsterProps[m->type];
- if (b == 5) {
- if (checkMonsterLevelConstModifiers(m, 0, p->level, b, 6))
- s = recalcDamageModifier(damageType, s);
+ if (savingThrowType != 5) {
+ if (trySavingThrow(m, 0, p->level, savingThrowType, 6))
+ s = savingThrowReduceDamage(savingThrowEffect, s);
}
if ((flags & 0x110) == 0x110) {
@@ -2110,14 +2110,14 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
return (s < 0) ? 0 : s;
}
-bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race) {
+bool EobCoreEngine::trySavingThrow(void *target, int hpModifier, int level, int type, int race) {
static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
- if (b == 5)
+ if (type == 5)
return false;
- int s = getConstModifierTableValue(hpModifier, level, b);
- if (((race == 3 || race == 5) && (b == 4 || b == 1 || b == 0)) || (race == 4 && (b == 4 || b == 1))) {
+ int s = getConstModifierTableValue(hpModifier, level, type);
+ if (((race == 3 || race == 5) && (type == 4 || type == 1 || type == 0)) || (race == 4 && (type == 4 || type == 1))) {
EobCharacter *c = (EobCharacter*)target;
s -= constMod[c->constitutionCur];
}
@@ -2125,8 +2125,8 @@ bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier
return rollDice(1, 20) < s ? false : true;
}
-bool EobCoreEngine::specialAttackConstTest(int charIndex, int b) {
- return checkMonsterLevelConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
+bool EobCoreEngine::specialAttackSavingThrow(int charIndex, int type) {
+ return trySavingThrow(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], type, _characters[charIndex].raceSex >> 1);
}
int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
@@ -2144,14 +2144,14 @@ bool EobCoreEngine::calcDamageCheckItemType(int itemType) {
return (itemType == 2 || itemType == 3) ? true : false;
}
-int EobCoreEngine::recalcDamageModifier(int damageType, int dmgModifier) {
- if (damageType == 3)
+int EobCoreEngine::savingThrowReduceDamage(int savingThrowEffect, int damage) {
+ if (savingThrowEffect == 3)
return 0;
- if (damageType == 0 || damageType == 1)
- return dmgModifier >> 1;
+ if (savingThrowEffect == 0 || savingThrowEffect == 1)
+ return damage >> 1;
- return dmgModifier;
+ return damage;
}
bool EobCoreEngine::tryMonsterAttackEvasion(EobMonsterInPlay *m) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 867582864f..51dfb8b726 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -260,6 +260,7 @@ protected:
// Main Menu, Intro, Finale
virtual int mainMenu() = 0;
+ virtual void seq_xdeath() {};
virtual void seq_playFinale() = 0;
bool _playFinale;
@@ -630,9 +631,9 @@ protected:
// Script
void runLevelScript(int block, int flags);
- void setScriptFlag(int flag);
- void clearScriptFlag(int flag);
- bool checkScriptFlag(int flag);
+ void setScriptFlags(uint32 flags);
+ void clearScriptFlags(uint32 flags);
+ bool checkScriptFlags(uint32 flags);
const uint8 *initScriptTimers(const uint8 *pos);
void updateScriptTimers();
@@ -856,9 +857,9 @@ protected:
int projectileWeaponAttack(int charIndex, Item item);
void inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool giveExperience);
- void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
- void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType);
- int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flg, int a, int damageType) ;
+ void calcAndInflictMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
+ void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect);
+ int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int damageType) ;
void inflictCharacterDamage(int charIndex, int damage);
bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
@@ -868,15 +869,15 @@ protected:
void monsterCloseAttack(EobMonsterInPlay *m);
void monsterSpellCast(EobMonsterInPlay *m, int type);
- void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int a, uint32 effectDuration, int restoreEvent, int noRefresh);
+ void statusAttack(int charIndex, int attackStatusFlags, const char *attackStatusString, int savingThrowType, uint32 effectDuration, int restoreEvent, int noRefresh);
- int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
+ int calcMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
- bool checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race);
- bool specialAttackConstTest(int charIndex, int b);
+ bool trySavingThrow(void *target, int hpModifier, int level, int type, int race);
+ bool specialAttackSavingThrow(int charIndex, int type);
int getConstModifierTableValue(int hpModifier, int level, int b);
bool calcDamageCheckItemType(int itemType);
- int recalcDamageModifier(int damageType, int dmgModifier);
+ int savingThrowReduceDamage(int savingThrowEffect, int damage);
bool tryMonsterAttackEvasion(EobMonsterInPlay *m);
int getStrHitChanceModifier(int charIndex);
int getStrDamageModifier(int charIndex);
@@ -912,6 +913,7 @@ protected:
bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
+ void causeWounds(int dcTimes, int dcPips, int dcOffs);
int getMagicWeaponSlot(int charIndex);
int createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNum, int dmgPips, int dmgInc, int extraProps);
@@ -919,6 +921,10 @@ protected:
void removeMagicWeaponItem(Item item);
int findSingleSpellTarget(int dist);
+
+ int findFirstCharacterSpellTarget();
+ int findNextCharacterSpellTarget(int curCharIndex);
+ int charDeathSavingThrow(int charIndex, int div);
void printWarning(const char *str);
void printNoEffectWarning();
@@ -987,10 +993,10 @@ protected:
bool spellCallback_end_lightningBoltPassive(void *obj);
bool spellCallback_end_unk1Passive(void *obj);
bool spellCallback_end_unk2Passive(void *obj);
- bool spellCallback_end_deathSpellPassive(void*);
- bool spellCallback_end_disintegratePassive(void*);
- bool spellCallback_end_causeCriticalWoundsPassive(void*);
- bool spellCallback_end_fleshToStonePassive(void*);
+ bool spellCallback_end_deathSpellPassive(void *obj);
+ bool spellCallback_end_disintegratePassive(void *obj);
+ bool spellCallback_end_causeCriticalWoundsPassive(void *obj);
+ bool spellCallback_end_fleshToStonePassive(void *obj);
int8 _openBookSpellLevel;
int8 _openBookSpellSelectedItem;
@@ -1005,6 +1011,7 @@ protected:
uint8 _activeSpellCharId;
uint8 _activeSpellCharacterPos;
int _activeSpell;
+ int _characterSpellTarget;
bool _returnAfterSpellCallback;
typedef void (EobCoreEngine::*SpellStartCallback)();
@@ -1059,7 +1066,8 @@ protected:
const int8 *_coneOfColdDest2;
const int8 *_coneOfColdDest3;
const int8 *_coneOfColdDest4;
- const int8 *_coneOfColdGfxTbl;
+ const uint8 *_coneOfColdGfxTbl;
+ int _coneOfColdGfxTblSize;
// Menu
EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index 393bbab4a8..fcd66c923b 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -385,7 +385,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
if (itm)
drawItemIconShape(_screen->_curPage, itm, x + 8, y);
- else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlag(0x80000000))
+ else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlags(0x80000000))
_screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
else
_screen->drawShape(_screen->_curPage, _itemIconShapes[85], x + 8, y, 0);
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 88046fd3a5..2ad0da7258 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -314,17 +314,14 @@ void EobCoreEngine::startSpell(int spell) {
}
if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
- if (_flags.gameID == GI_EOB1) {
- // TODO: warnings seem to exist at least for bless and aid
- } else {
+ if (_flags.gameID == GI_EOB2)
printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
- }
} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
- if (_flags.gameID == GI_EOB1) {
- // TODO: warnings seem to exist at least for bless and aid
- } else {
+ if (_flags.gameID == GI_EOB1 && s->effectFlags == 0x400)
+ // EOB 1 only warns in case of a bless spell
+ printWarning(_magicStrings8[1]);
+ else
printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
- }
} else {
if (s->flags & 8)
setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@@ -569,7 +566,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
return true;
}
- if (checkMonsterLevelConstModifiers(m, 0, p->level, mod, 6))
+ if (trySavingThrow(m, 0, p->level, mod, 6))
return false;
int para = 0;
@@ -638,6 +635,26 @@ int EobCoreEngine::getMagicWeaponSlot(int charIndex) {
return _characters[charIndex].inventory[1] ? 0 : 1;
}
+void EobCoreEngine::causeWounds(int dcTimes, int dcPips, int dcOffs) {
+ if (_openBookChar == 0 || _openBookChar == 1) {
+ int d = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+ if (d != -1) {
+ if (!characterAttackHitTest(_openBookChar, d, 0, 1))
+ return;
+
+ if (dcTimes == -1) {
+ dcOffs = _monsters[d].hitPointsMax - rollDice(1, 4);
+ dcTimes = dcPips = 0;
+ }
+ calcAndInflictMonsterDamage(&_monsters[d], dcTimes, dcPips, dcOffs, 0x801, 4, 2);
+ } else {
+ printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 4 : 3], _characters[_openBookChar].name).c_str());
+ }
+ } else {
+ printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 5 : 4], _characters[_openBookChar].name).c_str());
+ }
+}
+
int EobCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorClass, int allowedClasses, int dmgNumDice, int dmgPips, int dmgInc, int extraProps) {
int i = 51;
for (; i < 57; i++) {
@@ -655,7 +672,7 @@ int EobCoreEngine::createMagicWeaponType(int invFlags, int handFlags, int armorC
tp->armorClass = armorClass;
tp->allowedClasses = allowedClasses;
tp->dmgNumDiceL = tp->dmgNumDiceS = dmgNumDice;
- tp->dmgNumPipsL = tp->dmgNumPipsL = dmgPips;
+ tp->dmgNumPipsL = tp->dmgNumPipsS = dmgPips;
tp->dmgIncL = tp->dmgIncS = dmgInc;
tp->extraProperties = extraProps;
@@ -707,6 +724,33 @@ int EobCoreEngine::findSingleSpellTarget(int dist) {
return res;
}
+int EobCoreEngine::findFirstCharacterSpellTarget() {
+ int curCharIndex = rollDice(1, 6, -1);
+ for (_characterSpellTarget = 0; _characterSpellTarget < 6; _characterSpellTarget++) {
+ if (testCharacter(curCharIndex, 3))
+ return curCharIndex;
+ if (++curCharIndex == 6)
+ curCharIndex = 0;
+ }
+ return -1;
+}
+
+int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
+ for (; _characterSpellTarget < 6; _characterSpellTarget++) {
+ if (++curCharIndex == 6)
+ curCharIndex = 0;
+ if (testCharacter(curCharIndex, 3))
+ return curCharIndex;
+ }
+ return -1;
+}
+
+int EobCoreEngine::charDeathSavingThrow(int charIndex, int div) {
+ if (specialAttackSavingThrow(charIndex, 4))
+ div >>= 1;
+ return div;
+}
+
void EobCoreEngine::printWarning(const char *str) {
_txt->printMessage(str);
snd_playSoundEffect(79);
@@ -794,7 +838,11 @@ bool EobCoreEngine::spellCallback_end_shockingGraspFlameBlade(void *obj) {
}
void EobCoreEngine::spellCallback_start_improvedIdentify() {
-
+ for (int i = 0; i < 2; i++) {
+ Item itm = _characters[_activeSpellCharId].inventory[i];
+ if (itm)
+ _items[itm].flags |= 0x40;
+ }
}
void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
@@ -937,7 +985,15 @@ void EobCoreEngine::spellCallback_start_coneOfCold() {
static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
int cl = getMageLevel(_openBookChar);
- //drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 176, 120, 0);
+ _screen->setGfxParameters(0, 0, _screen->getPagePixel(2, 0, 0));
+ drawSceneShapes(7);
+ _screen->setCurPage(0);
+ disableSysTimer(2);
+ _screen->drawVortex(150, 50, 10, 1, 100, _coneOfColdGfxTbl, _coneOfColdGfxTblSize);
+ enableSysTimer(2);
const int8 *tbl = dirTables[_currentDirection];
_preventMonsterFlash = true;
@@ -1016,7 +1072,7 @@ void EobCoreEngine::spellCallback_start_powerWordStun() {
}
void EobCoreEngine::spellCallback_start_causeLightWounds() {
-
+ causeWounds(1, 8, 0);
}
void EobCoreEngine::spellCallback_start_cureLightWounds() {
@@ -1095,7 +1151,7 @@ void EobCoreEngine::spellCallback_start_removeParalysis() {
}
void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
-
+ causeWounds(2, 8, 1);
}
void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
@@ -1110,7 +1166,7 @@ void EobCoreEngine::spellCallback_start_neutralizePoison() {
}
void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
-
+ causeWounds(3, 8, 3);
}
void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
@@ -1136,7 +1192,7 @@ void EobCoreEngine::spellCallback_start_raiseDead() {
}
void EobCoreEngine::spellCallback_start_harm() {
-
+ causeWounds(-1, -1, -1);
}
void EobCoreEngine::spellCallback_start_heal() {
@@ -1202,19 +1258,68 @@ bool EobCoreEngine::spellCallback_end_unk2Passive(void *obj) {
return magicObjectDamageHit(fo, 0, 0, 18, 0);
}
-bool EobCoreEngine::spellCallback_end_deathSpellPassive(void*) {
+bool EobCoreEngine::spellCallback_end_deathSpellPassive(void *obj) {
+ EobFlyingObject *fo = (EobFlyingObject*)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int numDest = rollDice(1, 4);
+ _txt->printMessage(_magicStrings2[2]);
+ for (int d = findFirstCharacterSpellTarget(); d != -1 && numDest; d = findNextCharacterSpellTarget(d)) {
+ if (_characters[d].level[0] < 8) {
+ inflictCharacterDamage(d, 300);
+ numDest--;
+ }
+ }
+
return true;
}
-bool EobCoreEngine::spellCallback_end_disintegratePassive(void*) {
+bool EobCoreEngine::spellCallback_end_disintegratePassive(void *obj) {
+ EobFlyingObject *fo = (EobFlyingObject*)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ if (d != -1) {
+ if (!charDeathSavingThrow(d, 1)) {
+ inflictCharacterDamage(d, 300);
+ _txt->printMessage(_magicStrings2[1], -1, _characters[d].name);
+ }
+ }
+
return true;
}
-bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void*) {
+bool EobCoreEngine::spellCallback_end_causeCriticalWoundsPassive(void *obj) {
+ EobFlyingObject *fo = (EobFlyingObject*)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ if (d != -1) {
+ _txt->printMessage(_magicStrings2[3], -1, _characters[d].name);
+ inflictCharacterDamage(d, rollDice(3, 8, 3));
+ }
+
return true;
}
-bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void*) {
+bool EobCoreEngine::spellCallback_end_fleshToStonePassive(void *obj) {
+ EobFlyingObject *fo = (EobFlyingObject*)obj;
+ if (fo->curBlock != _currentBlock)
+ return false;
+
+ int d = findFirstCharacterSpellTarget();
+ while (d != -1) {
+ if (!charDeathSavingThrow(d, 2)) {
+ statusAttack(d, 8, _magicStrings2[4], 5, 0, 0, 1);
+ d = -1;
+ } else {
+ d = findNextCharacterSpellTarget(d);
+ }
+ }
+
return true;
}
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index b3a5aa3817..5ed658ccee 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -478,8 +478,36 @@ enum KyraResources {
kEobBaseMagicFlightProps,
kEobBaseTurnUndeadEffect,
kEobBaseBurningHandsDest,
+ kEobBaseConeOfColdDest1,
+ kEobBaseConeOfColdDest2,
+ kEobBaseConeOfColdDest3,
+ kEobBaseConeOfColdDest4,
+ kEobBaseConeOfColdGfxTbl,
kEob1MainMenuStrings,
+ kEob1BonusStrings,
+
+ kEob1IntroFilesOpening,
+ kEob1IntroFilesTower,
+ kEob1IntroFilesOrb,
+ kEob1IntroFilesWdEntry,
+ kEob1IntroFilesKing,
+ kEob1IntroFilesHands,
+ kEob1IntroFilesWdExit,
+ kEob1IntroFilesTunnel,
+ kEob1IntroOpeningFrmDelay,
+ kEob1IntroWdEncodeX,
+ kEob1IntroWdEncodeY,
+ kEob1IntroWdEncodeWH,
+ kEob1IntroWdDsX,
+ kEob1IntroWdDsY,
+ kEob1IntroTvlX1,
+ kEob1IntroTvlY1,
+ kEob1IntroTvlX2,
+ kEob1IntroTvlY2,
+ kEob1IntroTvlW,
+ kEob1IntroTvlH,
+
kEob1DoorShapeDefs,
kEob1DoorSwitchShapeDefs,
kEob1DoorSwitchCoords,
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 4c1bb1636f..aef131f6cb 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -1139,10 +1139,10 @@ void EobCoreEngine::drawDecorations(int index) {
int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint16 direction) {
uint16 b = calcNewBlockPosition(curBlock, direction);
int w = _levelBlockProperties[b].walls[direction ^ 2];
-
int f = _wllWallFlags[w];
+
if (!f)
- assert (w < (_flags.gameID == GI_EOB1 ? 70 : 80));
+ assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
if (w == 74 && _currentBlock == curBlock) {
for (int i = 0; i < 5; i++) {
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index ccbc2a166b..c9ee9119db 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -189,14 +189,14 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int
}
}
-uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag) {
+uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) {
uint8 *shp = 0;
uint16 shapesize = 0;
uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3);
uint8 *src = srcPage;
- if (flag) {
+ if (no4bitEncoding) {
uint16 h1 = h;
while (h1--) {
uint8 *lineEnd = src + (w << 3);
@@ -237,19 +237,20 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag
uint8 *lineEnd = src + (w << 3);
do {
uint8 val = *src++;
- if (!val) {
- *dst++ = val;
+ if (!val) {
+ *dst++ = 0;
uint8 *startZeroPos = src;
+
while (src != lineEnd && *src == 0)
src++;
uint16 numZero = src - startZeroPos + 1;
if (numZero >> 8) {
- numZero -= 0xff;
- *dst++ = 0xff;
+ *dst++ = 255;
*dst++ = 0;
+ numZero -= 255;
}
- val = (numZero & 0xff);
+ val = numZero & 0xff;
}
*dst++ = val;
} while (src != lineEnd);
@@ -384,7 +385,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
if (dX < 0) {
width += dX;
d = -dX;
- if ((flags & 1))
+ if (flags & 1)
src -= (d >> 1);
else
src += (d >> 1);
@@ -415,7 +416,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
dY = 320 - width;
width >>= 1;
w2 >>= 1;
- if ((flags & 1))
+ if (flags & 1)
src += (w2 - 1);
int16 w1shr = width;
@@ -431,7 +432,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
w1shr++;
int lineSrcStep = (w2 - w1shr);
- if ((flags & 1))
+ if (flags & 1)
lineSrcStep = w3 - lineSrcStep;
while (dH--) {
@@ -503,20 +504,12 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
return;
d = -d;
- for (int ii = 0; ii < d; ii++) {
+ for (int i = 0; i < d; i++) {
marginLeft = width;
- int i = 0;
- do {
- for (i = 0; i < marginLeft; i++)
- if (!*src++)
- break;
-
- if (!*(src-1) || i < marginLeft)
+ for (int ii = 0; ii < marginLeft; ii++) {
+ if (!*src++)
marginLeft = marginLeft + 1 - *src++;
- else
- marginLeft = 0;
-
- } while (marginLeft);
+ }
}
dY = _dsY1;
}
@@ -552,25 +545,40 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
marginRight = w2 - marginLeft - width;
}
- dst += (y * 320 + dX);
+ dst += (dY * 320 + dX);
uint8 * dstL = dst;
if (pageNum == 0 || pageNum == 1)
addDirtyRect(rX, rY, rW, rH);
while (dH--) {
- int16 xpos = (int16) marginLeft;
+ int16 xpos = (int16) marginLeft;
+
+ if (flags & 1) {
+ for (int i = 0; i < w2; i++) {
+ if (*src++ == 0) {
+ i += (*src - 1);
+ src += (*src - 1);
+ }
+ }
+ src--;
+ }
+ const uint8 *src2 = src;
if (xpos) {
do {
- while (*src && xpos) {
- src++;
+ uint8 val = (flags & 1) ? *(src - 1) : *src;
+ while (val && xpos) {
+ src += pixelStep;
xpos--;
+ val = (flags & 1) ? *(src - 1) : *src;
}
- if (!*src) {
- uint8 bt = *++src;
- src++;
+ val = (flags & 1) ? *(src - 1) : *src;
+ if (!val) {
+ src += pixelStep;
+ uint8 bt = (flags & 1) ? src[1] : src[0];
+ src += pixelStep;
xpos = xpos - bt;
}
} while (xpos > 0);
@@ -580,28 +588,36 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
xpos += width;
while (xpos > 0) {
- uint8 c = *src++;
+ uint8 c = *src;
+ uint8 m = (flags & 1) ? *(src - 1) : c;
+ src += pixelStep;
- if (c) {
+ if (m) {
drawShapeSetPixel(dst++, c);
xpos--;
} else {
- dst += *src;
- xpos -= *src++;
+ uint8 len = (flags & 1) ? src[1] : src[0];
+ dst += len;
+ xpos -= len;
+ src += pixelStep;
}
}
xpos += marginRight;
if (xpos) {
do {
- while (*src && xpos) {
- src++;
+ uint8 val = (flags & 1) ? *(src - 1) : *src;
+ while (val && xpos) {
+ src += pixelStep;
xpos--;
+ val = (flags & 1) ? *(src - 1) : *src;
}
- if (!*src) {
- uint8 bt = *++src;
- src++;
+ val = (flags & 1) ? *(src - 1) : *src;
+ if (!val) {
+ src += pixelStep;
+ uint8 bt = (flags & 1) ? src[1] : src[0];
+ src += pixelStep;
xpos = xpos - bt;
}
} while (xpos > 0);
@@ -609,6 +625,8 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
dstL += 320;
dst = dstL;
+ if (flags & 1)
+ src = src2 + 1;
}
}
}
@@ -707,7 +725,7 @@ void Screen_Eob::setGfxParameters(int x, int y, int col) {
_gfxCol = col;
}
-void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
+void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) {
int ymin = 0;
int ymax = _gfxMaxY[scale];
int xmin = -100;
@@ -735,20 +753,20 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
int16 *ptr7 = (int16*)&_dsTempPage[1500];
int16 *ptr8 = (int16*)&_dsTempPage[1800];
- if (numSteps > 150)
- numSteps = 150;
+ if (numElements > 150)
+ numElements = 150;
- for (int i = 0; i < numSteps; i++) {
+ for (int i = 0; i < numElements; i++) {
ptr2[i] = ptr3[i] = 0;
ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1);
ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio));
- ptr7[i] = _vm->_rnd.getRandomNumberRng(1024/stepSize, 2048/stepSize);
+ ptr7[i] = _vm->_rnd.getRandomNumberRng(1024 / stepSize, 2048 / stepSize);
ptr8[i] = scale << 8;
}
for (int l = 2; l;) {
if (l != 2) {
- for (int i = numSteps - 1; i >= 0; i--) {
+ for (int i = numElements - 1; i >= 0; i--) {
uint32 end = _system->getMillis() + 1;
int16 px = ((ptr2[i] >> 6) >> scale) + gx2;
int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
@@ -760,7 +778,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
updateScreen();
uint32 cur = _system->getMillis();
if (end > cur)
- _system->delayMillis(end - cur);
+ _system->delayMillis(end - cur);
}
}
}
@@ -768,7 +786,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
l = 0;
- for (int i = 0; i < numSteps; i++) {
+ for (int i = 0; i < numElements; i++) {
uint32 end = _system->getMillis() + 1;
if (ptr4[i] <= 0)
ptr4[i]++;
@@ -805,7 +823,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
updateScreen();
uint32 cur = _system->getMillis();
if (end > cur)
- _system->delayMillis(end - cur);
+ _system->delayMillis(end - cur);
}
}
} else {
@@ -817,12 +835,157 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize
showMouse();
}
+void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) {
+ int16 *xCoords = (int16*)_dsTempPage;
+ int16 *yCoords = (int16*)&_dsTempPage[300];
+ int16 *xMod = (int16*)&_dsTempPage[600];
+ int16 *yMod = (int16*)&_dsTempPage[900];
+ int16 *pixBackup = (int16*)&_dsTempPage[1200];
+ int16 *colTableStep = (int16*)&_dsTempPage[1500];
+ int16 *colTableIndex = (int16*)&_dsTempPage[1800];
+ int16 *pixDelay = (int16*)&_dsTempPage[2100];
+
+ hideMouse();
+ int cp = _curPage;
+
+ if (numElements > 150)
+ numElements = 150;
+
+ int cx = 88;
+ int cy = 48;
+ radius <<= 6;
+
+ for (int i = 0; i < numElements; i++) {
+ int16 v38 = _vm->_rnd.getRandomNumberRng(radius >> 2, radius);
+ int16 stepSum = 0;
+ int16 sqsum = 0;
+ while (sqsum < v38) {
+ stepSum += stepSize;
+ sqsum += stepSum;
+ }
+
+ switch (_vm->_rnd.getRandomNumber(255) & 3) {
+ case 0:
+ xCoords[i] = 32;
+ yCoords[i] = sqsum;
+ xMod[i] = stepSum;
+ yMod[i] = 0;
+ break;
+
+ case 1:
+ xCoords[i] = sqsum;
+ yCoords[i] = 32;
+ xMod[i] = 0;
+ yMod[i] = stepSum;
+ break;
+
+ case 2:
+ xCoords[i] = 32;
+ yCoords[i] = -sqsum;
+ xMod[i] = stepSum;
+ yMod[i] = 0;
+ break;
+
+ default:
+ xCoords[i] = -sqsum;
+ yCoords[i] = 32;
+ xMod[i] = 0;
+ yMod[i] = stepSum;
+ break;
+ }
+
+ if (_vm->_rnd.getRandomBit()) {
+ xMod[i] *= -1;
+ yMod[i] *= -1;
+ }
+
+ colTableStep[i] = _vm->_rnd.getRandomNumberRng(1024 / disorder, 2048 / disorder);
+ colTableIndex[i] = 0;
+ pixDelay[i] = _vm->_rnd.getRandomNumberRng(0, disorder >> 2);
+ }
+
+ int d = 0;
+ for (int i = 2; i; ) {
+ if (i != 2) {
+ uint32 nextDelay = _system->getMillis() + 1;
+ for (int ii = numElements - 1; ii >= 0; ii--) {
+ int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+ int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+ setPagePixel(0, px, py, pixBackup[ii]);
+
+ if (ii % 15 == 0) {
+ updateScreen();
+ uint32 cur = _system->getMillis();
+ if (nextDelay > cur)
+ _system->delayMillis(nextDelay - cur);
+ nextDelay += 1;
+ }
+ }
+ }
+
+ i = 0;
+ int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3);
+ uint32 nextDelay2 = _system->getMillis() + 1;
+
+ for (int ii = 0; ii < numElements; ii++) {
+ if (pixDelay[ii] == 0) {
+ if (xCoords[ii] > 0) {
+ xMod[ii] -= ((xMod[ii] > 0) ? stepSize : r);
+ } else {
+ xMod[ii] += ((xMod[ii] < 0) ? stepSize : r);
+ }
+
+ if (yCoords[ii] > 0) {
+ yMod[ii] -= ((yMod[ii] > 0) ? stepSize : r);
+ } else {
+ yMod[ii] += ((yMod[ii] < 0) ? stepSize : r);
+ }
+
+ xCoords[ii] += xMod[ii];
+ yCoords[ii] += yMod[ii];
+ colTableIndex[ii] += colTableStep[ii];
+
+ } else {
+ pixDelay[ii]--;
+ }
+
+ int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
+ int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
+
+ uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0;
+ pixBackup[ii] = getPagePixel(0, px, py);
+ uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1);
+ uint8 tc2 = colorTable[tblIndex];
+
+ if (tc2) {
+ i = 1;
+ if (tc1 == _gfxCol && !pixDelay[ii]) {
+ setPagePixel(0, px, py, tc2);
+ if (ii % 15 == 0) {
+ updateScreen();
+ uint32 cur = _system->getMillis();
+ if (nextDelay2 > cur)
+ _system->delayMillis(nextDelay2 - cur);
+ nextDelay2 += 1;
+ }
+ }
+ } else {
+ colTableStep[ii] = 0;
+ }
+ }
+ d++;
+ }
+
+ _curPage = cp;
+ showMouse();
+}
+
void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) {
uint8 *col = pal->getData();
for (bool loop = true; loop; ) {
loop = true;
- uint32 end = _system->getMillis() + 16;
+ uint32 end = _system->getMillis() + 1;
loop = false;
for (int ii = 0; ii < 3; ii++) {
diff --git a/engines/kyra/screen_eob.h b/engines/kyra/screen_eob.h
index 909a561462..d2d888107a 100644
--- a/engines/kyra/screen_eob.h
+++ b/engines/kyra/screen_eob.h
@@ -54,7 +54,7 @@ public:
void loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage);
void loadShapeSetBitmap(const char *file, int tempPage, int destPage);
- uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag = false);
+ uint8 *encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding = false);
void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd = -1, int flags = 0, ...);
const uint8 *scaleShape(const uint8 *shapeData, int blockDistance);
const uint8 *scaleShapeStep(const uint8 *shp);
@@ -65,7 +65,8 @@ public:
void setShapeFadeMode (uint8 i, bool b);
void setGfxParameters(int x, int y, int col);
- void drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
+ void drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize);
+ void drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize);
void fadeTextColor(Palette *pal, int color1, int fadeTextColor);
bool delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate);
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 2b86aa8d51..15f3c80b22 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -36,16 +36,16 @@ void EobCoreEngine::runLevelScript(int block, int flags) {
_inf->run(block, flags);
}
-void EobCoreEngine::setScriptFlag(int flag) {
- _inf->setFlag(flag);
+void EobCoreEngine::setScriptFlags(uint32 flags) {
+ _inf->setFlags(flags);
}
-void EobCoreEngine::clearScriptFlag(int flag) {
- _inf->clearFlag(flag);
+void EobCoreEngine::clearScriptFlags(uint32 flags) {
+ _inf->clearFlags(flags);
}
-bool EobCoreEngine::checkScriptFlag(int flag) {
- return _inf->checkFlag(flag);
+bool EobCoreEngine::checkScriptFlags(uint32 flags) {
+ return _inf->checkFlags(flags);
}
const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
@@ -198,16 +198,16 @@ void EobInfProcessor::run(int func, int sub) {
} while (!_abortScript && !_abortAfterSubroutine);
}
-void EobInfProcessor::setFlag(int flag) {
- _flagTable[17] |= flag;
+void EobInfProcessor::setFlags(uint32 flags) {
+ _flagTable[17] |= flags;
}
-void EobInfProcessor::clearFlag(int flag) {
- _flagTable[17] &= ~flag;
+void EobInfProcessor::clearFlags(uint32 flags) {
+ _flagTable[17] &= ~flags;
}
-bool EobInfProcessor::checkFlag(int flag) const {
- return (_flagTable[17] & flag) ? true : false;
+bool EobInfProcessor::checkFlags(uint32 flags) const {
+ return ((_flagTable[17] & flags) == flags) ? true : false;
}
bool EobInfProcessor::preventRest() const {
@@ -709,13 +709,13 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
while (cmd != -18) {
switch (cmd + 38) {
case 0:
- a = 0;
+ a = 1;
for (i = 0; i < 6; i++) {
if (!(_vm->_characters[i].flags & 1))
continue;
- if (_vm->_characters[i].effectFlags & 4)
+ if (_vm->_characters[i].effectFlags & 0x40)
continue;
- a = 1;
+ a = 0;
break;
}
_stack[_stackIndex++] = a;
@@ -806,7 +806,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
break;
case 25:
- _stack[_stackIndex++] = _vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags ? 1 : 0;
+ _stack[_stackIndex++] = (_vm->_levelBlockProperties[READ_LE_UINT16(pos)].flags & 1) ? 1 : 0;
pos += 2;
break;
@@ -944,13 +944,13 @@ int EobInfProcessor::oeob_eval_v2(int8 *data) {
break;
case 12:
- a = 0;
+ a = 1;
for (i = 0; i < 6; i++) {
if (!(_vm->_characters[i].flags & 1))
continue;
if (_vm->_characters[i].effectFlags & 0x40)
continue;
- a = 1;
+ a = 0;
break;
}
_stack[_stackIndex++] = a;
@@ -1415,7 +1415,7 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
switch (cmd) {
case -3:
- // eob1 outro
+ _vm->seq_xdeath();
_vm->_runFlag = false;
_vm->_playFinale = true;
_abortScript = 1;
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 71e53bc802..648d214017 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -42,9 +42,9 @@ public:
void loadData(const uint8 *data, uint32 dataSize);
void run(int func, int sub);
- void setFlag(int flag);
- void clearFlag(int flag);
- bool checkFlag(int flag) const;
+ void setFlags(uint32 flags);
+ void clearFlags(uint32 flags);
+ bool checkFlags(uint32 flags) const;
bool preventRest() const;
void loadState(Common::SeekableSubReadStreamEndian &in);
diff --git a/engines/kyra/sequences_eob1.cpp b/engines/kyra/sequences_eob1.cpp
index 8f360c071d..4c5bd17f02 100644
--- a/engines/kyra/sequences_eob1.cpp
+++ b/engines/kyra/sequences_eob1.cpp
@@ -104,43 +104,954 @@ int EobEngine::mainMenuLoop() {
}
void EobEngine::seq_playOpeningCredits() {
- static const char *cmpList[] = { "WESTWOOD.CMP", "AND.CMP", "SSI.CMP", "PRESENT.CMP", "DAND.CMP" };
- static const uint8 frameDelay[] = { 140, 50, 100, 50, 140 };
-
_allowSkip = true;
- _screen->loadPalette("WESTWOOD.COL", _screen->getPalette(0));
+ _screen->loadPalette(_introFilesOpening[5], _screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
- _screen->loadBitmap(cmpList[0], 5, 3, 0);
+ _screen->loadBitmap(_introFilesOpening[4], 5, 3, 0);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
_sound->playTrack(1);
- delay(frameDelay[0] * _tickLength);
+ delay(_introOpeningFrmDelay[0] * _tickLength);
- for (int i = 1; i < 5 && !shouldQuit() && !skipFlag(); i++) {
- _screen->loadBitmap(cmpList[i], 5, 3, 0);
- uint32 nextFrameTimer = _system->getMillis() + frameDelay[i] * _tickLength;
+ for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+ _screen->loadBitmap(_introFilesOpening[i], 5, 3, 0);
+ uint32 nextFrameTimer = _system->getMillis() + _introOpeningFrmDelay[i + 1] * _tickLength;
_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 2, 0);
delayUntil(nextFrameTimer);
}
- delay(50 * _tickLength);
_allowSkip = false;
}
void EobEngine::seq_playIntro() {
_allowSkip = true;
- //_sound->playTrack(2);
+ if (!shouldQuit() && !skipFlag()) {
+ _sound->playTrack(2);
+ _screen->loadBitmap("TITLE-V.CMP", 5, 3, 0);
+ _screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
+ delay(120 * _tickLength);
+ }
+
+ _screen->loadBitmap("TEXT.CMP", 3, 6, 0);
+
+ seq_tower();
+ seq_orb();
+ seq_waterdeepEntry();
+ seq_king();
+ seq_hands();
+ seq_waterdeepExit();
+ seq_tunnel();
+
+ whirlTransition();
+ _sound->haltTrack();
_allowSkip = false;
}
void EobEngine::seq_playFinale() {
- _allowSkip = true;
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ delete s;
+ snd_playSoundEffect(20);
+
+ _txt->resetPageBreakString();
+ _txt->setWaitButtonMode(1);
+ _txt->setupField(12, true);
+ gui_drawBox(0, 0, 176, 175, _color1_1, _color2_1, _bkgColor_1);
+ _txt->printDialogueText(51, _moreStrings[0]);
+
+ if (!checkScriptFlags(0x1ffe)) {
+ _screen->fadeToBlack();
+ return;
+ }
+
+ _txt->printDialogueText(_finBonusStrings[0]);
+ for (int i = 0; i < 6; i++) {
+ _txt->printDialogueText(_finBonusStrings[1]);
+ if (_characters[i].flags & 1)
+ _txt->printDialogueText(_characters[i].name);
+ }
+
+ uint32 password = 0;
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1))
+ continue;
- _allowSkip = false;
+ int len = strlen(_characters[i].name);
+ for (int ii = 0; ii < len; ii++) {
+ uint32 c = _characters[i].name[ii];
+ password += (c * c);
+ }
+ }
+
+ _txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
+ _screen->fadeToBlack();
+}
+
+void EobEngine::seq_tower() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ _screen->loadPalette(_introFilesTower[0], _screen->getPalette(0));
+ _screen->loadBitmap(_introFilesTower[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true);
+ _screen->copyPage(3, 4);
+ _screen->clearCurPage();
+
+ for (int i = 0; i < 200; i += 64)
+ _screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+ _screen->fillRect(0, 184, 319, 199, 12);
+ int cp = _screen->setCurPage(0);
+ whirlTransition();
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->setCurPage(cp);
+ _screen->clearCurPage();
+
+ for (int i = 0; i < 200; i += 64)
+ _screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
+
+ _screen->setCurPage(0);
+
+ for (int i = 0; i < 64 && !shouldQuit() && !skipFlag(); i += 2) {
+ uint32 end = _system->getMillis() + 2 * _tickLength;
+ _screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ if (!i)
+ _screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ for (int i = 0; i < 24 && !shouldQuit() && !skipFlag(); i += 2) {
+ uint32 end = _system->getMillis() + 2 * _tickLength;
+ _screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i += 2) {
+ uint32 end = _system->getMillis() + 2 * _tickLength;
+ _screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
+
+ if (i < 32) {
+ _screen->fillRect(128, 0, 255, i + 1, 12, 2);
+ _screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ _screen->fillRect(128, 0, 255, i + 1, 12, 2);
+ _screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
+ }
+
+ _screen->drawShape(2, shp, 128, i - 55, 0);
+ _screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(65 * _tickLength);
+ delete[] shp;
+}
+
+void EobEngine::seq_orb() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ uint8 *shp[5];
+ _screen->loadBitmap(_introFilesOrb[0], 5, 3, 0);
+ _screen->setCurPage(2);
+ shp[4] = _screen->encodeShape(0, 0, 20, 136, true);
+ _screen->loadBitmap(_introFilesOrb[1], 5, 3, 0);
+ shp[3] = _screen->encodeShape(16, 0, 16, 104, true);
+
+ _screen->fillRect(0, 0, 127, 103, 12);
+ for (int i = 1; i < 4; i++) {
+ copyBlurRegion(128, 0, 0, 0, 128, 104, i);
+ shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true);
+ }
+
+ _screen->fillRect(0, 0, 159, 135, 12);
+ _screen->setCurPage(0);
+ _screen->copyPage(3, 4);
+ _screen->clearCurPage();
+
+ _sound->playTrack(6);
+
+ for (int i = -1; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+ if (i >= 0)
+ _screen->drawShape(2, shp[i], 16, 16, 0);
+ _screen->drawShape(2, shp[4], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(40 * _tickLength);
+
+ _sound->playTrack(6);
+
+ for (int i = 3; i > -2 && !shouldQuit() && !skipFlag(); i--) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+ _screen->fillRect(16, 16, 143, 119, 12, 2);
+ if (i >= 0)
+ _screen->drawShape(2, shp[i], 16, 16, 0);
+ _screen->drawShape(2, shp[4], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ delay(40 * _tickLength);
+
+ for (int i = 0; i < 5; i++)
+ delete[] shp[i];
+}
+
+void EobEngine::seq_waterdeepEntry() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ uint8 *shp[4];
+ uint8 *shp2[31];
+ uint8 *shp3[3];
+
+ _screen->loadPalette(_introFilesWdEntry[0], _screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->loadBitmap(_introFilesWdEntry[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ shp[3] = _screen->encodeShape(0, 0, 20, 136, true);
+ for (int i = 1; i < 4; i++) {
+ copyBlurRegion(0, 0, 0, 0, 160, 136, i);
+ shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true);
+ }
+ _screen->setCurPage(0);
+
+ _screen->copyPage(3, 4);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _sound->playTrack(6);
+
+ for (int i = 0; i < 4 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+ _screen->drawShape(0, shp[i], 80, 24, 0);
+ delete[] shp[i];
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(50 * _tickLength);
+
+ _screen->setCurPage(2);
+ shp[0] = _screen->encodeShape(20, 0, 20, 136, true);
+ _screen->loadBitmap(_introFilesWdEntry[2], 5, 3, 0);
+ shp[1] = _screen->encodeShape(0, 0, 20, 136, true);
+ shp[2] = _screen->encodeShape(20, 0, 20, 136, true);
+ _screen->loadBitmap(_introFilesWdEntry[3], 5, 3, 0);
+
+ for (int i = 0; i < 31; i++)
+ shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+ for (int i = 0; i < 3; i++)
+ shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true);
+
+ _screen->copyPage(3, 4);
+
+ for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+ _screen->fillRect(0, 0, 159, 135, 12, 2);
+ _screen->drawShape(2, shp[i], 0, 0, 0);
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(4 * _tickLength);
+ _screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->updateScreen();
+ delay(4 * _tickLength);
+ _screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
+
+ int cx = 264;
+ int cy = 11;
+
+ for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+
+ _screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+ _screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ cx--;
+ cy++;
+
+ for (int ii = 0; ii < 5; ii++) {
+ int s = _rnd.getRandomNumber(255) % 31;
+ _screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+ }
+
+ if (!(_rnd.getRandomNumber(255) & 7))
+ _sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ for (int i = 0; i < 3; i++) {
+ delete[] shp[i];
+ delete[] shp3[i];
+ }
+
+ for (int i = 0; i < 31; i++)
+ delete[] shp2[i];
+}
+
+void EobEngine::seq_king() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ _screen->loadBitmap(_introFilesKing[0], 5, 3, 0);
+ _screen->copyPage(3, 4);
+
+ int x = 15;
+ int y = 14;
+ int w = 1;
+ int h = 1;
+
+ for (int i = 0; i < 10 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
+ if (x > 6)
+ x --;
+ if (y > 0)
+ y -= 2;
+ w += 3;
+ if (x + w > 34)
+ w = 34 - x;
+ h += 3;
+ if (y + h > 23)
+ h = 23 - y;
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ delay(25 * _tickLength);
+
+ uint8 *shp[4];
+ int16 dy[4];
+ int16 stepY[4];
+
+ static const uint8 advEncX[] = { 0, 6, 12, 19 };
+ static const uint8 advEncW[] = { 6, 6, 7, 6 };
+ static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
+
+ _screen->loadBitmap(_introFilesKing[1], 5, 3, 0);
+ _screen->setCurPage(2);
+ for (int i = 0; i < 4; i++) {
+ shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true);
+ dy[i] = 180 + ((_rnd.getRandomNumber(255) & 3) << 3);
+ stepY[i] = (i * 5) & 3;
+ }
+
+ _screen->copyPage(0, 4);
+
+ for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+ runloop = false;
+ uint32 end = _system->getMillis() + 2 * _tickLength;
+
+ for (int i = 0; i < 4; i++) {
+ if (dy[i] <= 82)
+ continue;
+ stepY[i] = (stepY[i] + 1) & 7;
+ dy[i] += modY[stepY[i]];
+
+ if (dy[i] < 82)
+ dy[i] = 82;
+
+ if (dy[i] < 180) {
+ _screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp[i], 0, dy[i], 0);
+ _screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
+ }
+
+ if (_rnd.getRandomNumber(255) & 3)
+ _sound->playTrack(7);
+
+ runloop = true;
+ }
+
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(70 * _tickLength);
+
+ for (int i = 0; i < 4; i++)
+ delete[] shp[i];
+}
+
+void EobEngine::seq_hands() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ _screen->setCurPage(2);
+ uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true);
+ uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true);
+ _screen->loadBitmap(_introFilesHands[0], 3, 5, 0);
+
+ _screen->fillRect(0, 160, 319, 199, 12, 0);
+ _screen->fillRect(0, 0, 191, 63, 157, 2);
+ _screen->drawShape(2, shp1, 0, 4, 0);
+ _screen->drawShape(2, shp2, 151, 4, 0);
+ boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
+ _screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->updateScreen();
+ delay(15 * _tickLength);
+ _sound->playTrack(11);
+
+ for (int i = -22; i <= 20 && !shouldQuit() && !skipFlag(); i += 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 167, 63, 157);
+ _screen->drawShape(2, shp1, i, 4, 0);
+ _screen->drawShape(2, shp1, 105 - i, 4, 0);
+ _screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _sound->playTrack(10);
+
+ delete[] shp1;
+ delete[] shp2;
+ delay(15 * _tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(17, 0, 11, 120, true);
+ shp2 = _screen->encodeShape(28, 112, 1, 31, true);
+ uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp1, 32, -80, 0);
+ _screen->drawShape(2, shp2, 40, -16, 0);
+ boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
+ delay(15 * _tickLength);
+
+ for (int i = -80; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp1, 32, i, 0);
+ _screen->drawShape(2, shp2, 40, i + 64, 0);
+ _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _sound->playTrack(12);
+ delay(5 * _tickLength);
+
+ for (int i = 0; i > -54 && !shouldQuit() && !skipFlag(); i -= 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 135, 63, 157);
+ _screen->drawShape(2, shp3, 12, 64 + i, 0);
+ _screen->drawShape(2, shp1, 32, i, 0);
+ _screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ delete[] shp1;
+ delete[] shp2;
+ delete[] shp3;
+ delay(15 * _tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(0, 0, 17, 136, true);
+ shp2 = _screen->encodeShape(0, 136, 9, 48, true);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 143, 95, 157);
+ _screen->drawShape(2, shp1, -56, -56, 0);
+ _screen->drawShape(2, shp2, 52, 49, 0);
+ boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
+ delay(15 * _tickLength);
+ _sound->playTrack(11);
+
+ for (int i = -56; i <= -8 && !shouldQuit() && !skipFlag(); i += 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 143, 95, 157);
+ _screen->drawShape(2, shp1, i, i, 0);
+ _screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
+ _screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _sound->playTrack(10);
+ delete[] shp1;
+ delete[] shp2;
+ delay(30 * _tickLength);
+
+ _screen->setCurPage(4);
+ shp1 = _screen->encodeShape(28, 0, 11, 40, true);
+ shp2 = _screen->encodeShape(28, 40, 10, 72, true);
+
+ _screen->setCurPage(2);
+ _screen->fillRect(0, 0, 87, 112, 157);
+ _screen->drawShape(2, shp2, 0, 90, 0);
+ boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
+ delay(15 * _tickLength);
+
+ int dy = 90;
+ for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 87, 112, 157);
+ _screen->drawShape(2, shp2, 0, dy, 0);
+ _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ dy -= 5;
+ }
+
+ _sound->playTrack(13);
+
+ for (int i = -40; i <= 0 && !shouldQuit() && !skipFlag(); i += 4) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->fillRect(0, 0, 87, 39, 157);
+ _screen->drawShape(2, shp1, 0, i, 0);
+ _screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ delete[] shp1;
+ delete[] shp2;
+ delay(48 * _tickLength);
+}
+
+void EobEngine::seq_waterdeepExit() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ uint8 *shp2[31];
+ uint8 *shp3[3];
+
+ _screen->loadBitmap(_introFilesWdExit[0], 5, 3, 0);
+ _screen->setCurPage(2);
+ for (int i = 0; i < 31; i++)
+ shp2[i] = _screen->encodeShape(_introWdEncodeX[i], 136 + (_introWdEncodeY[i] << 3), _introWdEncodeWH[i], _introWdEncodeWH[i] << 3, true);
+ for (int i = 0; i < 3; i++)
+ shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true);
+ uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true);
+ _screen->copyPage(3, 4);
+ _screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
+
+ int cx = 140;
+ int cy = 128;
+
+ for (int i = 0; i < 70 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 3 * _tickLength;
+ int fx = cx - 2;
+ if (fx < 160)
+ fx = 160;
+ int fy = cy - 2;
+ if (fy > 98)
+ fy = 98;
+
+ _screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
+ _screen->drawShape(4, shp1, 160, 104, 0);
+ _screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
+ cx++;
+ cy--;
+
+ for (int ii = 0; ii < 5; ii++) {
+ int s = _rnd.getRandomNumber(255) % 31;
+ _screen->drawShape(0, shp2[s], _introWdDsX[s] - 80, _introWdDsY[s] + 24, 0);
+ }
+
+ if (!(_rnd.getRandomNumber(255) & 7))
+ _sound->playTrack(_rnd.getRandomBit() ? 5 : 14);
+
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ for (int i = 0; i < 3; i++)
+ delete[] shp3[i];
+
+ for (int i = 0; i < 31; i++)
+ delete[] shp2[i];
+ delete[] shp1;
+
+ _screen->setCurPage(0);
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
+
+ _screen->loadPalette(_introFilesWdExit[1], _screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->loadBitmap(_introFilesWdExit[2], 3, 5, 0);
+ _screen->copyPage(5, 2);
+ whirlTransition();
+ delay(6 * _tickLength);
+
+ _screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+
+ cx = 0;
+ cy = 136;
+ int dy = 0;
+ for (int i = 0; i < 19 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
+ cy += 8;
+ dy += 8;
+ if (i == 6) {
+ cx = 160;
+ cy = 0;
+ }
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _sound->playTrack(3);
+ delay(60 * _tickLength);
+
+ for (int i = 0; i < 56 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ for (int i = 1; i < 48 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->loadBitmap(_introFilesWdExit[3], 3, 5, 0);
+ _screen->copyPage(5, 2);
+ delay(30 * _tickLength);
+ _screen->setCurPage(0);
+ _screen->fillRect(0, 16, 319, 31, 12);
+ _screen->fillRect(0, 136, 319, 199, 12);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->loadPalette(_introFilesWdExit[4], _screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
+ _screen->updateScreen();
+ delay(50 * _tickLength);
+}
+
+void EobEngine::seq_tunnel() {
+ if (shouldQuit() || skipFlag())
+ return;
+
+ _screen->setCurPage(4);
+ uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true);
+ uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true);
+ drawBlockObject(1, 4, shp2, 160, 0, 0);
+ drawBlockObject(1, 4, shp1, 0, 0, 0);
+ delete[] shp1;
+ delete[] shp2;
+
+ for (int i = 0; i < 3 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + 8 * _tickLength;
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _sound->playTrack(7);
+ _screen->updateScreen();
+ delayUntil(end);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _sound->playTrack(7);
+ end = _system->getMillis() + 8 * _tickLength;
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(18 * _tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(5 * _tickLength);
+ _screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(5 * _tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ for (int i = 0; i < 6; i++)
+ _screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(5 * _tickLength);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->loadBitmap(_introFilesTunnel[0], 5, 3, 0);
+ _screen->copyPage(3, 4);
+ _screen->updateScreen();
+ delay(40 * _tickLength);
+
+ _screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
+ _sound->playTrack(8);
+ _screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(16 * _tickLength);
+ _sound->playTrack(4);
+
+ for (int i = 0; i < 30 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ if (i == 0)
+ _screen->fillRect(0, 168, 319, 199, 12, 0);
+ _screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+
+ _sound->playTrack(9);
+
+ for (int i = 0; i < 6 && !shouldQuit() && !skipFlag(); i++) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(_introTvlX1[i] << 3, _introTvlY1[i], _introTvlX2[i] << 3, _introTvlY2[i], _introTvlW[i] << 3, _introTvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
+ for (int ii = 0; ii < 4 && !shouldQuit() && !skipFlag(); ii++) {
+ _screen->updateScreen();
+ delayUntil(end);
+ end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(80, 25 + (_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
+ }
+ }
+ _screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(40 * _tickLength);
+
+ _screen->loadBitmap(_introFilesTunnel[1], 5, 3, 0);
+ _screen->copyPage(3, 4);
+ _sound->playTrack(6);
+ _screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+ _screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+ _screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->setCurPage(0);
+ _screen->updateScreen();
+ delay(50 * _tickLength);
+}
+
+void EobEngine::seq_xdeath() {
+ uint8 *shapes1[5];
+ uint8 *shapes2;
+
+ _screen->loadShapeSetBitmap("XDEATH2", 5, 3);
+ for (int i = 0; i < 4; i++)
+ shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true);
+ _screen->loadShapeSetBitmap("XDEATH3", 5, 3);
+ shapes2 = _screen->encodeShape(22, 0, 16, 95, true);
+ _screen->loadEobBitmap("XDEATH1", 0, 5, 3, -1);
+ _screen->setCurPage(0);
+
+ for (int i = 0; i < 10; i++) {
+ if (i == 2)
+ snd_playSoundEffect(72);
+ else if (i == 4 || i == 6)
+ snd_playSoundEffect(54);
+ else
+ snd_playSoundEffect(34);
+
+ if (i < 6) {
+ _screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
+ } else {
+ snd_playSoundEffect(42);
+ _screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
+ }
+
+ _screen->updateScreen();
+ delay(4 * _tickLength);
+ }
+
+ const ScreenDim *dm = _screen->getScreenDim(5);
+ _screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
+
+ for (int i = 0; i < 19; i++) {
+ snd_playSoundEffect(119);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
+ _screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ delay(2 * _tickLength);
+ }
+
+ _screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
+
+ snd_playSoundEffect(5);
+ delay(60 * _tickLength);
+
+ for (int i = 0; i < 4; i++)
+ delete[] shapes1[i];
+ delete[] shapes2;
+}
+
+void EobEngine::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
+ const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
+
+ if (step == 1) {
+ while (h > 0) {
+ int dx = x2;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[i]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ dx = x2;
+ y2++;
+ ptr2 += 320;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, 0);
+ _screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
+ }
+ y2++;
+ ptr2 += 320;
+ h -= 2;
+ }
+ } else if (step == 2) {
+ while (h > 0) {
+ int dx = x2;
+ for (int i = 0; i < w; i += 2) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[i]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ dx = x2;
+ y2++;
+ ptr2 += 320;
+ for (int i = 0; i < w; i++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+
+ y2++;
+ ptr2 += 320;
+ h -= 2;
+ }
+ } else if (step == 3) {
+ for (int i = 0; i < h; i++) {
+ int dx = x2;
+ if ((i % 3) == 0) {
+ int ii = 0;
+ for (; ii < w - 3; ii += 3) {
+ _screen->setPagePixel(3, dx++, y2, ptr2[ii]);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ for (; ii < w; ii++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+ } else {
+ for (int ii = 0; ii < w; ii++)
+ _screen->setPagePixel(3, dx++, y2, 0);
+ }
+ y2++;
+ ptr2 += 320;
+ }
+ }
+}
+
+void EobEngine::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH) {
+ int originX2 = originX1 + originW;
+ int originY2 = originY1 + originH;
+ if (originY2 > 21)
+ originY2 = 21;
+
+ int w = 1;
+ int h = 1;
+ for (bool runloop = true; runloop && !shouldQuit() && !skipFlag(); ) {
+ uint32 end = _system->getMillis() + _tickLength;
+ _screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
+ if (originX1 < targetDestX)
+ _screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+ if (originY1 < targetDestY)
+ _screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+ if ((targetFinalX + targetFinalW) <= originX2)
+ _screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
+ if ((targetFinalY + targetFinalH) <= originY2)
+ _screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
+
+ if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
+ runloop = false;
+
+ int v = targetFinalX - targetDestX;
+ v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+ targetDestX += v;
+ v = targetFinalY - targetDestY;
+ v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
+ targetDestY += v;
+
+ if (w != targetFinalW)
+ w += 2;
+ if (w > targetFinalW)
+ w = targetFinalW;
+
+ if (h != targetFinalH)
+ h += 2;
+ if (h > targetFinalH)
+ h = targetFinalH;
+
+ if (++originX1 > targetFinalX)
+ originX1 = targetFinalX;
+
+ if (++originY1 > targetFinalY)
+ originY1 = targetFinalY;
+
+ if ((targetFinalX + targetFinalW) < originX2)
+ originX2--;
+
+ if ((targetFinalY + targetFinalH) < originY2)
+ originY2--;
+
+ _screen->updateScreen();
+ delayUntil(end);
+ }
+}
+
+void EobEngine::whirlTransition() {
+ for (int i = 0; i < 2; i++) {
+ for (int ii = 0; ii < 8; ii++) {
+ uint32 e = _system->getMillis() + 3;
+ if (ii & 1) {
+ for (int iii = i + ii; iii < 320; iii += 8)
+ _screen->drawClippedLine(iii, 0, iii, 199, 12);
+ } else {
+ for (int iii = i + ii; iii < 200; iii += 8)
+ _screen->drawClippedLine(0, iii, 319, iii, 12);
+ }
+ _screen->updateScreen();
+ uint32 c = _system->getMillis();
+ if (e > c)
+ _system->delayMillis(e - c);
+ }
+ }
}
} // End of namespace Kyra
diff --git a/engines/kyra/sequences_eob2.cpp b/engines/kyra/sequences_eob2.cpp
index bba5a7a220..395e94713c 100644
--- a/engines/kyra/sequences_eob2.cpp
+++ b/engines/kyra/sequences_eob2.cpp
@@ -120,7 +120,6 @@ int DarkMoonEngine::mainMenu() {
case 1:
// load game in progress
- //
menuChoice = -1;
break;
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index cb8ae51860..e4001b24d7 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -55,7 +55,7 @@ namespace Kyra {
void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
Common::String s = filename;
- if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath"))
+ if ((_flags.gameID == GI_EOB1) && (!scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath")))
s += "1";
_screen->loadShapeSetBitmap(s.c_str(), 3, 3);
@@ -272,10 +272,10 @@ void EobCoreEngine::updateAttackingMonsterFlags() {
}
if (m2->type == 7)
- _inf->setFlag(4);
+ setScriptFlags(4);
if (m2->type == 12)
- _inf->setFlag(0x800);
+ setScriptFlags(0x800);
}
const int8 *EobCoreEngine::getMonstersOnBlockPositions(uint16 block) {
@@ -791,9 +791,9 @@ void EobCoreEngine::turnFriendlyMonstersHostile() {
if (m) {
if (m->type == 7)
- _inf->setFlag(0x40000);
+ setScriptFlags(0x40000);
else if (m->type == 12)
- _inf->setFlag(0x8000000);
+ setScriptFlags(0x8000000);
}
}
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index b1ab606f5e..5995f8a5cd 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -535,6 +535,11 @@ void EobCoreEngine::initStaticResource() {
_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
_turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp);
_burningHandsDest = _staticres->loadRawData(kEobBaseBurningHandsDest, temp);
+ _coneOfColdDest1 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest1, temp);
+ _coneOfColdDest2 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest2, temp);
+ _coneOfColdDest3 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest3, temp);
+ _coneOfColdDest4 = (const int8*)_staticres->loadRawData(kEobBaseConeOfColdDest4, temp);
+ _coneOfColdGfxTbl = _staticres->loadRawData(kEobBaseConeOfColdGfxTbl, _coneOfColdGfxTblSize);
// Hard code the following strings, since EOB I doesn't have them in the original.
// EOB I doesn't have load and save menus, because there is only one single
@@ -1056,6 +1061,28 @@ void EobCoreEngine::initSpells() {
void EobEngine::initStaticResource() {
int temp;
_mainMenuStrings = _staticres->loadStrings(kEob1MainMenuStrings, temp);
+ _finBonusStrings = _staticres->loadStrings(kEob1BonusStrings, temp);
+
+ _introFilesOpening = _staticres->loadStrings(kEob1IntroFilesOpening, temp);
+ _introFilesTower = _staticres->loadStrings(kEob1IntroFilesTower, temp);
+ _introFilesOrb = _staticres->loadStrings(kEob1IntroFilesOrb, temp);
+ _introFilesWdEntry = _staticres->loadStrings(kEob1IntroFilesWdEntry, temp);
+ _introFilesKing = _staticres->loadStrings(kEob1IntroFilesKing, temp);
+ _introFilesHands = _staticres->loadStrings(kEob1IntroFilesHands, temp);
+ _introFilesWdExit = _staticres->loadStrings(kEob1IntroFilesWdExit, temp);
+ _introFilesTunnel = _staticres->loadStrings(kEob1IntroFilesTunnel, temp);
+ _introOpeningFrmDelay = _staticres->loadRawData(kEob1IntroOpeningFrmDelay, temp);
+ _introWdEncodeX = _staticres->loadRawData(kEob1IntroWdEncodeX, temp);
+ _introWdEncodeY = _staticres->loadRawData(kEob1IntroWdEncodeY, temp);
+ _introWdEncodeWH = _staticres->loadRawData(kEob1IntroWdEncodeWH, temp);
+ _introWdDsX = _staticres->loadRawDataBe16(kEob1IntroWdDsX, temp);
+ _introWdDsY = _staticres->loadRawData(kEob1IntroWdDsY, temp);
+ _introTvlX1 = _staticres->loadRawData(kEob1IntroTvlX1, temp);
+ _introTvlY1 = _staticres->loadRawData(kEob1IntroTvlY1, temp);
+ _introTvlX2 = _staticres->loadRawData(kEob1IntroTvlX2, temp);
+ _introTvlY2 = _staticres->loadRawData(kEob1IntroTvlY2, temp);
+ _introTvlW = _staticres->loadRawData(kEob1IntroTvlW, temp);
+ _introTvlH = _staticres->loadRawData(kEob1IntroTvlH, temp);
_doorShapeEncodeDefs = _staticres->loadRawData(kEob1DoorShapeDefs, temp);
_doorSwitchShapeEncodeDefs = _staticres->loadRawData(kEob1DoorSwitchShapeDefs, temp);
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 80858d1743..3641681f4b 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -646,7 +646,7 @@ void TextDisplayer_Eob::displayWaitButton() {
vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
vm()->_dialogueButtonYoffs = 0;
- SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+ SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
vm()->drawDialogueButtons();
if (!vm()->shouldQuit())
@@ -654,8 +654,9 @@ void TextDisplayer_Eob::displayWaitButton() {
while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
+ _screen->fillRect(vm()->_dialogueButtonPosX[0], vm()->_dialogueButtonPosY[0], vm()->_dialogueButtonPosX[0] + vm()->_dialogueButtonW - 1, vm()->_dialogueButtonPosY[0] + vm()->_dialogueButtonH - 1, vm()->_bkgColor_1);
vm()->_dialogueButtonW = 95;
- SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+ SWAP(vm()->_dialogueButtonLabelCol1, vm()->_dialogueButtonLabelCol2);
clearCurDim();
}