diff options
-rw-r--r-- | devtools/create_kyradat/create_kyradat.cpp | 80 | ||||
-rw-r--r-- | devtools/create_kyradat/create_kyradat.h | 28 | ||||
-rw-r--r-- | devtools/create_kyradat/games.cpp | 37 | ||||
-rw-r--r-- | devtools/create_kyradat/tables.cpp | 159 | ||||
-rw-r--r-- | dists/engine-data/kyra.dat | bin | 463146 -> 464892 bytes | |||
-rw-r--r-- | engines/kyra/chargen.cpp | 6 | ||||
-rw-r--r-- | engines/kyra/eob1.cpp | 42 | ||||
-rw-r--r-- | engines/kyra/eob1.h | 38 | ||||
-rw-r--r-- | engines/kyra/eob2.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/eobcommon.cpp | 68 | ||||
-rw-r--r-- | engines/kyra/eobcommon.h | 40 | ||||
-rw-r--r-- | engines/kyra/gui_eob.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/magic_eob.cpp | 145 | ||||
-rw-r--r-- | engines/kyra/resource.h | 28 | ||||
-rw-r--r-- | engines/kyra/scene_eob.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/screen_eob.cpp | 259 | ||||
-rw-r--r-- | engines/kyra/screen_eob.h | 5 | ||||
-rw-r--r-- | engines/kyra/script_eob.cpp | 38 | ||||
-rw-r--r-- | engines/kyra/script_eob.h | 6 | ||||
-rw-r--r-- | engines/kyra/sequences_eob1.cpp | 937 | ||||
-rw-r--r-- | engines/kyra/sequences_eob2.cpp | 1 | ||||
-rw-r--r-- | engines/kyra/sprites_eob.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/staticres_eob.cpp | 27 | ||||
-rw-r--r-- | engines/kyra/text_eob.cpp | 5 |
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 Binary files differindex 494a39591a..aa3d62b84d 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat 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(); } |