PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/engines/kyra/sequence/sequences_hof.cpp

http://github.com/scummvm/scummvm
C++ | 3524 lines | 2846 code | 633 blank | 45 comment | 658 complexity | 2cef18f99ad1cc7ddc8c44f8682322b4 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
  1. /* ScummVM - Graphic Adventure Engine
  2. *
  3. * ScummVM is the legal property of its developers, whose names
  4. * are too numerous to list here. Please refer to the COPYRIGHT
  5. * file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. #include "kyra/engine/kyra_hof.h"
  23. #include "kyra/graphics/screen_hof.h"
  24. #include "kyra/graphics/screen_lol.h"
  25. #include "kyra/resource/resource.h"
  26. #include "kyra/sound/sound.h"
  27. #include "kyra/sequence/sequences_hof.h"
  28. #include "kyra/engine/timer.h"
  29. #include "common/system.h"
  30. namespace Kyra {
  31. enum SequenceID {
  32. kSequenceNoLooping = -1,
  33. kSequenceVirgin = 0,
  34. kSequenceWestwood,
  35. kSequenceTitle,
  36. kSequenceOverview,
  37. kSequenceLibrary,
  38. kSequenceHand,
  39. kSequencePoint,
  40. kSequenceZanfaun,
  41. kSequenceFunters,
  42. kSequenceFerb,
  43. kSequenceFish,
  44. kSequenceFheep,
  45. kSequenceFarmer,
  46. kSequenceFuards,
  47. kSequenceFirates,
  48. kSequenceFrash,
  49. kSequenceHoFDemoVirgin,
  50. kSequenceHoFDemoWestwood,
  51. kSequenceHoFDemoTitle,
  52. kSequenceHoFDemoHill,
  53. kSequenceHoFDemoOuthome,
  54. kSequenceHoFDemoWharf,
  55. kSequenceHoFDemoDinob,
  56. kSequenceHoFDemoFisher,
  57. // The following enums remain active even if LoL is disabled
  58. kSequenceLoLDemoScene1,
  59. kSequenceLoLDemoText1,
  60. kSequenceLoLDemoScene2,
  61. kSequenceLoLDemoText2,
  62. kSequenceLoLDemoScene3,
  63. kSequenceLoLDemoText3,
  64. kSequenceLoLDemoScene4,
  65. kSequenceLoLDemoText4,
  66. kSequenceLoLDemoScene5,
  67. kSequenceLoLDemoText5,
  68. kSequenceLoLDemoScene6,
  69. kSequenceArraySize
  70. };
  71. enum NestedSequenceID {
  72. kNestedSequenceFiggle = 0,
  73. kNestedSequenceOver1,
  74. kNestedSequenceOver2,
  75. kNestedSequenceForest,
  76. kNestedSequenceDragon,
  77. kNestedSequenceDarm,
  78. kNestedSequenceLibrary2,
  79. kNestedSequenceLibrary3,
  80. kNestedSequenceMarco,
  81. kNestedSequenceHand1a,
  82. kNestedSequenceHand1b,
  83. kNestedSequenceHand1c,
  84. kNestedSequenceHand2,
  85. kNestedSequenceHand3,
  86. kNestedSequenceHand4,
  87. kNestedSequenceHoFDemoWharf2,
  88. kNestedSequenceHoFDemoDinob2,
  89. kNestedSequenceHoFDemoWater,
  90. kNestedSequenceHoFDemoBail,
  91. kNestedSequenceHoFDemoDig,
  92. kNestedSequenceArraySize
  93. };
  94. typedef int (SeqPlayer_HOF::*SeqProc)(WSAMovie_v2 *, int, int, int);
  95. struct SeqPlayerConfig {
  96. SeqPlayerConfig(const HoFSeqData *data, const SeqProc *callbacks, const SeqProc *nestedCallbacks) : seq(data->seq), seqProc(callbacks), numSeq(data->numSeq), nestedSeq(data->nestedSeq), nestedSeqProc(nestedCallbacks), numNestedSeq(data->numNestedSeq) {}
  97. const HoFSequence *seq;
  98. const SeqProc *seqProc;
  99. int numSeq;
  100. const HoFNestedSequence *nestedSeq;
  101. const SeqProc *nestedSeqProc;
  102. int numNestedSeq;
  103. };
  104. class SeqPlayer_HOF {
  105. public:
  106. SeqPlayer_HOF(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system, bool startupSaveLoadable = false);
  107. ~SeqPlayer_HOF();
  108. int play(SequenceID firstScene, SequenceID loopStartScene);
  109. void pause(bool toggle);
  110. static SeqPlayer_HOF *instance() { return _instance; }
  111. private:
  112. // Init
  113. void setupCallbacks();
  114. // Playback loop
  115. void runLoop();
  116. void playScenes();
  117. bool checkAbortPlayback();
  118. bool checkPlaybackStatus();
  119. bool _abortRequested;
  120. uint32 _pauseStart;
  121. // Sequence transitions
  122. void doTransition(int type);
  123. void nestedFrameAnimTransition(int srcPage, int dstPage, int delaytime, int steps, int x, int y, int w, int h, int openClose, int directionFlags);
  124. void nestedFrameFadeTransition(const char *cmpFile);
  125. // Animations
  126. void playAnimation(WSAMovie_v2 *wsaObj, int startFrame, int numFrames, int frameRate, int x, int y, const SeqProc callback, Palette *fadePal1, Palette *fadePal2, int fadeRate, bool restoreScreen);
  127. void playDialogueAnimation(uint16 strID, uint16 soundID, int textColor, int textPosX, int textPosY, int textWidth, WSAMovie_v2 *wsaObj, int animStartFrame, int animLastFrame, int animPosX, int animPosY);
  128. void startNestedAnimation(int animSlot, int sequenceID);
  129. void closeNestedAnimation(int animSlot);
  130. void unloadNestedAnimation(int animSlot);
  131. void doNestedFrameTransition(int transitionType, int animSlot);
  132. void updateAllNestedAnimations();
  133. bool updateNestedAnimation(int animSlot);
  134. struct AnimSlot {
  135. SeqProc callback;
  136. WSAMovie_v2 *movie;
  137. const FrameControl *control;
  138. int16 flags;
  139. uint16 startFrame;
  140. uint16 endFrame;
  141. uint16 frameDelay;
  142. uint32 nextFrame;
  143. uint16 currentFrame;
  144. uint16 lastFrame;
  145. uint16 x;
  146. uint16 y;
  147. uint16 fadeInTransitionType;
  148. uint16 fadeOutTransitionType;
  149. };
  150. AnimSlot _animSlots[8];
  151. bool _updateAnimations;
  152. uint32 _animDuration;
  153. int _animCurrentFrame;
  154. int _callbackCurrentFrame;
  155. // The only reason to declare these here (instead of just locally) is being able to increase them after pausing the Engine
  156. uint32 _specialAnimTimeOutTotal;
  157. uint32 _specialAnimFrameTimeOut;
  158. // Subtitles/Dialogue/Sound
  159. void playSoundEffect(uint16 id, int16 vol);
  160. void playSoundAndDisplaySubTitle(uint16 id);
  161. void printFadingText(uint16 strID, int x, int y, const uint8 *colorMap, uint8 textcolor);
  162. int displaySubTitle(uint16 strID, uint16 posX, uint16 posY, int duration, uint16 width);
  163. void updateSubTitles();
  164. char *preprocessString(const char *str, int width);
  165. void waitForSubTitlesTimeout();
  166. uint32 ticksTillSubTitlesTimeout();
  167. void resetAllTextSlots();
  168. void fadeOutMusic();
  169. struct TextSlot {
  170. uint16 strIndex;
  171. uint16 x;
  172. uint16 y;
  173. uint16 width;
  174. int32 duration;
  175. uint32 startTime;
  176. int16 textcolor;
  177. };
  178. TextSlot _textSlots[10];
  179. char *_tempString;
  180. uint8 _textColor[2];
  181. uint8 _textColorMap[16];
  182. int _textDuration[33];
  183. const char *const *_sequenceStrings;
  184. const char *const *_sequenceSoundList;
  185. int _sequenceSoundListSize;
  186. static const uint8 _textColorPresets[];
  187. // HOF credits
  188. void playHoFTalkieCredits();
  189. void displayHoFTalkieScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed, int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData = 0, const char *const *specialData = 0);
  190. bool _talkieFinaleExtraFlag;
  191. // HOF+LOL demo specific
  192. void updateDemoAdText(int bottom, int top);
  193. ActiveItemAnim _hofDemoActiveItemAnim[5];
  194. const HoFSeqItemAnimData *_hofDemoAnimData;
  195. uint32 _fisherAnimCurTime;
  196. int _scrollProgressCounter;
  197. uint8 *_hofDemoShapeData;
  198. uint8 *_hofDemoItemShapes[20];
  199. // Misc
  200. void delayTicks(uint32 ticks);
  201. void delayUntil(uint32 dest);
  202. void setCountDown(uint32 ticks);
  203. bool countDownRunning();
  204. uint32 _countDownRemainder;
  205. uint32 _countDownLastUpdate;
  206. enum SeqPlayerTargetInfo {
  207. kHoF = 0,
  208. kHoFDemo,
  209. kLoLDemo
  210. };
  211. SeqPlayerTargetInfo _target;
  212. int _firstScene, _loopStartScene, _curScene, _preventSkipBeforeScene, _lastScene;
  213. bool _startupSaveLoadable, _isFinale, _preventLooping;
  214. SeqPlayerConfig *_config;
  215. MainMenu *_menu;
  216. int _result;
  217. bool _abortPlayback;
  218. KyraEngine_v1 *_vm;
  219. Screen_v2 *_screen;
  220. // We might consider getting rid of Screen_HoF, since there are only 2 methods left in that class anyway
  221. Screen_HoF *_screenHoF;
  222. OSystem *_system;
  223. static SeqPlayer_HOF *_instance;
  224. private:
  225. // Sequence specific callback functions
  226. int cbHOF_westwood(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  227. int cbHOF_title(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  228. int cbHOF_overview(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  229. int cbHOF_library(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  230. int cbHOF_hand(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  231. int cbHOF_point(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  232. int cbHOF_zanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  233. int cbHOF_over1(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  234. int cbHOF_over2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  235. int cbHOF_forest(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  236. int cbHOF_dragon(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  237. int cbHOF_darm(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  238. int cbHOF_library2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  239. int cbHOF_marco(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  240. int cbHOF_hand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  241. int cbHOF_hand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  242. int cbHOF_hand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  243. int cbHOF_hand2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  244. int cbHOF_hand3(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  245. int cbHOF_funters(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  246. int cbHOF_ferb(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  247. int cbHOF_fish(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  248. int cbHOF_fheep(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  249. int cbHOF_farmer(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  250. int cbHOF_fuards(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  251. int cbHOF_firates(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  252. int cbHOF_frash(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  253. int cbHOF_figgle(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  254. int cbHOFDEMO_virgin(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  255. int cbHOFDEMO_westwood(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  256. int cbHOFDEMO_title(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  257. int cbHOFDEMO_hill(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  258. int cbHOFDEMO_outhome(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  259. int cbHOFDEMO_wharf(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  260. int cbHOFDEMO_dinob(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  261. int cbHOFDEMO_fisher(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  262. int cbHOFDEMO_wharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  263. int cbHOFDEMO_dinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  264. int cbHOFDEMO_water(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  265. int cbHOFDEMO_bail(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  266. int cbHOFDEMO_dig(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  267. #ifdef ENABLE_LOL
  268. int cbLOLDEMO_scene1(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  269. int cbLOLDEMO_scene2(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  270. int cbLOLDEMO_scene3(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  271. int cbLOLDEMO_scene4(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  272. int cbLOLDEMO_scene5(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  273. int cbLOLDEMO_text5(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  274. int cbLOLDEMO_scene6(WSAMovie_v2 *wsaObj, int x, int y, int frm);
  275. #endif // ENABLE_LOL
  276. };
  277. SeqPlayer_HOF *SeqPlayer_HOF::_instance = 0;
  278. SeqPlayer_HOF::SeqPlayer_HOF(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system, bool startupSaveLoadable) : _vm(vm), _screen(screen), _system(system), _startupSaveLoadable(startupSaveLoadable) {
  279. // We use a static pointer for pauseEngine functionality. Since we don't
  280. // ever need more than one SeqPlayer_HOF object at the same time we keep
  281. // this simple and just add an assert to detect typos, regressions, etc.
  282. assert(_instance == 0);
  283. memset(_animSlots, 0, sizeof(_animSlots));
  284. memset(_textSlots, 0, sizeof(_textSlots));
  285. memset(_hofDemoActiveItemAnim, 0, sizeof(_hofDemoActiveItemAnim));
  286. _screenHoF = _vm->game() == GI_KYRA2 ? (Screen_HoF*)screen : 0;
  287. _config = 0;
  288. _result = 0;
  289. _sequenceSoundList = 0;
  290. _hofDemoAnimData = 0;
  291. _hofDemoShapeData = 0;
  292. _isFinale = false;
  293. _preventLooping = false;
  294. _menu = 0;
  295. _abortRequested = false;
  296. _pauseStart = 0;
  297. _updateAnimations = false;
  298. _animDuration = 0;
  299. _animCurrentFrame = 0;
  300. _callbackCurrentFrame = 0;
  301. _abortPlayback = false;
  302. _curScene = 0;
  303. _preventSkipBeforeScene = -1;
  304. _lastScene = 0;
  305. _scrollProgressCounter = 0;
  306. _fisherAnimCurTime = 0;
  307. _tempString = new char[200];
  308. _countDownRemainder = 0;
  309. _countDownLastUpdate = 0;
  310. int tempSize = 0;
  311. _vm->resource()->unloadAllPakFiles();
  312. _vm->resource()->loadPakFile(StaticResource::staticDataFilename());
  313. const char *const *files = _vm->staticres()->loadStrings(k2SeqplayPakFiles, tempSize);
  314. _vm->resource()->loadFileList(files, tempSize);
  315. _sequenceStrings = _vm->staticres()->loadStrings(k2SeqplayStrings, tempSize);
  316. uint8 multiplier = (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98) ? 12 : 8;
  317. for (int i = 0; i < MIN(33, tempSize); i++)
  318. _textDuration[i] = (int)strlen(_sequenceStrings[i]) * multiplier;
  319. if (_sequenceSoundList) {
  320. for (int i = 0; i < _sequenceSoundListSize; i++) {
  321. if (_sequenceSoundList[i])
  322. delete[] _sequenceSoundList[i];
  323. }
  324. delete[] _sequenceSoundList;
  325. _sequenceSoundList = 0;
  326. }
  327. const char *const *seqSoundList = _vm->staticres()->loadStrings(k2SeqplaySfxFiles, _sequenceSoundListSize);
  328. // replace sequence talkie files with localized versions
  329. const char *const *tlkfiles = _vm->staticres()->loadStrings(k2SeqplayTlkFiles, tempSize);
  330. char **tmpSndLst = new char *[_sequenceSoundListSize];
  331. for (int i = 0; i < _sequenceSoundListSize; i++) {
  332. const int len = strlen(seqSoundList[i]);
  333. tmpSndLst[i] = new char[len + 1];
  334. tmpSndLst[i][0] = 0;
  335. if (tlkfiles && len > 1) {
  336. for (int ii = 0; ii < tempSize; ii++) {
  337. if (strlen(tlkfiles[ii]) > 1 && !scumm_stricmp(&seqSoundList[i][1], &tlkfiles[ii][1]))
  338. strcpy(tmpSndLst[i], tlkfiles[ii]);
  339. }
  340. }
  341. if (tmpSndLst[i][0] == 0)
  342. strcpy(tmpSndLst[i], seqSoundList[i]);
  343. }
  344. tlkfiles = seqSoundList = 0;
  345. _vm->staticres()->unloadId(k2SeqplayTlkFiles);
  346. _vm->staticres()->unloadId(k2SeqplaySfxFiles);
  347. _sequenceSoundList = tmpSndLst;
  348. if (_vm->gameFlags().platform == Common::kPlatformPC98)
  349. _vm->sound()->loadSoundFile("SOUND.DAT");
  350. _screen->loadFont(_screen->FID_GOLDFONT_FNT, "GOLDFONT.FNT");
  351. _screen->setFont(_vm->gameFlags().lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_GOLDFONT_FNT);
  352. if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) {
  353. if (_vm->game() == GI_KYRA2) {
  354. _hofDemoAnimData = _vm->staticres()->loadHoFSeqItemAnimData(k2SeqplayShapeAnimData, tempSize);
  355. uint8 *shp = _vm->resource()->fileData("ICONS.SHP", 0);
  356. uint32 outsize = READ_LE_UINT16(shp + 4);
  357. _hofDemoShapeData = new uint8[outsize];
  358. Screen::decodeFrame4(shp + 10, _hofDemoShapeData, outsize);
  359. for (int i = 0; i < 20; i++)
  360. _hofDemoItemShapes[i] = _screen->getPtrToShape(_hofDemoShapeData, i);
  361. delete[] shp;
  362. }
  363. } else {
  364. const MainMenu::StaticData data = {
  365. { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98], 0 },
  366. { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xD7, 0xD6 },
  367. { 0xD8, 0xDA, 0xD9, 0xD8 },
  368. (_vm->gameFlags().lang == Common::JA_JPN) ? Screen::FID_SJIS_FNT : Screen::FID_8_FNT, 240
  369. };
  370. _menu = new MainMenu(_vm);
  371. _menu->init(data, MainMenu::Animation());
  372. }
  373. _instance = this;
  374. }
  375. SeqPlayer_HOF::~SeqPlayer_HOF() {
  376. _instance = 0;
  377. if (_sequenceSoundList) {
  378. for (int i = 0; i < _sequenceSoundListSize; i++) {
  379. if (_sequenceSoundList[i])
  380. delete[] _sequenceSoundList[i];
  381. }
  382. delete[] _sequenceSoundList;
  383. _sequenceSoundList = NULL;
  384. }
  385. delete[] _tempString;
  386. delete[] _hofDemoShapeData;
  387. delete _menu;
  388. if (_vm->game() != GI_LOL)
  389. _screen->setFont(_vm->gameFlags().lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_8_FNT);
  390. }
  391. int SeqPlayer_HOF::play(SequenceID firstScene, SequenceID loopStartScene) {
  392. bool incompatibleData = false;
  393. AudioResourceSet soundSet = kMusicIntro;
  394. _firstScene = firstScene;
  395. _loopStartScene = loopStartScene;
  396. _preventLooping = false;
  397. _result = 0;
  398. if (firstScene >= kSequenceArraySize || firstScene < kSequenceVirgin || loopStartScene >= kSequenceArraySize || loopStartScene < kSequenceNoLooping) {
  399. return 0;
  400. } else if (firstScene >= kSequenceLoLDemoScene1) {
  401. #ifndef ENABLE_LOL
  402. error("SeqPlayer_HOF::play(): The Lands of Lore sub engine (including this non-interactive demo) has been disabled in this build");
  403. #endif
  404. incompatibleData = (_vm->game() != GI_LOL);
  405. _firstScene -= kSequenceLoLDemoScene1;
  406. if (loopStartScene != kSequenceNoLooping)
  407. _loopStartScene -= kSequenceLoLDemoScene1;
  408. _lastScene = kSequenceLoLDemoScene6 - kSequenceLoLDemoScene1;
  409. _target = kLoLDemo;
  410. _screen->_charWidth = 0;
  411. } else if (firstScene >= kSequenceHoFDemoVirgin) {
  412. incompatibleData = (_vm->game() != GI_KYRA2 || !_vm->gameFlags().isDemo || _vm->gameFlags().isTalkie);
  413. _firstScene -= kSequenceHoFDemoVirgin;
  414. if (loopStartScene != kSequenceNoLooping)
  415. _loopStartScene -= kSequenceHoFDemoVirgin;
  416. _lastScene = kSequenceHoFDemoFisher - kSequenceHoFDemoVirgin;
  417. _target = kHoFDemo;
  418. _screen->_charWidth = -2;
  419. } else {
  420. _isFinale = _preventLooping = firstScene > kSequenceZanfaun;
  421. incompatibleData = (_vm->game() != GI_KYRA2 || (_vm->gameFlags().isDemo && (!_vm->gameFlags().isTalkie || _isFinale)));
  422. _target = kHoF;
  423. _screen->_charWidth = -2;
  424. if (_isFinale) {
  425. soundSet = kMusicFinale;
  426. _lastScene = kSequenceFrash;
  427. } else {
  428. _lastScene = kSequenceZanfaun;
  429. }
  430. }
  431. if (incompatibleData)
  432. error("SeqPlayer_HOF::play(): Specified sequences do not match the available sequence data for this target");
  433. _vm->sound()->selectAudioResourceSet(soundSet);
  434. _vm->sound()->loadSoundFile(0);
  435. setupCallbacks();
  436. runLoop();
  437. return _result;
  438. }
  439. void SeqPlayer_HOF::pause(bool toggle) {
  440. if (toggle) {
  441. _pauseStart = _system->getMillis();
  442. } else {
  443. uint32 pausedTime = _system->getMillis() - _pauseStart;
  444. _pauseStart = 0;
  445. _countDownLastUpdate += pausedTime;
  446. _fisherAnimCurTime += pausedTime;
  447. _specialAnimTimeOutTotal += pausedTime;
  448. _specialAnimFrameTimeOut += pausedTime;
  449. for (int i = 0; i < 10; i++) {
  450. if (_textSlots[i].duration != -1)
  451. _textSlots[i].startTime += pausedTime;
  452. }
  453. for (int i = 0; i < 8; i++) {
  454. if (_animSlots[i].flags != -1)
  455. _animSlots[i].nextFrame += pausedTime;
  456. }
  457. }
  458. }
  459. void SeqPlayer_HOF::setupCallbacks() {
  460. #define SCB(x) &SeqPlayer_HOF::cbHOF_##x
  461. static const SeqProc seqCallbacksHoF[] = { 0, SCB(westwood), SCB(title), SCB(overview), SCB(library), SCB(hand), SCB(point), SCB(zanfaun), SCB(funters), SCB(ferb), SCB(fish), SCB(fheep), SCB(farmer), SCB(fuards), SCB(firates), SCB(frash) };
  462. static const SeqProc nestedSeqCallbacksHoF[] = { SCB(figgle), SCB(over1), SCB(over2), SCB(forest), SCB(dragon), SCB(darm), SCB(library2), SCB(library2), SCB(marco), SCB(hand1a), SCB(hand1b), SCB(hand1c), SCB(hand2), SCB(hand3), 0 };
  463. #undef SCB
  464. #define SCB(x) &SeqPlayer_HOF::cbHOFDEMO_##x
  465. static const SeqProc seqCallbacksHoFDemo[] = { SCB(virgin), SCB(westwood), SCB(title), SCB(hill), SCB(outhome), SCB(wharf), SCB(dinob), SCB(fisher) };
  466. static const SeqProc nestedSeqCallbacksHoFDemo[] = { SCB(wharf2), SCB(dinob2), SCB(water), SCB(bail), SCB(dig), 0 };
  467. #undef SCB
  468. #ifdef ENABLE_LOL
  469. #define SCB(x) &SeqPlayer_HOF::cbLOLDEMO_##x
  470. static const SeqProc seqCallbacksLoLDemo[] = { SCB(scene1), 0, SCB(scene2), 0, SCB(scene3), 0, SCB(scene4), 0, SCB(scene5), SCB(text5), SCB(scene6), 0 };
  471. #undef SCB
  472. #else
  473. static const SeqProc seqCallbacksLoLDemo[] = { 0 };
  474. #endif
  475. static const SeqProc nestedSeqCallbacksLoLDemo[] = { 0 };
  476. static const SeqProc *const seqCallbacks[] = { seqCallbacksHoF, seqCallbacksHoFDemo, seqCallbacksLoLDemo};
  477. static const SeqProc *const nestedSeqCallbacks[] = { nestedSeqCallbacksHoF, nestedSeqCallbacksHoFDemo, nestedSeqCallbacksLoLDemo};
  478. int tmpSize = 0;
  479. delete _config;
  480. _config = new SeqPlayerConfig(_vm->staticres()->loadHoFSequenceData(k2SeqplaySeqData, tmpSize), seqCallbacks[_target], nestedSeqCallbacks[_target]);
  481. }
  482. void SeqPlayer_HOF::runLoop() {
  483. memset(_animSlots, 0, sizeof(_animSlots));
  484. memset(_textSlots, 0, sizeof(_textSlots));
  485. memset(_hofDemoActiveItemAnim, 0, sizeof(_hofDemoActiveItemAnim));
  486. for (int i = 0; i < 8; ++i)
  487. _animSlots[i].flags = -1;
  488. _screen->clearPage(10);
  489. _screen->clearPage(12);
  490. _screen->hideMouse();
  491. int oldPage = _screen->setCurPage(2);
  492. for (int i = 0; i < 4; ++i)
  493. _screen->getPalette(i).clear();
  494. _updateAnimations = false;
  495. _animCurrentFrame = 0;
  496. _textColor[0] = _textColor[1] = 0;
  497. _curScene = _firstScene;
  498. do {
  499. playScenes();
  500. doTransition(0);
  501. resetAllTextSlots();
  502. fadeOutMusic();
  503. _firstScene = ((!_startupSaveLoadable || _preventLooping) && _curScene >= _loopStartScene) ? kSequenceNoLooping : _loopStartScene;
  504. } while (!_vm->shouldQuit() && _firstScene != kSequenceNoLooping);
  505. checkPlaybackStatus();
  506. for (int i = 0; i < 8; i++)
  507. unloadNestedAnimation(i);
  508. if (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie)
  509. _screen->fadeToBlack();
  510. else if (!_isFinale && !_startupSaveLoadable)
  511. _result = 1;
  512. if (!_result)
  513. delayTicks(75);
  514. _screen->setCurPage(oldPage);
  515. _screen->_charWidth = 0;
  516. _screen->showMouse();
  517. }
  518. void SeqPlayer_HOF::playScenes() {
  519. _vm->sound()->stopAllSoundEffects();
  520. _curScene = _firstScene;
  521. _screen->copyPalette(1, 0);
  522. WSAMovie_v2 anim(_vm);
  523. _abortRequested = false;
  524. _scrollProgressCounter = 0;
  525. while (!_vm->shouldQuit()) {
  526. if (checkAbortPlayback())
  527. if (checkPlaybackStatus())
  528. break;
  529. _callbackCurrentFrame = 0;
  530. if (_curScene > _lastScene)
  531. break;
  532. const Kyra::HoFSequence &sq = _config->seq[_curScene];
  533. if (sq.flags & 2) {
  534. _screen->loadBitmap(sq.cpsFile, 2, 2, &_screen->getPalette(0));
  535. _screen->setScreenPalette(_screen->getPalette(0));
  536. } else {
  537. _screen->setCurPage(2);
  538. _screen->clearPage(2);
  539. _screen->loadPalette("GOLDFONT.COL", _screen->getPalette(0));
  540. }
  541. if (_config->seqProc[_curScene] && !(_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie))
  542. (this->*_config->seqProc[_curScene])(0, 0, 0, -1);
  543. if (sq.flags & 1) {
  544. anim.open(sq.wsaFile, 0, &_screen->getPalette(0));
  545. if (!(sq.flags & 2))
  546. anim.displayFrame(0, 2, sq.xPos, sq.yPos, 0x4000, 0, 0);
  547. }
  548. if (sq.flags & 4) {
  549. int cp = _screen->setCurPage(2);
  550. Screen::FontId cf = _screen->setFont(_vm->gameFlags().lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_GOLDFONT_FNT);
  551. if (sq.stringIndex1 != -1)
  552. _screen->printText(_sequenceStrings[sq.stringIndex1], (320 - _screen->getTextWidth(_sequenceStrings[sq.stringIndex1])) / 2, 100 - _screen->getFontHeight(), 1, 0);
  553. if (sq.stringIndex2 != -1)
  554. _screen->printText(_sequenceStrings[sq.stringIndex2], (320 - _screen->getTextWidth(_sequenceStrings[sq.stringIndex2])) / 2, 100, 1, 0);
  555. _screen->setFont(cf);
  556. _screen->setCurPage(cp);
  557. }
  558. _screen->copyPage(2, 12);
  559. _screen->copyPage(0, 2);
  560. _screen->copyPage(2, 10);
  561. _screen->copyPage(12, 2);
  562. doTransition(sq.fadeInTransitionType);
  563. if (!(checkAbortPlayback() || _vm->shouldQuit() || _result)) {
  564. _screen->copyPage(2, 0);
  565. _screen->updateScreen();
  566. }
  567. if (sq.flags & 1) {
  568. playAnimation(&anim, sq.startFrame, sq.numFrames, sq.duration, sq.xPos, sq.yPos, _config->seqProc[_curScene], &_screen->getPalette(1), &_screen->getPalette(0), 30, 0);
  569. anim.close();
  570. } else {
  571. _animDuration = sq.duration;
  572. setCountDown(_animDuration);
  573. while (!checkAbortPlayback() && !_vm->shouldQuit() && (countDownRunning() || _updateAnimations)) {
  574. uint32 endFrame = (_system->getMillis() + _vm->tickLength()) & ~(_vm->tickLength() - 1);
  575. updateAllNestedAnimations();
  576. if (_config->seqProc[_curScene])
  577. (this->*_config->seqProc[_curScene])(0, 0, 0, 0);
  578. updateSubTitles();
  579. _screen->copyPage(2, 0);
  580. _screen->updateScreen();
  581. _screen->copyPage(12, 2);
  582. do {
  583. if (checkAbortPlayback())
  584. if (checkPlaybackStatus())
  585. break;
  586. } while (_system->getMillis() < endFrame);
  587. }
  588. }
  589. if (_config->seqProc[_curScene] && !(_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie))
  590. (this->*_config->seqProc[_curScene])(0, 0, 0, -2);
  591. uint32 textTimeOut = ticksTillSubTitlesTimeout();
  592. setCountDown(sq.timeout < textTimeOut ? textTimeOut : sq.timeout);
  593. while (!checkAbortPlayback() && !_vm->shouldQuit() && (countDownRunning() || _updateAnimations)) {
  594. updateAllNestedAnimations();
  595. _screen->copyPage(2, 0);
  596. _screen->updateScreen();
  597. _screen->copyPage(12, 2);
  598. }
  599. doTransition(sq.fadeOutTransitionType);
  600. _curScene++;
  601. }
  602. resetAllTextSlots();
  603. _vm->sound()->haltTrack();
  604. _vm->sound()->voiceStop();
  605. if ((!checkAbortPlayback() || _vm->shouldQuit()) && _vm->gameFlags().isDemo)
  606. _curScene = -1;
  607. }
  608. bool SeqPlayer_HOF::checkAbortPlayback() {
  609. Common::Event event;
  610. if (_vm->skipFlag()) {
  611. _abortRequested = true;
  612. _vm->resetSkipFlag();
  613. }
  614. if (_abortRequested)
  615. return true;
  616. while (_system->getEventManager()->pollEvent(event)) {
  617. switch (event.type) {
  618. case Common::EVENT_KEYDOWN:
  619. if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL)) {
  620. _abortRequested = true;
  621. _vm->quitGame();
  622. return true;
  623. } else if (event.kbd.keycode != Common::KEYCODE_ESCAPE && event.kbd.keycode != Common::KEYCODE_RETURN && event.kbd.keycode != Common::KEYCODE_SPACE) {
  624. continue;
  625. }
  626. // fall through
  627. case Common::EVENT_LBUTTONDOWN:
  628. case Common::EVENT_RBUTTONDOWN:
  629. case Common::EVENT_LBUTTONUP:
  630. case Common::EVENT_RBUTTONUP:
  631. _abortRequested = true;
  632. return true;
  633. default:
  634. break;
  635. }
  636. }
  637. return false;
  638. }
  639. bool SeqPlayer_HOF::checkPlaybackStatus() {
  640. _updateAnimations = false;
  641. if (_curScene <= _preventSkipBeforeScene || (_curScene == _loopStartScene && !_isFinale)) {
  642. _abortRequested = false;
  643. return false;
  644. }
  645. if (_loopStartScene == kSequenceNoLooping) {
  646. doTransition(0);
  647. fadeOutMusic();
  648. _abortPlayback = true;
  649. }
  650. return true;
  651. }
  652. void SeqPlayer_HOF::doTransition(int type) {
  653. for (int i = 0; i < 8; i++)
  654. closeNestedAnimation(i);
  655. switch (type) {
  656. case 0:
  657. _screen->fadeToBlack(36);
  658. _screen->getPalette(0).clear();
  659. _screen->getPalette(1).clear();
  660. break;
  661. case 1:
  662. playSoundAndDisplaySubTitle(_vm->_rnd.getRandomBit());
  663. _screen->getPalette(0).fill(0, 256, 0x3F);
  664. _screen->fadePalette(_screen->getPalette(0), 16);
  665. _screen->copyPalette(1, 0);
  666. break;
  667. case 3:
  668. _screen->copyPage(2, 0);
  669. _screen->fadePalette(_screen->getPalette(0), 16);
  670. _screen->copyPalette(1, 0);
  671. break;
  672. case 4:
  673. _screen->copyPage(2, 0);
  674. _screen->fadePalette(_screen->getPalette(0), 36);
  675. _screen->copyPalette(1, 0);
  676. break;
  677. case 5:
  678. _screen->copyPage(2, 0);
  679. break;
  680. case 6:
  681. // UNUSED
  682. // seq_loadBLD("library.bld");
  683. break;
  684. case 7:
  685. // UNUSED
  686. // seq_loadBLD("marco.bld");
  687. break;
  688. case 8:
  689. _screen->fadeToBlack(16);
  690. _screen->getPalette(0).clear();
  691. _screen->getPalette(1).clear();
  692. delayTicks(120);
  693. break;
  694. case 9: {
  695. Palette &pal = _screen->getPalette(0);
  696. for (int i = 0; i < 255; i++)
  697. pal.fill(i, 1, (pal[3 * i] + pal[3 * i + 1] + pal[3 * i + 2]) / 3);
  698. pal.fill(255, 1, 0x3F);
  699. _screen->fadePalette(pal, 64);
  700. _screen->copyPalette(1, 0);
  701. } break;
  702. default:
  703. break;
  704. }
  705. }
  706. void SeqPlayer_HOF::nestedFrameAnimTransition(int srcPage, int dstPage, int delaytime, int steps, int x, int y, int w, int h, int openClose, int directionFlags) {
  707. if (openClose) {
  708. for (int i = 1; i < steps; i++) {
  709. uint32 endtime = _system->getMillis() + delaytime * _vm->tickLength();
  710. int w2 = (((w * 256) / steps) * i) / 256;
  711. int h2 = (((h * 256) / steps) * i) / 256;
  712. int ym = (directionFlags & 2) ? (h - h2) : 0;
  713. int xm = (directionFlags & 1) ? (w - w2) : 0;
  714. _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0);
  715. _screen->copyPage(dstPage, 6);
  716. _screen->copyPage(dstPage, 0);
  717. _screen->updateScreen();
  718. _screen->copyPage(12, dstPage);
  719. delayUntil(endtime);
  720. }
  721. _screen->wsaFrameAnimationStep(0, 0, x, y, w, h, w, h, srcPage, dstPage, 0);
  722. _screen->copyPage(dstPage, 6);
  723. _screen->copyPage(dstPage, 0);
  724. _screen->updateScreen();
  725. } else {
  726. _screen->copyPage(12, dstPage);
  727. for (int i = steps; i; i--) {
  728. uint32 endtime = _system->getMillis() + delaytime * _vm->tickLength();
  729. int w2 = (((w * 256) / steps) * i) / 256;
  730. int h2 = (((h * 256) / steps) * i) / 256;
  731. int ym = (directionFlags & 2) ? (h - h2) : 0;
  732. int xm = (directionFlags & 1) ? (w - w2) : 0;
  733. _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0);
  734. _screen->copyPage(dstPage, 6);
  735. _screen->copyPage(dstPage, 0);
  736. _screen->updateScreen();
  737. _screen->copyPage(12, dstPage);
  738. delayUntil(endtime);
  739. }
  740. }
  741. }
  742. void SeqPlayer_HOF::nestedFrameFadeTransition(const char *cmpFile) {
  743. _screen->copyPage(10, 2);
  744. _screen->copyPage(4, 10);
  745. _screen->clearPage(6);
  746. _screen->loadBitmap(cmpFile, 6, 6, 0);
  747. _screen->copyPage(12, 4);
  748. for (int i = 0; i < 3; i++) {
  749. uint32 endtime = _system->getMillis() + 4 * _vm->tickLength();
  750. assert(_screenHoF);
  751. _screenHoF->cmpFadeFrameStep(4, 320, 200, 0, 0, 2, 320, 200, 0, 0, 320, 200, 6);
  752. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  753. _screen->updateScreen();
  754. delayUntil(endtime);
  755. }
  756. _screen->copyPage(4, 0);
  757. _screen->updateScreen();
  758. _screen->copyPage(4, 2);
  759. _screen->copyPage(4, 6);
  760. _screen->copyPage(10, 4);
  761. }
  762. void SeqPlayer_HOF::playAnimation(WSAMovie_v2 *wsaObj, int startFrame, int lastFrame, int frameRate, int x, int y, const SeqProc callback, Palette *fadePal1, Palette *fadePal2, int fadeRate, bool restoreScreen) {
  763. bool finished = false;
  764. uint32 startTime = _system->getMillis();
  765. int origW = wsaObj ? wsaObj->width() : 0;
  766. int origH = wsaObj ? wsaObj->height() : 0;
  767. int drwX = x;
  768. int drwY = y;
  769. int drwW = origW;
  770. int drwH = origH;
  771. _animDuration = frameRate;
  772. if (wsaObj) {
  773. if (x < 0) {
  774. drwW += x;
  775. drwX = 0;
  776. }
  777. if (y < 0) {
  778. drwH += y;
  779. drwY = 0;
  780. }
  781. if (x + origW > 319)
  782. origW = 320 - x;
  783. if (y + origH > 199)
  784. origW = 200 - y;
  785. }
  786. int8 frameStep = (startFrame > lastFrame) ? -1 : 1;
  787. _animCurrentFrame = startFrame;
  788. while (!_vm->shouldQuit() && !finished) {
  789. if (checkAbortPlayback())
  790. if (checkPlaybackStatus())
  791. break;
  792. setCountDown(_animDuration);
  793. if (wsaObj || callback)
  794. _screen->copyPage(12, 2);
  795. int frameIndex = _animCurrentFrame;
  796. if (wsaObj)
  797. frameIndex %= wsaObj->frames();
  798. if (callback)
  799. (this->*callback)(wsaObj, x, y, frameIndex);
  800. if (wsaObj)
  801. wsaObj->displayFrame(frameIndex, 2, x, y, 0, 0, 0);
  802. _screen->copyPage(2, 12);
  803. updateAllNestedAnimations();
  804. updateSubTitles();
  805. if ((wsaObj || callback) && (!(checkAbortPlayback() || _vm->shouldQuit() || _result))) {
  806. _screen->copyPage(2, 0);
  807. _screen->updateScreen();
  808. }
  809. while (!_vm->shouldQuit()) {
  810. if (checkAbortPlayback())
  811. if (checkPlaybackStatus())
  812. break;
  813. if (fadePal1 && fadePal2) {
  814. if (!_screen->timedPaletteFadeStep(fadePal1->getData(), fadePal2->getData(), _system->getMillis() - startTime, fadeRate * _vm->tickLength()) && !wsaObj)
  815. break;
  816. }
  817. if ((wsaObj || callback) && (!(checkAbortPlayback() || _vm->shouldQuit() || _result))) {
  818. _screen->copyPage(2, 0);
  819. _screen->updateScreen();
  820. }
  821. updateSubTitles();
  822. if (!countDownRunning())
  823. break;
  824. }
  825. if (wsaObj) {
  826. _animCurrentFrame += frameStep;
  827. if ((frameStep > 0 && _animCurrentFrame >= lastFrame) || (frameStep < 0 && _animCurrentFrame < lastFrame))
  828. finished = true;
  829. }
  830. if (restoreScreen && (wsaObj || callback)) {
  831. _screen->copyPage(12, 2);
  832. _screen->copyRegion(drwX, drwY, drwX, drwY, drwW, drwH, 2, 0, Screen::CR_NO_P_CHECK);
  833. _screen->updateScreen();
  834. }
  835. }
  836. }
  837. void SeqPlayer_HOF::playDialogueAnimation(uint16 strID, uint16 soundID, int textColor, int textPosX, int textPosY, int textWidth, WSAMovie_v2 *wsaObj, int animStartFrame, int animLastFrame, int animPosX, int animPosY) {
  838. int dur = int(strlen(_sequenceStrings[strID])) * (_vm->gameFlags().isTalkie ? 7 : 15);
  839. if (_vm->textEnabled()) {
  840. int slot = displaySubTitle(strID, textPosX, textPosY, dur, textWidth);
  841. if (slot >= 0)
  842. _textSlots[slot].textcolor = textColor;
  843. }
  844. _specialAnimTimeOutTotal = _system->getMillis() + dur * _vm->tickLength();
  845. int curframe = animStartFrame;
  846. if (soundID && _vm->speechEnabled()) {
  847. while (_vm->sound()->voiceIsPlaying() && !_abortPlayback)
  848. delayTicks(1);
  849. playSoundAndDisplaySubTitle(soundID);
  850. }
  851. while (_system->getMillis() < _specialAnimTimeOutTotal && !_abortPlayback) {
  852. if (animLastFrame < 0) {
  853. int t = ABS(animLastFrame);
  854. if (t < curframe)
  855. curframe = t;
  856. }
  857. if (ABS(animLastFrame) < curframe)
  858. curframe = animStartFrame;
  859. _specialAnimFrameTimeOut = _system->getMillis() + _animDuration * _vm->tickLength();
  860. setCountDown(_animDuration);
  861. if (wsaObj)
  862. wsaObj->displayFrame(curframe % wsaObj->frames(), 2, animPosX, animPosY, 0, 0, 0);
  863. _screen->copyPage(2, 12);
  864. updateSubTitles();
  865. delayUntil(MIN(_specialAnimFrameTimeOut, _specialAnimTimeOutTotal));
  866. if (_vm->speechEnabled() && !_vm->textEnabled() && !_vm->snd_voiceIsPlaying())
  867. break;
  868. if (checkAbortPlayback())
  869. if (checkPlaybackStatus())
  870. break;
  871. _screen->copyPage(2, 0);
  872. _screen->updateScreen();
  873. curframe++;
  874. }
  875. if (_abortPlayback)
  876. _vm->sound()->voiceStop();
  877. if (ABS(animLastFrame) < curframe)
  878. curframe = ABS(animLastFrame);
  879. if (curframe == animStartFrame)
  880. curframe++;
  881. _animCurrentFrame = curframe;
  882. }
  883. void SeqPlayer_HOF::startNestedAnimation(int animSlot, int sequenceID) {
  884. if (_animSlots[animSlot].flags != -1)
  885. return;
  886. if (_target == kLoLDemo) {
  887. return;
  888. } else if (_target == kHoFDemo) {
  889. assert(sequenceID >= kNestedSequenceHoFDemoWharf2);
  890. sequenceID -= kNestedSequenceHoFDemoWharf2;
  891. }
  892. HoFNestedSequence s = _config->nestedSeq[sequenceID];
  893. if (!_animSlots[animSlot].movie) {
  894. _animSlots[animSlot].movie = new WSAMovie_v2(_vm);
  895. assert(_animSlots[animSlot].movie);
  896. }
  897. _animSlots[animSlot].movie->close();
  898. _animSlots[animSlot].movie->open(s.wsaFile, 0, 0);
  899. if (!_animSlots[animSlot].movie->opened()) {
  900. delete _animSlots[animSlot].movie;
  901. _animSlots[animSlot].movie = 0;
  902. return;
  903. }
  904. _animSlots[animSlot].endFrame = s.endFrame;
  905. _animSlots[animSlot].startFrame = _animSlots[animSlot].currentFrame = s.startframe;
  906. _animSlots[animSlot].frameDelay = s.frameDelay;
  907. _animSlots[animSlot].callback = _config->nestedSeqProc[sequenceID];
  908. _animSlots[animSlot].control = s.wsaControl;
  909. _animSlots[animSlot].flags = s.flags | 1;
  910. _animSlots[animSlot].x = s.x;
  911. _animSlots[animSlot].y = s.y;
  912. _animSlots[animSlot].fadeInTransitionType = s.fadeInTransitionType;
  913. _animSlots[animSlot].fadeOutTransitionType = s.fadeOutTransitionType;
  914. _animSlots[animSlot].lastFrame = 0xFFFF;
  915. doNestedFrameTransition(s.fadeInTransitionType, animSlot);
  916. if (!s.fadeInTransitionType)
  917. updateNestedAnimation(animSlot);
  918. _animSlots[animSlot].nextFrame = _system->getMillis() & ~(_vm->tickLength() - 1);
  919. }
  920. void SeqPlayer_HOF::closeNestedAnimation(int animSlot) {
  921. if (_animSlots[animSlot].flags == -1)
  922. return;
  923. _animSlots[animSlot].flags = -1;
  924. doNestedFrameTransition(_animSlots[animSlot].fadeOutTransitionType, animSlot);
  925. _animSlots[animSlot].movie->close();
  926. }
  927. void SeqPlayer_HOF::unloadNestedAnimation(int animSlot) {
  928. if (_animSlots[animSlot].movie) {
  929. _animSlots[animSlot].movie->close();
  930. delete _animSlots[animSlot].movie;
  931. _animSlots[animSlot].movie = 0;
  932. }
  933. }
  934. void SeqPlayer_HOF::doNestedFrameTransition(int transitionType, int animSlot) {
  935. int xa = 0, ya = 0;
  936. transitionType--;
  937. if (!_animSlots[animSlot].movie || _abortPlayback || _vm->shouldQuit())
  938. return;
  939. switch (transitionType) {
  940. case 0:
  941. xa = -_animSlots[animSlot].movie->xAdd();
  942. ya = -_animSlots[animSlot].movie->yAdd();
  943. _animSlots[animSlot].movie->displayFrame(0, 8, xa, ya, 0, 0, 0);
  944. nestedFrameAnimTransition(8, 2, 7, 8, _animSlots[animSlot].movie->xAdd(), _animSlots[animSlot].movie->yAdd(),
  945. _animSlots[animSlot].movie->width(), _animSlots[animSlot].movie->height(), 1, 2);
  946. break;
  947. case 1:
  948. xa = -_animSlots[animSlot].movie->xAdd();
  949. ya = -_animSlots[animSlot].movie->yAdd();
  950. _animSlots[animSlot].movie->displayFrame(0, 8, xa, ya, 0, 0, 0);
  951. nestedFrameAnimTransition(8, 2, 7, 8, _animSlots[animSlot].movie->xAdd(), _animSlots[animSlot].movie->yAdd(),
  952. _animSlots[animSlot].movie->width(), _animSlots[animSlot].movie->height(), 1, 1);
  953. break;
  954. case 2:
  955. waitForSubTitlesTimeout();
  956. xa = -_animSlots[animSlot].movie->xAdd();
  957. ya = -_animSlots[animSlot].movie->yAdd();
  958. _animSlots[animSlot].movie->displayFrame(21, 8, xa, ya, 0, 0, 0);
  959. nestedFrameAnimTransition(8, 2, 7, 8, _animSlots[animSlot].movie->xAdd(), _animSlots[animSlot].movie->yAdd(),
  960. _animSlots[animSlot].movie->width(), _animSlots[animSlot].movie->height(), 0, 2);
  961. break;
  962. case 3:
  963. _screen->copyPage(2, 10);
  964. _animSlots[animSlot].movie->displayFrame(0, 2, 0, 0, 0, 0, 0);
  965. _screen->copyPage(2, 12);
  966. nestedFrameFadeTransition("scene2.cmp");
  967. break;
  968. case 4:
  969. _screen->copyPage(2, 10);
  970. _animSlots[animSlot].movie->displayFrame(0, 2, 0, 0, 0, 0, 0);
  971. _screen->copyPage(2, 12);
  972. nestedFrameFadeTransition("scene3.cmp");
  973. break;
  974. default:
  975. break;
  976. }
  977. }
  978. void SeqPlayer_HOF::updateAllNestedAnimations() {
  979. for (int i = 0; i < 8; i++) {
  980. if (_animSlots[i].flags != -1) {
  981. if (updateNestedAnimation(i))
  982. closeNestedAnimation(i);
  983. }
  984. }
  985. }
  986. bool SeqPlayer_HOF::updateNestedAnimation(int animSlot) {
  987. uint16 currentFrame = _animSlots[animSlot].currentFrame;
  988. uint32 curTick = _system->getMillis() & ~(_vm->tickLength() - 1);
  989. if (_animSlots[animSlot].callback && currentFrame != _animSlots[animSlot].lastFrame) {
  990. _animSlots[animSlot].lastFrame = currentFrame;
  991. currentFrame = (this->*_animSlots[animSlot].callback)(_animSlots[animSlot].movie, _animSlots[animSlot].x, _animSlots[animSlot].y, currentFrame);
  992. }
  993. if (_animSlots[animSlot].movie) {
  994. if (_animSlots[animSlot].flags & 0x20) {
  995. _animSlots[animSlot].movie->displayFrame(_animSlots[animSlot].control[currentFrame].index, 2, _animSlots[animSlot].x, _animSlots[animSlot].y, 0x4000, 0, 0);
  996. _animSlots[animSlot].frameDelay = _animSlots[animSlot].control[currentFrame].delay;
  997. } else {
  998. _animSlots[animSlot].movie->displayFrame(currentFrame % _animSlots[animSlot].movie->frames(), 2, _animSlots[animSlot].x, _animSlots[animSlot].y, 0x4000, 0, 0);
  999. }
  1000. }
  1001. if (_animSlots[animSlot].flags & 0x10) {
  1002. currentFrame = (curTick - _animSlots[animSlot].nextFrame) / (_animSlots[animSlot].frameDelay * _vm->tickLength());
  1003. } else {
  1004. int diff = (curTick - _animSlots[animSlot].nextFrame) / (_animSlots[animSlot].frameDelay * _vm->tickLength());
  1005. if (diff > 0) {
  1006. currentFrame++;
  1007. if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)
  1008. _animSlots[animSlot].nextFrame += ((curTick - _animSlots[animSlot].nextFrame) * 2 / 3);
  1009. else
  1010. _animSlots[animSlot].nextFrame = curTick;
  1011. }
  1012. }
  1013. bool res = false;
  1014. if (currentFrame >= _animSlots[animSlot].endFrame) {
  1015. int sw = ((_animSlots[animSlot].flags & 0x1E) - 2);
  1016. switch (sw) {
  1017. case 0:
  1018. res = true;
  1019. currentFrame = _animSlots[animSlot].endFrame;
  1020. _screen->copyPage(2, 12);
  1021. break;
  1022. case 6:
  1023. case 8:
  1024. currentFrame = _animSlots[animSlot].endFrame - 1;
  1025. break;
  1026. case 2:
  1027. case 10:
  1028. currentFrame = _animSlots[animSlot].startFrame;
  1029. break;
  1030. default:
  1031. currentFrame = _animSlots[animSlot].endFrame - 1;
  1032. res = true;
  1033. }
  1034. }
  1035. _animSlots[animSlot].currentFrame = currentFrame;
  1036. return res;
  1037. }
  1038. void SeqPlayer_HOF::playSoundEffect(uint16 id, int16 vol) {
  1039. assert(id < _sequenceSoundListSize);
  1040. _vm->sound()->voicePlay(_sequenceSoundList[id], 0, vol);
  1041. }
  1042. void SeqPlayer_HOF::playSoundAndDisplaySubTitle(uint16 id) {
  1043. assert(id < _sequenceSoundListSize);
  1044. if (id < 12 && !_vm->gameFlags().isDemo && _vm->textEnabled())
  1045. displaySubTitle(id, 160, 168, _textDuration[id], 160);
  1046. _vm->sound()->voicePlay(_sequenceSoundList[id], 0);
  1047. }
  1048. void SeqPlayer_HOF::printFadingText(uint16 strID, int x, int y, const uint8 *colorMap, uint8 textcolor) {
  1049. uint8 cmap[16];
  1050. if (checkAbortPlayback())
  1051. checkPlaybackStatus();
  1052. if (_abortPlayback || _abortRequested || _vm->shouldQuit() || _result)
  1053. return;
  1054. Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
  1055. _screen->getPalette(0).fill(254, 2, 63);
  1056. _screen->setPaletteIndex(252, 63, 32, 48);
  1057. cmap[0] = colorMap[0];
  1058. cmap[1] = 253;
  1059. memcpy(&cmap[2], &colorMap[2], 14);
  1060. uint8 col0 = _textColor[0];
  1061. _textColor[0] = 253;
  1062. _screen->setTextColorMap(cmap);
  1063. resetAllTextSlots();
  1064. displaySubTitle(strID, x, y, 128, 120);
  1065. updateSubTitles();
  1066. _screen->copyPage(2, 0);
  1067. _screen->updateScreen();
  1068. _screen->getPalette(0).copy(_screen->getPalette(0), textcolor, 1, 253);
  1069. _screen->fadePalette(_screen->getPalette(0), 24);
  1070. _textColor[0] = textcolor;
  1071. _screen->setTextColorMap(colorMap);
  1072. resetAllTextSlots();
  1073. displaySubTitle(strID, x, y, 128, 120);
  1074. updateSubTitles();
  1075. _screen->copyPage(2, 0);
  1076. _screen->updateScreen();
  1077. _screen->getPalette(0).fill(253, 1, 0);
  1078. _screen->fadePalette(_screen->getPalette(0), 1);
  1079. _screen->copyPage(2, 12);
  1080. resetAllTextSlots();
  1081. _textColor[0] = col0;
  1082. _screen->setFont(of);
  1083. }
  1084. int SeqPlayer_HOF::displaySubTitle(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width) {
  1085. for (int i = 0; i < 10; i++) {
  1086. if (_textSlots[i].duration != -1) {
  1087. if (i < 9)
  1088. continue;
  1089. else
  1090. return -1;
  1091. }
  1092. _textSlots[i].strIndex = strIndex;
  1093. _textSlots[i].x = posX;
  1094. _textSlots[i].y = posY;
  1095. _textSlots[i].duration = duration * _vm->tickLength();
  1096. _textSlots[i].width = width;
  1097. _textSlots[i].startTime = _system->getMillis();
  1098. _textSlots[i].textcolor = -1;
  1099. return i;
  1100. }
  1101. return -1;
  1102. }
  1103. void SeqPlayer_HOF::updateSubTitles() {
  1104. int curPage = _screen->setCurPage(2);
  1105. char outputStr[70];
  1106. for (int i = 0; i < 10; i++) {
  1107. if (_textSlots[i].startTime + _textSlots[i].duration > _system->getMillis() && _textSlots[i].duration != -1) {
  1108. char *srcStr = preprocessString(_sequenceStrings[_textSlots[i].strIndex], _textSlots[i].width);
  1109. int yPos = _textSlots[i].y;
  1110. while (*srcStr) {
  1111. uint32 linePos = 0;
  1112. for (; *srcStr; linePos++) {
  1113. if (*srcStr == '\r')
  1114. break;
  1115. outputStr[linePos] = *srcStr;
  1116. srcStr++;
  1117. }
  1118. outputStr[linePos] = 0;
  1119. if (*srcStr == '\r')
  1120. srcStr++;
  1121. uint8 textColor = (_textSlots[i].textcolor >= 0) ? _textSlots[i].textcolor : _textColor[0];
  1122. _screen->printText(outputStr, _textSlots[i].x - (_screen->getTextWidth(outputStr) / 2), yPos, textColor, 0);
  1123. yPos += 10;
  1124. }
  1125. } else {
  1126. _textSlots[i].duration = -1;
  1127. }
  1128. }
  1129. _screen->setCurPage(curPage);
  1130. }
  1131. char *SeqPlayer_HOF::preprocessString(const char *srcStr, int width) {
  1132. char *dstStr = _tempString;
  1133. int lineStart = 0;
  1134. int linePos = 0;
  1135. while (*srcStr) {
  1136. while (*srcStr && *srcStr != ' ')
  1137. dstStr[lineStart + linePos++] = *srcStr++;
  1138. dstStr[lineStart + linePos] = 0;
  1139. int len = _screen->getTextWidth(&dstStr[lineStart]);
  1140. if (width >= len && *srcStr) {
  1141. dstStr[lineStart + linePos++] = *srcStr++;
  1142. } else {
  1143. dstStr[lineStart + linePos] = '\r';
  1144. lineStart += linePos + 1;
  1145. linePos = 0;
  1146. if (*srcStr)
  1147. srcStr++;
  1148. }
  1149. }
  1150. dstStr[lineStart + linePos] = 0;
  1151. return strlen(_tempString) ? dstStr : 0;
  1152. }
  1153. void SeqPlayer_HOF::waitForSubTitlesTimeout() {
  1154. uint32 timeOut = _system->getMillis() + ticksTillSubTitlesTimeout() * _vm->tickLength();
  1155. if (_vm->textEnabled()) {
  1156. delayUntil(timeOut);
  1157. } else if (_vm->speechEnabled()) {
  1158. while (_vm->snd_voiceIsPlaying())
  1159. delayTicks(1);
  1160. }
  1161. resetAllTextSlots();
  1162. }
  1163. uint32 SeqPlayer_HOF::ticksTillSubTitlesTimeout() {
  1164. uint32 longest = 0;
  1165. for (int i = 0; i < 10; i++) {
  1166. uint32 timeOut = (_textSlots[i].duration + _textSlots[i].startTime);
  1167. uint32 curtime = _system->getMillis();
  1168. if (_textSlots[i].duration != -1 && timeOut > curtime) {
  1169. timeOut -= curtime;
  1170. if (longest < timeOut)
  1171. longest = timeOut;
  1172. }
  1173. }
  1174. uint32 tl = _vm->tickLength();
  1175. return (longest + (tl - 1)) / tl;
  1176. }
  1177. void SeqPlayer_HOF::resetAllTextSlots() {
  1178. for (int i = 0; i < 10; i++)
  1179. _textSlots[i].duration = -1;
  1180. }
  1181. void SeqPlayer_HOF::fadeOutMusic() {
  1182. _vm->sound()->beginFadeOut();
  1183. delayTicks(80);
  1184. }
  1185. void SeqPlayer_HOF::playHoFTalkieCredits() {
  1186. static const uint8 colormap[] = {0, 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  1187. static const ScreenDim d = { 0x00, 0x0C, 0x28, 0xB4, 0xFF, 0x00, 0x00, 0x00 };
  1188. _screen->loadBitmap("finale.cps", 3, 3, &_screen->getPalette(0));
  1189. _screen->setFont(Screen::FID_GOLDFONT_FNT);
  1190. int talkieCreditsSize, talkieCreditsSpecialSize;
  1191. const uint8 *talkieCredits = _vm->staticres()->loadRawData(k2SeqplayCredits, talkieCreditsSize);
  1192. const char *const *talkieCreditsSpecial = _vm->staticres()->loadStrings(k2SeqplayCreditsSpecial, talkieCreditsSpecialSize);
  1193. _vm->sound()->selectAudioResourceSet(kMusicIngame);
  1194. _vm->sound()->loadSoundFile(3);
  1195. _vm->sound()->playTrack(3);
  1196. _screen->setTextColorMap(colormap);
  1197. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1198. _screen->updateScreen();
  1199. _screen->fadeFromBlack();
  1200. _screen->_charWidth = -2;
  1201. uint8 *dataPtr = new uint8[0xAFD];
  1202. memcpy(dataPtr, talkieCredits, talkieCreditsSize);
  1203. _vm->staticres()->unloadId(k2SeqplayCredits);
  1204. displayHoFTalkieScrollText(dataPtr, &d, 2, 6, 5, 1, Screen::FID_GOLDFONT_FNT, Screen::FID_GOLDFONT_FNT, 0, talkieCreditsSpecial);
  1205. delayTicks(8);
  1206. delete[] dataPtr;
  1207. _vm->staticres()->unloadId(k2SeqplayCreditsSpecial);
  1208. _vm->sound()->selectAudioResourceSet(kMusicFinale);
  1209. _vm->sound()->loadSoundFile(0);
  1210. }
  1211. void SeqPlayer_HOF::displayHoFTalkieScrollText(uint8 *data, const ScreenDim *d, int tempPage1, int tempPage2, int speed,
  1212. int step, Screen::FontId fid1, Screen::FontId fid2, const uint8 *shapeData, const char *const *specialData) {
  1213. if (!data)
  1214. return;
  1215. static const char mark[] = { 5, 13, 0 };
  1216. _screen->clearPage(tempPage1);
  1217. _screen->clearPage(tempPage2);
  1218. _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, 0, tempPage1);
  1219. struct ScrollTextData {
  1220. int16 x;
  1221. int16 y;
  1222. uint8 *text;
  1223. byte unk1;
  1224. byte height;
  1225. byte adjust;
  1226. ScrollTextData() {
  1227. x = 0; // 0 11
  1228. y = 0; // 2 13
  1229. text = 0; // 4 15
  1230. unk1 = 0; // 8 19
  1231. height = 0; // 9 20
  1232. adjust = 0; // 10 21
  1233. }
  1234. };
  1235. ScrollTextData *textData = new ScrollTextData[36];
  1236. uint8 *ptr = data;
  1237. bool loop = true;
  1238. int cnt = 0;
  1239. while (loop) {
  1240. uint32 loopEnd = _system->getMillis() + speed * _vm->tickLength();
  1241. while (cnt < 35 && *ptr) {
  1242. uint16 cH;
  1243. if (cnt)
  1244. cH = textData[cnt].y + textData[cnt].height + (textData[cnt].height >> 3);
  1245. else
  1246. cH = d->h;
  1247. char *str = (char *)ptr;
  1248. ptr = (uint8 *)strpbrk(str, mark);
  1249. if (!ptr)
  1250. ptr = (uint8 *)strchr(str, 0);
  1251. textData[cnt + 1].unk1 = *ptr;
  1252. *ptr = 0;
  1253. if (textData[cnt + 1].unk1)
  1254. ptr++;
  1255. if (*str == 3 || *str == 4)
  1256. textData[cnt + 1].adjust = *str++;
  1257. else
  1258. textData[cnt + 1].adjust = 0;
  1259. _screen->setFont(fid1);
  1260. if (*str == 1) {
  1261. _screen->setFont(fid2);
  1262. str++;
  1263. } else if (*str == 2) {
  1264. str++;
  1265. }
  1266. textData[cnt + 1].height = _screen->getFontHeight();
  1267. switch (textData[cnt + 1].adjust) {
  1268. case 3:
  1269. textData[cnt + 1].x = 157 - _screen->getTextWidth(str);
  1270. break;
  1271. case 4:
  1272. textData[cnt + 1].x = 161;
  1273. break;
  1274. default:
  1275. textData[cnt + 1].x = (((d->w << 3) - _screen->getTextWidth(str)) >> 1) + 1;
  1276. }
  1277. if (textData[cnt].unk1 == 5)
  1278. cH -= (textData[cnt].height + (textData[cnt].height >> 3));
  1279. textData[cnt + 1].y = cH;
  1280. textData[cnt + 1].text = (uint8 *)str;
  1281. cnt++;
  1282. }
  1283. _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage1, tempPage2);
  1284. int cnt2 = 0;
  1285. bool palCycle = 0;
  1286. while (cnt2 < cnt) {
  1287. const char *str = (const char *)textData[cnt2 + 1].text;
  1288. const char *str2 = str;
  1289. int16 cW = textData[cnt2 + 1].x - 10;
  1290. int16 cH = textData[cnt2 + 1].y;
  1291. int x = (d->sx << 3) + cW;
  1292. int y = d->sy + cH;
  1293. int col1 = 255;
  1294. if (cH < d->h) {
  1295. _screen->setCurPage(tempPage2);
  1296. _screen->setFont(fid1);
  1297. if (textData[cnt2 + 1].height != _screen->getFontHeight())
  1298. _screen->setFont(fid2);
  1299. if (specialData) {
  1300. if (!strcmp(str, specialData[0])) {
  1301. col1 = 112;
  1302. char cChar[2] = " ";
  1303. while (*str2) {
  1304. cChar[0] = *str2;
  1305. _screen->printText(cChar, x, y, col1++, 0);
  1306. x += _screen->getCharWidth((uint8)*str2++);
  1307. }
  1308. palCycle = true;
  1309. } else if (!strcmp(str, specialData[1])) {
  1310. col1 = 133;
  1311. char cChar[2] = " ";
  1312. while (*str2) {
  1313. cChar[0] = *str2;
  1314. _screen->printText(cChar, x, y, col1--, 0);
  1315. x += _screen->getCharWidth((uint8)*str2++);
  1316. }
  1317. palCycle = true;
  1318. } else {
  1319. _screen->printText(str, x, y, col1, 0);
  1320. }
  1321. } else {
  1322. _screen->printText(str, x, y, col1, 0);
  1323. }
  1324. _screen->setCurPage(0);
  1325. }
  1326. textData[cnt2 + 1].y -= step;
  1327. cnt2++;
  1328. }
  1329. _screen->copyRegion(d->sx << 3, d->sy, d->sx << 3, d->sy, d->w << 3, d->h, tempPage2, 0);
  1330. _screen->updateScreen();
  1331. if (textData[1].y < -10) {
  1332. textData[1].text += strlen((char *)textData[1].text);
  1333. textData[1].text[0] = textData[1].unk1;
  1334. cnt--;
  1335. memmove(&textData[1], &textData[2], cnt * sizeof(ScrollTextData));
  1336. }
  1337. if (palCycle) {
  1338. for (int col = 133; col > 112; col--)
  1339. _screen->getPalette(0).copy(_screen->getPalette(0), col - 1, 1, col);
  1340. _screen->getPalette(0).copy(_screen->getPalette(0), 133, 1, 112);
  1341. _screen->setScreenPalette(_screen->getPalette(0));
  1342. }
  1343. delayUntil(loopEnd);
  1344. if ((cnt < 36) && ((d->sy + d->h) > (textData[cnt].y + textData[cnt].height)) && !_abortPlayback) {
  1345. delayTicks(500);
  1346. cnt = 0;
  1347. }
  1348. if (checkAbortPlayback())
  1349. if (checkPlaybackStatus())
  1350. loop = false;
  1351. if (!cnt || _abortPlayback)
  1352. loop = false;
  1353. }
  1354. _vm->sound()->beginFadeOut();
  1355. _screen->fadeToBlack();
  1356. _abortPlayback = _abortRequested = false;
  1357. delete[] textData;
  1358. }
  1359. void SeqPlayer_HOF::updateDemoAdText(int bottom, int top) {
  1360. int dstY, dstH, srcH;
  1361. static const ScreenDim d = { 0x00, 0x00, 0x28, 0x320, 0xFF, 0xFE, 0x00, 0x00 };
  1362. if (_scrollProgressCounter - (top - 1) < 0) {
  1363. dstY = top - _scrollProgressCounter;
  1364. dstH = _scrollProgressCounter;
  1365. srcH = 0;
  1366. } else {
  1367. dstY = 0;
  1368. srcH = _scrollProgressCounter - top;
  1369. dstH = (400 - srcH <= top) ? 400 - srcH : top;
  1370. }
  1371. if (dstH > 0) {
  1372. if (_hofDemoAnimData) {
  1373. for (int i = 0; i < 4; i++) {
  1374. const HoFSeqItemAnimData *def = &_hofDemoAnimData[i];
  1375. ActiveItemAnim *a = &_hofDemoActiveItemAnim[i];
  1376. _screen->fillRect(12, def->y - 8, 28, def->y + 8, 0, 4);
  1377. _screen->drawShape(4, _hofDemoItemShapes[def->itemIndex + def->frames[a->currentFrame]], 12, def->y - 8, 0, 0);
  1378. if (_callbackCurrentFrame % 2 == 0)
  1379. a->currentFrame = (a->currentFrame + 1) % 20;
  1380. }
  1381. }
  1382. _screen->copyRegionEx(4, 0, srcH, 2, 2, dstY + bottom, 320, dstH, &d);
  1383. }
  1384. }
  1385. void SeqPlayer_HOF::delayTicks(uint32 ticks) {
  1386. uint32 len = ticks * _vm->tickLength();
  1387. while (len && !_vm->shouldQuit() && !checkAbortPlayback()) {
  1388. uint32 step = (len >= 10) ? 10 : len;
  1389. _system->delayMillis(step);
  1390. len -= step;
  1391. }
  1392. }
  1393. void SeqPlayer_HOF::delayUntil(uint32 dest) {
  1394. for (uint32 ct = _system->getMillis(); ct < dest && !_vm->shouldQuit() && !checkAbortPlayback(); ) {
  1395. uint32 step = (dest - ct >= 10) ? 10 : (dest - ct);
  1396. _system->delayMillis(step);
  1397. ct = _system->getMillis();
  1398. }
  1399. }
  1400. void SeqPlayer_HOF::setCountDown(uint32 ticks) {
  1401. _countDownRemainder = ticks * _vm->tickLength();
  1402. if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)
  1403. _countDownRemainder = _countDownRemainder * 2 / 3;
  1404. _countDownLastUpdate = _system->getMillis() & ~(_vm->tickLength() - 1);
  1405. }
  1406. bool SeqPlayer_HOF::countDownRunning() {
  1407. uint32 cur = _system->getMillis();
  1408. uint32 step = cur - _countDownLastUpdate;
  1409. _countDownLastUpdate = cur;
  1410. _countDownRemainder = (step <= _countDownRemainder) ? _countDownRemainder - step : 0;
  1411. return _countDownRemainder;
  1412. }
  1413. #define CASE_ALT(dosCase, towns98Case)\
  1414. case dosCase:\
  1415. case towns98Case:\
  1416. if (!((_callbackCurrentFrame == towns98Case && (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)) || (_callbackCurrentFrame == dosCase && _vm->gameFlags().platform == Common::kPlatformDOS)))\
  1417. break;
  1418. int SeqPlayer_HOF::cbHOF_westwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1419. if (frm == -2) {
  1420. if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)
  1421. delayTicks(300);
  1422. } else if (!frm) {
  1423. _vm->sound()->playTrack(2);
  1424. }
  1425. return 0;
  1426. }
  1427. int SeqPlayer_HOF::cbHOF_title(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1428. if (frm == 1) {
  1429. _vm->sound()->playTrack(3);
  1430. } else if (frm == 25 && _startupSaveLoadable) {
  1431. int cp = _screen->setCurPage(0);
  1432. _screen->showMouse();
  1433. _system->updateScreen();
  1434. _result = _menu->handle(11) + 1;
  1435. _updateAnimations = false;
  1436. if (_result == 1 || _result == 3) {
  1437. _curScene = _lastScene;
  1438. _preventLooping = true;
  1439. }
  1440. if (_result == 2) {
  1441. _result = 0;
  1442. } else if (_result == 4) {
  1443. setCountDown(200);
  1444. _vm->quitGame();
  1445. }
  1446. _screen->hideMouse();
  1447. _screen->setCurPage(cp);
  1448. } else if (frm == 25) {
  1449. setCountDown(200);
  1450. }
  1451. return 0;
  1452. }
  1453. int SeqPlayer_HOF::cbHOF_overview(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1454. uint8 *tmpPal = _screen->getPalette(3).getData() + 0x101;
  1455. memset(tmpPal, 0, 256);
  1456. uint32 frameEnd = 0;
  1457. switch (_callbackCurrentFrame) {
  1458. case 0:
  1459. _updateAnimations = true;
  1460. fadeOutMusic();
  1461. _vm->sound()->playTrack(4);
  1462. frameEnd = _system->getMillis() + 60 * _vm->tickLength();
  1463. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1464. memset(_textColorMap, _textColor[1], 16);
  1465. _textColorMap[1] = _textColor[0] = _screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xFF;
  1466. _screen->setTextColorMap(_textColorMap);
  1467. delayUntil(frameEnd);
  1468. break;
  1469. case 1:
  1470. assert(_screenHoF);
  1471. _screenHoF->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x40, 0, 0, 0, 0x100, true);
  1472. for (int i = 0; i < 256; i++)
  1473. tmpPal[_screen->getPalette(3)[i]] = 1;
  1474. for (int i = 0; i < 256; i++) {
  1475. int v = (tmpPal[i] == 1) ? i : _screen->getPalette(3)[i];
  1476. v *= 3;
  1477. _screen->getPalette(2)[3 * i] = _screen->getPalette(0)[v];
  1478. _screen->getPalette(2)[3 * i + 1] = _screen->getPalette(0)[v + 1];
  1479. _screen->getPalette(2)[3 * i + 2] = _screen->getPalette(0)[v + 2];
  1480. }
  1481. break;
  1482. case 40:
  1483. startNestedAnimation(0, kNestedSequenceOver1);
  1484. break;
  1485. case 60:
  1486. startNestedAnimation(1, kNestedSequenceOver2);
  1487. break;
  1488. case 120:
  1489. playSoundAndDisplaySubTitle(0);
  1490. break;
  1491. case 200:
  1492. waitForSubTitlesTimeout();
  1493. _screen->fadePalette(_screen->getPalette(2), 64);
  1494. break;
  1495. case 201:
  1496. _screen->setScreenPalette(_screen->getPalette(2));
  1497. _screen->updateScreen();
  1498. _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
  1499. _screen->copyPage(2, 12);
  1500. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1501. _screen->setScreenPalette(_screen->getPalette(0));
  1502. _screen->updateScreen();
  1503. closeNestedAnimation(0);
  1504. closeNestedAnimation(1);
  1505. break;
  1506. case 282:
  1507. startNestedAnimation(0, kNestedSequenceForest);
  1508. playSoundAndDisplaySubTitle(1);
  1509. break;
  1510. case 434:
  1511. //CASE_ALT(434, 354)
  1512. closeNestedAnimation(0);
  1513. startNestedAnimation(0, kNestedSequenceDragon);
  1514. break;
  1515. case 540:
  1516. //CASE_ALT(540, 400)
  1517. waitForSubTitlesTimeout();
  1518. closeNestedAnimation(0);
  1519. setCountDown(0);
  1520. _updateAnimations = false;
  1521. break;
  1522. default:
  1523. break;
  1524. }
  1525. _callbackCurrentFrame++;
  1526. return 0;
  1527. }
  1528. int SeqPlayer_HOF::cbHOF_library(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1529. switch (_callbackCurrentFrame) {
  1530. case 0:
  1531. _updateAnimations = true;
  1532. _vm->sound()->playTrack(5);
  1533. assert(_screenHoF);
  1534. _screenHoF->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
  1535. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1536. memset(_textColorMap, _textColor[1], 16);
  1537. _textColorMap[1] = _textColor[0] = _screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xFF;
  1538. _screen->setTextColorMap(_textColorMap);
  1539. break;
  1540. case 1:
  1541. startNestedAnimation(0, kNestedSequenceLibrary3);
  1542. playSoundAndDisplaySubTitle(4);
  1543. break;
  1544. case 100:
  1545. waitForSubTitlesTimeout();
  1546. _screen->copyPage(12, 2);
  1547. _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
  1548. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1549. _screen->updateScreen();
  1550. _screen->copyPage(2, 12);
  1551. closeNestedAnimation(0);
  1552. startNestedAnimation(0, kNestedSequenceDarm);
  1553. break;
  1554. case 104:
  1555. playSoundAndDisplaySubTitle(5);
  1556. break;
  1557. case 240:
  1558. waitForSubTitlesTimeout();
  1559. closeNestedAnimation(0);
  1560. startNestedAnimation(0, kNestedSequenceLibrary2);
  1561. break;
  1562. case 340:
  1563. closeNestedAnimation(0);
  1564. _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
  1565. _screen->copyPage(2, 12);
  1566. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1567. _screen->updateScreen();
  1568. startNestedAnimation(0, kNestedSequenceMarco);
  1569. playSoundAndDisplaySubTitle(6);
  1570. break;
  1571. case 660:
  1572. //CASE_ALT(660, 480)
  1573. _screen->copyPage(2, 12);
  1574. waitForSubTitlesTimeout();
  1575. closeNestedAnimation(0);
  1576. setCountDown(0);
  1577. _updateAnimations = false;
  1578. break;
  1579. default:
  1580. break;
  1581. }
  1582. _callbackCurrentFrame++;
  1583. return 0;
  1584. }
  1585. int SeqPlayer_HOF::cbHOF_hand(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1586. switch (_callbackCurrentFrame) {
  1587. case 0:
  1588. _updateAnimations = true;
  1589. _vm->sound()->playTrack(6);
  1590. assert(_screenHoF);
  1591. _screenHoF->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
  1592. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1593. memset(_textColorMap, _textColor[1], 16);
  1594. _textColorMap[1] = _textColor[0] = _screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xFF;
  1595. _screen->setTextColorMap(_textColorMap);
  1596. break;
  1597. case 1:
  1598. startNestedAnimation(0, kNestedSequenceHand1a);
  1599. startNestedAnimation(1, kNestedSequenceHand1b);
  1600. startNestedAnimation(2, kNestedSequenceHand1c);
  1601. playSoundAndDisplaySubTitle(7);
  1602. break;
  1603. case 201:
  1604. waitForSubTitlesTimeout();
  1605. _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
  1606. _screen->copyPage(2, 12);
  1607. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1608. _screen->updateScreen();
  1609. closeNestedAnimation(0);
  1610. closeNestedAnimation(1);
  1611. closeNestedAnimation(2);
  1612. startNestedAnimation(0, kNestedSequenceHand2);
  1613. playSoundAndDisplaySubTitle(8);
  1614. break;
  1615. CASE_ALT(395, 260)
  1616. waitForSubTitlesTimeout();
  1617. closeNestedAnimation(0);
  1618. startNestedAnimation(1, kNestedSequenceHand3);
  1619. playSoundAndDisplaySubTitle(9);
  1620. break;
  1621. CASE_ALT(500, 365)
  1622. waitForSubTitlesTimeout();
  1623. closeNestedAnimation(1);
  1624. startNestedAnimation(0, kNestedSequenceHand4);
  1625. break;
  1626. CASE_ALT(540, 405)
  1627. playSoundAndDisplaySubTitle(10);
  1628. break;
  1629. CASE_ALT(630, 484)
  1630. waitForSubTitlesTimeout();
  1631. closeNestedAnimation(0);
  1632. setCountDown(0);
  1633. _updateAnimations = false;
  1634. break;
  1635. default:
  1636. break;
  1637. }
  1638. _callbackCurrentFrame++;
  1639. return 0;
  1640. }
  1641. int SeqPlayer_HOF::cbHOF_point(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1642. if (frm == -2) {
  1643. waitForSubTitlesTimeout();
  1644. setCountDown(0);
  1645. }
  1646. switch (_callbackCurrentFrame) {
  1647. case -2:
  1648. waitForSubTitlesTimeout();
  1649. break;
  1650. case 0:
  1651. _vm->sound()->playTrack(7);
  1652. _textColor[1] = 0xF7;
  1653. memset(_textColorMap, _textColor[1], 16);
  1654. _textColorMap[1] = _textColor[0] = _screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xFF;
  1655. _screen->setTextColorMap(_textColorMap);
  1656. assert(_screenHoF);
  1657. _screenHoF->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
  1658. break;
  1659. case 1:
  1660. playSoundAndDisplaySubTitle(11);
  1661. break;
  1662. default:
  1663. break;
  1664. }
  1665. _callbackCurrentFrame++;
  1666. return 0;
  1667. }
  1668. int SeqPlayer_HOF::cbHOF_zanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1669. if (frm == -2) {
  1670. waitForSubTitlesTimeout();
  1671. setCountDown(0);
  1672. return 0;
  1673. }
  1674. switch (_callbackCurrentFrame) {
  1675. case 0:
  1676. _vm->sound()->playTrack(8);
  1677. _textColor[1] = 0xFD;
  1678. memset(_textColorMap, _textColor[1], 16);
  1679. _textColorMap[1] = _textColor[0] = _screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xFF;
  1680. _screen->setTextColorMap(_textColorMap);
  1681. break;
  1682. case 1:
  1683. if (_vm->gameFlags().isTalkie) {
  1684. playDialogueAnimation(21, 13, -1, 140, 70, 160, wsaObj, 0, 8, x, y);
  1685. } else {
  1686. displaySubTitle(21, 140, 70, 200, 160);
  1687. _animDuration = 200;
  1688. }
  1689. break;
  1690. case 2:
  1691. case 11:
  1692. case 21:
  1693. if (!_vm->gameFlags().isTalkie)
  1694. _animDuration = 12;
  1695. break;
  1696. case 9:
  1697. if (_vm->gameFlags().isTalkie)
  1698. playDialogueAnimation(13, 14, -1, 140, (_vm->gameFlags().lang == Common::FR_FRA
  1699. || _vm->gameFlags().lang == Common::DE_DEU) ? 50 : 70, 160, wsaObj, 9, 15, x, y);
  1700. break;
  1701. case 10:
  1702. if (!_vm->gameFlags().isTalkie) {
  1703. waitForSubTitlesTimeout();
  1704. displaySubTitle(13, 140, 50, _textDuration[13], 160);
  1705. _animDuration = 300;
  1706. }
  1707. break;
  1708. case 16:
  1709. if (_vm->gameFlags().isTalkie)
  1710. playDialogueAnimation(18, 15, -1, 140, (_vm->gameFlags().lang == Common::FR_FRA) ? 50 :
  1711. (_vm->gameFlags().lang == Common::DE_DEU ? 40 : 70), 160, wsaObj, 10, 16, x, y);
  1712. break;
  1713. case 17:
  1714. if (_vm->gameFlags().isTalkie)
  1715. _animDuration = 12;
  1716. break;
  1717. case 20:
  1718. if (!_vm->gameFlags().isTalkie) {
  1719. waitForSubTitlesTimeout();
  1720. displaySubTitle(18, 160, 50, _textDuration[18], 160);
  1721. _animDuration = 200;
  1722. }
  1723. break;
  1724. case 26:
  1725. waitForSubTitlesTimeout();
  1726. break;
  1727. case 46:
  1728. if (_vm->gameFlags().isTalkie) {
  1729. playDialogueAnimation(16, 16, -1, 200, 50, 120, wsaObj, 46, 46, x, y);
  1730. } else {
  1731. waitForSubTitlesTimeout();
  1732. displaySubTitle(16, 200, 50, _textDuration[16], 120);
  1733. }
  1734. setCountDown(120);
  1735. break;
  1736. default:
  1737. break;
  1738. }
  1739. _callbackCurrentFrame++;
  1740. return 0;
  1741. }
  1742. int SeqPlayer_HOF::cbHOF_over1(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1743. if (frm == 2)
  1744. waitForSubTitlesTimeout();
  1745. else if (frm == 3)
  1746. playSoundAndDisplaySubTitle(12);
  1747. return frm;
  1748. }
  1749. int SeqPlayer_HOF::cbHOF_over2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1750. if (frm == 1)
  1751. playSoundAndDisplaySubTitle(12);
  1752. return frm;
  1753. }
  1754. int SeqPlayer_HOF::cbHOF_forest(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1755. if (frm == 11)
  1756. waitForSubTitlesTimeout();
  1757. else if (frm == 12)
  1758. playSoundAndDisplaySubTitle(2);
  1759. return frm;
  1760. }
  1761. int SeqPlayer_HOF::cbHOF_dragon(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1762. if (frm == 11)
  1763. waitForSubTitlesTimeout();
  1764. else if (frm == 3)
  1765. playSoundAndDisplaySubTitle(3);
  1766. return frm;
  1767. }
  1768. int SeqPlayer_HOF::cbHOF_darm(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1769. return frm;
  1770. }
  1771. int SeqPlayer_HOF::cbHOF_library2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1772. return frm;
  1773. }
  1774. int SeqPlayer_HOF::cbHOF_marco(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1775. if (frm == 36) {
  1776. waitForSubTitlesTimeout();
  1777. setCountDown(0);
  1778. }
  1779. return frm;
  1780. }
  1781. int SeqPlayer_HOF::cbHOF_hand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1782. return frm;
  1783. }
  1784. int SeqPlayer_HOF::cbHOF_hand1b(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1785. if (frm == 15)
  1786. frm = 12;
  1787. return frm;
  1788. }
  1789. int SeqPlayer_HOF::cbHOF_hand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1790. if (frm == 8)
  1791. frm = 4;
  1792. return frm;
  1793. }
  1794. int SeqPlayer_HOF::cbHOF_hand2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1795. return frm;
  1796. }
  1797. int SeqPlayer_HOF::cbHOF_hand3(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1798. return frm;
  1799. }
  1800. int SeqPlayer_HOF::cbHOF_funters(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1801. uint32 frameEnd = 0;
  1802. int subTitleX = 0;
  1803. int subTitleY = 0;
  1804. int subTitleW = 0;
  1805. int subTitleFirstFrame = 0;
  1806. int subTitleLastFrame = 0;
  1807. uint16 voiceIndex = 0;
  1808. switch (frm) {
  1809. case -2:
  1810. doTransition(9);
  1811. break;
  1812. case 0:
  1813. _vm->sound()->playTrack(3);
  1814. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1815. memset(_textColorMap, _textColor[1], 16);
  1816. _textColor[0] = _textColorMap[1] = 0xFF;
  1817. _screen->setTextColorMap(_textColorMap);
  1818. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  1819. printFadingText(81, 240, 70, _textColorMap, 252);
  1820. printFadingText(82, 240, 90, _textColorMap, _textColor[0]);
  1821. _screen->copyPage(2, 12);
  1822. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 28 : 24);
  1823. delayUntil(frameEnd);
  1824. _textColor[0] = 1;
  1825. if (_vm->gameFlags().isTalkie) {
  1826. subTitleY = (_vm->gameFlags().lang == Common::FR_FRA) ? 70 : 78;
  1827. subTitleFirstFrame = 9;
  1828. subTitleLastFrame = 15;
  1829. voiceIndex = 34;
  1830. } else {
  1831. subTitleY = (_vm->gameFlags().lang == Common::FR_FRA) ? 78 : 70;
  1832. subTitleFirstFrame = 0;
  1833. subTitleLastFrame = 8;
  1834. }
  1835. subTitleX = (_vm->gameFlags().lang == Common::FR_FRA) ? 84 : 88;
  1836. subTitleW = 100;
  1837. playDialogueAnimation(22, voiceIndex, 187, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  1838. break;
  1839. case 9:
  1840. case 16:
  1841. if (!((frm == 9 && !_vm->gameFlags().isTalkie) || (frm == 16 && _vm->gameFlags().isTalkie)))
  1842. break;
  1843. _animDuration = 12;
  1844. if (_vm->gameFlags().lang == Common::FR_FRA) {
  1845. subTitleX = 80;
  1846. subTitleW = 112;
  1847. } else {
  1848. subTitleX = (_vm->gameFlags().lang == Common::DE_DEU) ? 84 : 96;
  1849. subTitleW = 100;
  1850. }
  1851. if (_vm->gameFlags().isTalkie) {
  1852. subTitleFirstFrame = 0;
  1853. subTitleLastFrame = 8;
  1854. voiceIndex = 35;
  1855. } else {
  1856. subTitleFirstFrame = 9;
  1857. subTitleLastFrame = 15;
  1858. }
  1859. subTitleY = 70;
  1860. playDialogueAnimation(23, voiceIndex, 137, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  1861. if (_vm->gameFlags().isTalkie)
  1862. _animCurrentFrame = 17;
  1863. break;
  1864. default:
  1865. break;
  1866. }
  1867. _callbackCurrentFrame++;
  1868. return 0;
  1869. }
  1870. int SeqPlayer_HOF::cbHOF_ferb(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1871. uint32 frameEnd = 0;
  1872. int subTitleX = 0;
  1873. int subTitleY = 0;
  1874. int subTitleW = 0;
  1875. int subTitleFirstFrame = 0;
  1876. int subTitleLastFrame = 0;
  1877. uint16 voiceIndex = 0;
  1878. switch (frm) {
  1879. case -2:
  1880. doTransition(9);
  1881. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  1882. printFadingText(34, 240, _vm->gameFlags().isTalkie ? 60 : 40, _textColorMap, 252);
  1883. printFadingText(35, 240, _vm->gameFlags().isTalkie ? 70 : 50, _textColorMap, _textColor[0]);
  1884. printFadingText(36, 240, _vm->gameFlags().isTalkie ? 90 : 70, _textColorMap, 252);
  1885. printFadingText(37, 240, _vm->gameFlags().isTalkie ? 100 : 90, _textColorMap, _textColor[0]);
  1886. printFadingText(38, 240, _vm->gameFlags().isTalkie ? 120 : 110, _textColorMap, 252);
  1887. printFadingText(39, 240, _vm->gameFlags().isTalkie ? 130 : 120, _textColorMap, _textColor[0]);
  1888. if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)
  1889. printFadingText(103, 240, 130, _textColorMap, _textColor[0]);
  1890. delayUntil(frameEnd);
  1891. setCountDown(0);
  1892. break;
  1893. case 0:
  1894. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1895. memset(_textColorMap, _textColor[1], 16);
  1896. _textColor[0] = _textColorMap[1] = 255;
  1897. _screen->setTextColorMap(_textColorMap);
  1898. break;
  1899. case 5:
  1900. if (!_vm->gameFlags().isTalkie)
  1901. playSoundAndDisplaySubTitle(18);
  1902. _animDuration = 16;
  1903. if (_vm->gameFlags().isTalkie) {
  1904. subTitleFirstFrame = 5;
  1905. subTitleLastFrame = 8;
  1906. voiceIndex = 22;
  1907. } else {
  1908. subTitleLastFrame = 14;
  1909. }
  1910. subTitleX = 116;
  1911. subTitleY = 90;
  1912. subTitleW = 60;
  1913. playDialogueAnimation(24, voiceIndex, 149, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  1914. break;
  1915. case 11:
  1916. if (_vm->gameFlags().isTalkie)
  1917. playDialogueAnimation(24, 22, 149, 116, 90, 60, wsaObj, 11, 14, x, y);
  1918. break;
  1919. case 16:
  1920. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 23 : 19);
  1921. _animDuration = _vm->gameFlags().isTalkie ? 20 : 16;
  1922. if (_vm->gameFlags().lang == Common::FR_FRA) {
  1923. subTitleY = 48;
  1924. subTitleW = 88;
  1925. } else {
  1926. subTitleY = 60;
  1927. subTitleW = 100;
  1928. }
  1929. subTitleX = 60;
  1930. if (_vm->gameFlags().isTalkie)
  1931. voiceIndex = 36;
  1932. playDialogueAnimation(25, voiceIndex, 143, subTitleX, subTitleY, subTitleW, wsaObj, 16, 25, x, y);
  1933. _animDuration = 16;
  1934. break;
  1935. default:
  1936. break;
  1937. }
  1938. _callbackCurrentFrame++;
  1939. return 0;
  1940. }
  1941. int SeqPlayer_HOF::cbHOF_fish(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  1942. uint32 frameEnd = 0;
  1943. int subTitleX = 0;
  1944. int subTitleY = 0;
  1945. int subTitleW = 0;
  1946. uint16 voiceIndex = 0;
  1947. switch (frm) {
  1948. case -2:
  1949. doTransition(9);
  1950. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  1951. printFadingText(40, 240, _vm->gameFlags().isTalkie ? 55 : 40, _textColorMap, 252);
  1952. printFadingText(41, 240, _vm->gameFlags().isTalkie ? 65 : 50, _textColorMap, _textColor[0]);
  1953. printFadingText(42, 240, _vm->gameFlags().isTalkie ? 75 : 60, _textColorMap, _textColor[0]);
  1954. printFadingText(43, 240, _vm->gameFlags().isTalkie ? 95 : 80, _textColorMap, 252);
  1955. printFadingText(44, 240, _vm->gameFlags().isTalkie ? 105 : 90, _textColorMap, _textColor[0]);
  1956. printFadingText(93, 240, _vm->gameFlags().isTalkie ? 125 : 110, _textColorMap, 252);
  1957. printFadingText(94, 240, _vm->gameFlags().isTalkie ? 135 : 120, _textColorMap, _textColor[0]);
  1958. delayUntil(frameEnd);
  1959. setCountDown(0);
  1960. break;
  1961. case 0:
  1962. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  1963. memset(_textColorMap, _textColor[1], 16);
  1964. _textColor[0] = _textColorMap[1] = 0xFF;
  1965. _screen->setTextColorMap(_textColorMap);
  1966. break;
  1967. case 4:
  1968. subTitleX = 94;
  1969. subTitleY = 42;
  1970. subTitleW = 100;
  1971. if (_vm->gameFlags().isTalkie)
  1972. voiceIndex = 37;
  1973. playDialogueAnimation(26, voiceIndex, 149, subTitleX, subTitleY, subTitleW, wsaObj, 3, 12, x, y);
  1974. break;
  1975. case 14:
  1976. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 19 : 15);
  1977. break;
  1978. case 23:
  1979. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 20 : 16);
  1980. break;
  1981. case 29:
  1982. subTitleX = (_vm->gameFlags().lang == Common::DE_DEU) ? 82 : ((_vm->gameFlags().lang == Common::FR_FRA) ? 92 : 88);
  1983. subTitleY = 40;
  1984. subTitleW = 100;
  1985. if (_vm->gameFlags().isTalkie) {
  1986. if (_vm->gameFlags().lang == Common::DE_DEU)
  1987. subTitleY = 35;
  1988. voiceIndex = 38;
  1989. }
  1990. playDialogueAnimation(27, voiceIndex, 187, subTitleX, subTitleY, subTitleW, wsaObj, 28, 34, x, y);
  1991. break;
  1992. case 45:
  1993. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 21 : 17);
  1994. break;
  1995. case 50:
  1996. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 29 : 25);
  1997. break;
  1998. default:
  1999. break;
  2000. }
  2001. _callbackCurrentFrame++;
  2002. return 0;
  2003. }
  2004. int SeqPlayer_HOF::cbHOF_fheep(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2005. uint32 frameEnd = 0;
  2006. int subTitleX = 0;
  2007. int subTitleY = 0;
  2008. int subTitleW = 0;
  2009. int subTitleFirstFrame = 0;
  2010. int subTitleLastFrame = 0;
  2011. uint16 voiceIndex = 0;
  2012. switch (frm) {
  2013. case -2:
  2014. _screen->copyPage(12, 2);
  2015. _screen->copyPage(2, 0);
  2016. _screen->updateScreen();
  2017. doTransition(9);
  2018. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  2019. printFadingText(49, 240, 20, _textColorMap, 252);
  2020. printFadingText(50, 240, 30, _textColorMap, _textColor[0]);
  2021. printFadingText(51, 240, 40, _textColorMap, _textColor[0]);
  2022. printFadingText(52, 240, 50, _textColorMap, _textColor[0]);
  2023. printFadingText(53, 240, 60, _textColorMap, _textColor[0]);
  2024. printFadingText(54, 240, 70, _textColorMap, _textColor[0]);
  2025. printFadingText(55, 240, 80, _textColorMap, _textColor[0]);
  2026. printFadingText(56, 240, 90, _textColorMap, _textColor[0]);
  2027. printFadingText(57, 240, 100, _textColorMap, _textColor[0]);
  2028. printFadingText(58, 240, 110, _textColorMap, _textColor[0]);
  2029. printFadingText(60, 240, 120, _textColorMap, _textColor[0]);
  2030. printFadingText(61, 240, 130, _textColorMap, _textColor[0]);
  2031. printFadingText(62, 240, 140, _textColorMap, _textColor[0]);
  2032. printFadingText(63, 240, 150, _textColorMap, _textColor[0]);
  2033. printFadingText(64, 240, 160, _textColorMap, _textColor[0]);
  2034. delayUntil(frameEnd);
  2035. setCountDown(0);
  2036. break;
  2037. case 0:
  2038. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  2039. memset(_textColorMap, _textColor[1], 16);
  2040. _textColor[0] = _textColorMap[1] = 0xFF;
  2041. _screen->setTextColorMap(_textColorMap);
  2042. break;
  2043. case 2:
  2044. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 25 : 21);
  2045. if (_vm->gameFlags().lang == Common::FR_FRA) {
  2046. subTitleX = 92;
  2047. subTitleY = 72;
  2048. } else {
  2049. subTitleX = (_vm->gameFlags().lang == Common::DE_DEU) ? 90 : 98;
  2050. subTitleY = 84;
  2051. }
  2052. if (_vm->gameFlags().isTalkie) {
  2053. subTitleFirstFrame = 8;
  2054. subTitleLastFrame = 9;
  2055. voiceIndex = 39;
  2056. } else {
  2057. subTitleFirstFrame = 2;
  2058. subTitleLastFrame = -8;
  2059. }
  2060. subTitleW = 100;
  2061. playDialogueAnimation(28, voiceIndex, -1, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  2062. if (_vm->gameFlags().isTalkie)
  2063. _animCurrentFrame = 4;
  2064. break;
  2065. case 9:
  2066. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 24 : 20);
  2067. _animDuration = 100;
  2068. break;
  2069. default:
  2070. break;
  2071. }
  2072. _callbackCurrentFrame++;
  2073. return 0;
  2074. }
  2075. int SeqPlayer_HOF::cbHOF_farmer(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2076. uint32 frameEnd = 0;
  2077. int subTitleX = 0;
  2078. int subTitleY = 0;
  2079. int subTitleW = 0;
  2080. uint16 voiceIndex = 0;
  2081. switch (frm) {
  2082. case -2:
  2083. _screen->copyPage(12, 2);
  2084. _screen->copyPage(2, 0);
  2085. _screen->updateScreen();
  2086. doTransition(9);
  2087. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  2088. printFadingText(45, 240, 40, _textColorMap, 252);
  2089. printFadingText(46, 240, 50, _textColorMap, _textColor[0]);
  2090. printFadingText(47, 240, 60, _textColorMap, _textColor[0]);
  2091. printFadingText(83, 240, 80, _textColorMap, 252);
  2092. printFadingText(48, 240, 90, _textColorMap, _textColor[0]);
  2093. printFadingText(65, 240, 110, _textColorMap, 252);
  2094. printFadingText(66, 240, 120, _textColorMap, _textColor[0]);
  2095. printFadingText(67, 240, 130, _textColorMap, _textColor[0]);
  2096. printFadingText(68, 240, 140, _textColorMap, _textColor[0]);
  2097. printFadingText(69, 240, 150, _textColorMap, _textColor[0]);
  2098. if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98)
  2099. printFadingText(104, 240, 160, _textColorMap, _textColor[0]);
  2100. delayUntil(frameEnd);
  2101. setCountDown(0);
  2102. break;
  2103. case 0:
  2104. _textColor[1] = 1 + (_screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 254) & 0xFF);
  2105. memset(_textColorMap, _textColor[1], 16);
  2106. _textColorMap[1] = _textColor[0] = 1 + (_screen->findLeastDifferentColor(_textColorPresets + 3, _screen->getPalette(0), 1, 254) & 0xFF);
  2107. _screen->setTextColorMap(_textColorMap);
  2108. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 30 : 26);
  2109. break;
  2110. case 6:
  2111. if (_vm->gameFlags().isTalkie)
  2112. playSoundAndDisplaySubTitle(18);
  2113. break;
  2114. case 12:
  2115. if (!_vm->gameFlags().isTalkie)
  2116. playSoundAndDisplaySubTitle(14);
  2117. subTitleX = 90;
  2118. subTitleY = 30;
  2119. subTitleW = 100;
  2120. if (_vm->gameFlags().isTalkie) {
  2121. if (_vm->gameFlags().lang == Common::FR_FRA || _vm->gameFlags().lang == Common::DE_DEU) {
  2122. subTitleX = 75;
  2123. subTitleY = 25;
  2124. }
  2125. voiceIndex = 40;
  2126. }
  2127. playDialogueAnimation(29, voiceIndex, 150, subTitleX, subTitleY, subTitleW, wsaObj, 12, -21, x, y);
  2128. break;
  2129. default:
  2130. break;
  2131. }
  2132. _callbackCurrentFrame++;
  2133. return 0;
  2134. }
  2135. int SeqPlayer_HOF::cbHOF_fuards(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2136. uint32 frameEnd = 0;
  2137. int subTitleX = 0;
  2138. int subTitleY = 0;
  2139. int subTitleW = 0;
  2140. int subTitleFirstFrame = 0;
  2141. int subTitleLastFrame = 0;
  2142. uint16 voiceIndex = 0;
  2143. switch (frm) {
  2144. case -2:
  2145. doTransition(9);
  2146. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  2147. printFadingText(70, 240, 20, _textColorMap, 252);
  2148. printFadingText(71, 240, 30, _textColorMap, _textColor[0]);
  2149. printFadingText(72, 240, 40, _textColorMap, _textColor[0]);
  2150. printFadingText(73, 240, 50, _textColorMap, _textColor[0]);
  2151. printFadingText(74, 240, 60, _textColorMap, _textColor[0]);
  2152. printFadingText(75, 240, 70, _textColorMap, _textColor[0]);
  2153. printFadingText(101, 240, 80, _textColorMap, _textColor[0]);
  2154. printFadingText(102, 240, 90, _textColorMap, _textColor[0]);
  2155. printFadingText(87, 240, 100, _textColorMap, _textColor[0]);
  2156. printFadingText(88, 240, 110, _textColorMap, _textColor[0]);
  2157. printFadingText(89, 240, 120, _textColorMap, _textColor[0]);
  2158. printFadingText(90, 240, 130, _textColorMap, _textColor[0]);
  2159. printFadingText(91, 240, 140, _textColorMap, _textColor[0]);
  2160. printFadingText(92, 240, 150, _textColorMap, _textColor[0]);
  2161. delayUntil(frameEnd);
  2162. setCountDown(0);
  2163. break;
  2164. case 0:
  2165. for (int i = 0; i < 0x300; i++)
  2166. _screen->getPalette(0)[i] &= 0x3F;
  2167. _textColor[1] = 0xCf;
  2168. memset(_textColorMap, _textColor[1], 16);
  2169. _textColor[0] = _textColorMap[1] = 0xFE;
  2170. _screen->setTextColorMap(_textColorMap);
  2171. break;
  2172. case 6:
  2173. _animDuration = 20;
  2174. if (_vm->gameFlags().isTalkie) {
  2175. subTitleX = 82;
  2176. subTitleFirstFrame = 16;
  2177. subTitleLastFrame = 21;
  2178. voiceIndex = 41;
  2179. } else {
  2180. subTitleX = 62;
  2181. subTitleFirstFrame = 9;
  2182. subTitleLastFrame = 13;
  2183. }
  2184. subTitleY = (_vm->gameFlags().lang == Common::FR_FRA || _vm->gameFlags().lang == Common::DE_DEU) ? 88 :100;
  2185. subTitleW = 80;
  2186. playDialogueAnimation(30, voiceIndex, 137, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  2187. if (_vm->gameFlags().isTalkie)
  2188. _animCurrentFrame = 8;
  2189. break;
  2190. case 9:
  2191. case 16:
  2192. if (_vm->gameFlags().isTalkie) {
  2193. if (frm == 16)
  2194. break;
  2195. subTitleX = 64;
  2196. subTitleFirstFrame = 9;
  2197. subTitleLastFrame = 13;
  2198. voiceIndex = 42;
  2199. } else {
  2200. if (frm == 9)
  2201. break;
  2202. subTitleX = 80;
  2203. subTitleFirstFrame = 16;
  2204. subTitleLastFrame = 21;
  2205. }
  2206. subTitleY = 100;
  2207. subTitleW = 100;
  2208. playDialogueAnimation(31, voiceIndex, 143, subTitleX, subTitleY, subTitleW, wsaObj, subTitleFirstFrame, subTitleLastFrame, x, y);
  2209. if (_vm->gameFlags().isTalkie)
  2210. _animCurrentFrame = 21;
  2211. break;
  2212. default:
  2213. break;
  2214. }
  2215. _callbackCurrentFrame++;
  2216. return 0;
  2217. }
  2218. int SeqPlayer_HOF::cbHOF_firates(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2219. uint32 frameEnd = 0;
  2220. int subTitleX = 0;
  2221. int subTitleY = 0;
  2222. int subTitleW = 0;
  2223. uint16 voiceIndex = 0;
  2224. switch (frm) {
  2225. case -2:
  2226. _screen->copyPage(12, 2);
  2227. _screen->copyPage(2, 0);
  2228. _screen->updateScreen();
  2229. doTransition(9);
  2230. frameEnd = _system->getMillis() + 480 * _vm->tickLength();
  2231. printFadingText(76, 240, 40, _textColorMap, 252);
  2232. printFadingText(77, 240, 50, _textColorMap, 252);
  2233. printFadingText(78, 240, 60, _textColorMap, _textColor[0]);
  2234. printFadingText(79, 240, 70, _textColorMap, _textColor[0]);
  2235. printFadingText(80, 240, 80, _textColorMap, _textColor[0]);
  2236. printFadingText(84, 240, 100, _textColorMap, 252);
  2237. printFadingText(85, 240, 110, _textColorMap, _textColor[0]);
  2238. printFadingText(99, 240, 130, _textColorMap, 252);
  2239. printFadingText(100, 240, 140, _textColorMap, _textColor[0]);
  2240. delayUntil(frameEnd);
  2241. setCountDown(0);
  2242. break;
  2243. case 0:
  2244. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  2245. memset(_textColorMap, _textColor[1], 16);
  2246. _textColor[0] = _textColorMap[1] = 0xFF;
  2247. _screen->setTextColorMap(_textColorMap);
  2248. break;
  2249. case 6:
  2250. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 31 : 27);
  2251. break;
  2252. case 14:
  2253. case 15:
  2254. if (!((frm == 15 && !_vm->gameFlags().isTalkie) || (frm == 14 && _vm->gameFlags().isTalkie)))
  2255. break;
  2256. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 31 : 27);
  2257. if (_vm->gameFlags().lang == Common::DE_DEU) {
  2258. subTitleX = 82;
  2259. subTitleY = 84;
  2260. subTitleW = 140;
  2261. } else {
  2262. subTitleX = 74;
  2263. subTitleY = (_vm->gameFlags().lang == Common::FR_FRA) ? 96: 108;
  2264. subTitleW = 80;
  2265. }
  2266. if (_vm->gameFlags().isTalkie)
  2267. voiceIndex = 43;
  2268. playDialogueAnimation(32, voiceIndex, 137, subTitleX, subTitleY, subTitleW, wsaObj, 14, 16, x, y);
  2269. break;
  2270. case 28:
  2271. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 32 : 28);
  2272. break;
  2273. case 29:
  2274. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 33 : 29);
  2275. break;
  2276. case 31:
  2277. if (_vm->gameFlags().isTalkie)
  2278. voiceIndex = 44;
  2279. subTitleX = 90;
  2280. subTitleY = (_vm->gameFlags().lang == Common::DE_DEU) ? 60 : 76;
  2281. subTitleW = 80;
  2282. playDialogueAnimation(33, voiceIndex, 143, subTitleX, subTitleY, subTitleW, wsaObj, 31, 34, x, y);
  2283. break;
  2284. case 35:
  2285. _animDuration = 300;
  2286. break;
  2287. default:
  2288. break;
  2289. }
  2290. _callbackCurrentFrame++;
  2291. return 0;
  2292. }
  2293. int SeqPlayer_HOF::cbHOF_frash(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2294. int tmp = 0;
  2295. switch (frm) {
  2296. case -2:
  2297. _screen->setCurPage(2);
  2298. _screen->clearCurPage();
  2299. _screen->copyPage(2, 12);
  2300. _screen->copyPage(2, 0);
  2301. _screen->updateScreen();
  2302. _callbackCurrentFrame = 0;
  2303. startNestedAnimation(0, kNestedSequenceFiggle);
  2304. break;
  2305. case -1:
  2306. if (_vm->gameFlags().isTalkie)
  2307. playHoFTalkieCredits();
  2308. _talkieFinaleExtraFlag = _vm->gameFlags().isTalkie;
  2309. break;
  2310. case 0:
  2311. if (_callbackCurrentFrame == 1) {
  2312. _vm->sound()->playTrack(4);
  2313. _textColor[1] = _screen->findLeastDifferentColor(_textColorPresets, _screen->getPalette(0), 1, 255) & 0xFF;
  2314. memset(_textColorMap, _textColor[1], 16);
  2315. _textColor[0] = _textColorMap[1] = 0xFF;
  2316. _screen->setTextColorMap(_textColorMap);
  2317. }
  2318. _animDuration = 10;
  2319. break;
  2320. case 1:
  2321. if (_callbackCurrentFrame < 20 && _talkieFinaleExtraFlag) {
  2322. _animCurrentFrame = 0;
  2323. } else {
  2324. _animDuration = _vm->gameFlags().isTalkie ? 500 : (300 + _vm->_rnd.getRandomNumberRng(1, 300));
  2325. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 26 : 22);
  2326. if (_talkieFinaleExtraFlag) {
  2327. _callbackCurrentFrame = 3;
  2328. _talkieFinaleExtraFlag = false;
  2329. }
  2330. }
  2331. break;
  2332. case 2:
  2333. _animDuration = 20;
  2334. break;
  2335. case 3:
  2336. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 27 : 23);
  2337. _animDuration = _vm->gameFlags().isTalkie ? 500 : (300 + _vm->_rnd.getRandomNumberRng(1, 300));
  2338. break;
  2339. case 4:
  2340. _animDuration = 10;
  2341. break;
  2342. case 5:
  2343. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 27 : 23);
  2344. tmp = _callbackCurrentFrame / 6;
  2345. if (tmp == 2)
  2346. _animDuration = _vm->gameFlags().isTalkie ? 7 : (1 + _vm->_rnd.getRandomNumberRng(1, 10));
  2347. else if (tmp < 2)
  2348. _animDuration = _vm->gameFlags().isTalkie ? 500 : (300 + _vm->_rnd.getRandomNumberRng(1, 300));
  2349. break;
  2350. case 6:
  2351. _animDuration = 10;
  2352. tmp = _callbackCurrentFrame / 6;
  2353. if (tmp == 2)
  2354. _animCurrentFrame = 4;
  2355. else if (tmp < 2)
  2356. _animCurrentFrame = 0;
  2357. break;
  2358. case 7:
  2359. _callbackCurrentFrame = 0;
  2360. _animDuration = 5;
  2361. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 26 : 22);
  2362. break;
  2363. case 11:
  2364. if (_callbackCurrentFrame < 8)
  2365. _animCurrentFrame = 8;
  2366. break;
  2367. default:
  2368. break;
  2369. }
  2370. _callbackCurrentFrame++;
  2371. return 0;
  2372. }
  2373. int SeqPlayer_HOF::cbHOF_figgle(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2374. if (_callbackCurrentFrame == 10)
  2375. setCountDown(0);
  2376. if (_callbackCurrentFrame == 10 || _callbackCurrentFrame == 5 || _callbackCurrentFrame == 7)
  2377. playSoundAndDisplaySubTitle(_vm->gameFlags().isTalkie ? 45 : 30);
  2378. _callbackCurrentFrame++;
  2379. return frm;
  2380. }
  2381. int SeqPlayer_HOF::cbHOFDEMO_virgin(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2382. if (!frm)
  2383. delayTicks(50);
  2384. return 0;
  2385. }
  2386. int SeqPlayer_HOF::cbHOFDEMO_westwood(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2387. if (!frm)
  2388. _vm->sound()->playTrack(2);
  2389. return 0;
  2390. }
  2391. int SeqPlayer_HOF::cbHOFDEMO_title(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2392. if (!frm) {
  2393. _vm->sound()->playTrack(3);
  2394. } else if (frm == 25) {
  2395. delayTicks(60);
  2396. setCountDown(0);
  2397. doTransition(0);
  2398. }
  2399. return 0;
  2400. }
  2401. int SeqPlayer_HOF::cbHOFDEMO_hill(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2402. if (!frm) {
  2403. _vm->sound()->playTrack(4);
  2404. } else if (frm == 25) {
  2405. startNestedAnimation(0, kNestedSequenceHoFDemoWater);
  2406. _animDuration--;
  2407. } else if (frm > 25 && frm < 50) {
  2408. if (_animDuration > 3)
  2409. _animDuration--;
  2410. } else if (frm == 95) {
  2411. _animDuration = 70;
  2412. } else if (frm == 96) {
  2413. _animDuration = 7;
  2414. } else if (frm == 129) {
  2415. closeNestedAnimation(0);
  2416. }
  2417. return 0;
  2418. }
  2419. int SeqPlayer_HOF::cbHOFDEMO_outhome(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2420. switch (frm) {
  2421. case 12:
  2422. playSoundAndDisplaySubTitle(4);
  2423. break;
  2424. case 32:
  2425. playSoundAndDisplaySubTitle(7);
  2426. break;
  2427. case 36:
  2428. playSoundAndDisplaySubTitle(10);
  2429. break;
  2430. case 57:
  2431. playSoundAndDisplaySubTitle(9);
  2432. break;
  2433. case 80:
  2434. case 96:
  2435. case 149:
  2436. _animDuration = 70;
  2437. break;
  2438. case 81:
  2439. case 97:
  2440. _animDuration = 5;
  2441. break;
  2442. case 110:
  2443. playSoundAndDisplaySubTitle(5);
  2444. break;
  2445. case 137:
  2446. playSoundAndDisplaySubTitle(6);
  2447. break;
  2448. default:
  2449. break;
  2450. }
  2451. return 0;
  2452. }
  2453. int SeqPlayer_HOF::cbHOFDEMO_wharf(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2454. if (!_callbackCurrentFrame)
  2455. startNestedAnimation(0, kNestedSequenceHoFDemoWharf2);
  2456. switch (frm) {
  2457. case 0:
  2458. playSoundAndDisplaySubTitle(11);
  2459. break;
  2460. case 5:
  2461. if ((_callbackCurrentFrame / 8) <= 2 || _animSlots[0].flags != -1)
  2462. _animCurrentFrame = 0;
  2463. else
  2464. closeNestedAnimation(0);
  2465. break;
  2466. case 6:
  2467. closeNestedAnimation(0);
  2468. break;
  2469. case 8:
  2470. case 10:
  2471. playSoundAndDisplaySubTitle(2);
  2472. break;
  2473. case 13:
  2474. playSoundAndDisplaySubTitle(7);
  2475. break;
  2476. case 16:
  2477. playSoundAndDisplaySubTitle(12);
  2478. break;
  2479. default:
  2480. break;
  2481. }
  2482. _callbackCurrentFrame++;
  2483. return 0;
  2484. }
  2485. int SeqPlayer_HOF::cbHOFDEMO_dinob(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2486. if (frm == 0) {
  2487. if (!(_callbackCurrentFrame/8)) {
  2488. startNestedAnimation(0, kNestedSequenceHoFDemoDinob2);
  2489. _animCurrentFrame = 0;
  2490. }
  2491. } else if (frm == 3) {
  2492. if (_animSlots[0].flags != -1) {
  2493. _animCurrentFrame = 0;
  2494. } else {
  2495. closeNestedAnimation(0);
  2496. _screen->copyPage(2, 12);
  2497. }
  2498. } else if (frm == 4) {
  2499. closeNestedAnimation(0);
  2500. }
  2501. _callbackCurrentFrame++;
  2502. return 0;
  2503. }
  2504. int SeqPlayer_HOF::cbHOFDEMO_fisher(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2505. if (((_system->getMillis() - _fisherAnimCurTime) / (5 * _vm->tickLength())) > 0) {
  2506. _fisherAnimCurTime = _system->getMillis();
  2507. if (!_callbackCurrentFrame) {
  2508. startNestedAnimation(0, kNestedSequenceHoFDemoBail);
  2509. startNestedAnimation(1, kNestedSequenceHoFDemoDig);
  2510. }
  2511. if (_scrollProgressCounter >= 0x18F && !_callbackCurrentFrame)
  2512. return 0;
  2513. if (!_callbackCurrentFrame) {
  2514. _screen->loadBitmap("adtext.cps", 4, 4, 0);
  2515. _screen->loadBitmap("adtext2.cps", 6, 6, 0);
  2516. _screen->copyPageMemory(6, 0, 4, 64000, 1024);
  2517. _screen->copyPageMemory(6, 1023, 6, 0, 64000);
  2518. _scrollProgressCounter = 0;
  2519. }
  2520. updateDemoAdText(24, 144);
  2521. _callbackCurrentFrame++;
  2522. if (_callbackCurrentFrame < 0x256 || _callbackCurrentFrame > 0x31C) {
  2523. if (_callbackCurrentFrame < 0x174 || _callbackCurrentFrame > 0x1D7) {
  2524. if (_callbackCurrentFrame < 0x84 || _callbackCurrentFrame > 0xE7) {
  2525. _scrollProgressCounter++;
  2526. }
  2527. }
  2528. }
  2529. if (_callbackCurrentFrame > 0x31E) {
  2530. closeNestedAnimation(0);
  2531. closeNestedAnimation(1);
  2532. setCountDown(0);
  2533. _screen->copyPage(2, 12);
  2534. }
  2535. } else {
  2536. updateDemoAdText(24, 144);
  2537. }
  2538. return 0;
  2539. }
  2540. int SeqPlayer_HOF::cbHOFDEMO_wharf2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2541. if (frm == 69)
  2542. _animCurrentFrame = 8;
  2543. return frm;
  2544. }
  2545. int SeqPlayer_HOF::cbHOFDEMO_dinob2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2546. switch (frm) {
  2547. case 19:
  2548. playSoundAndDisplaySubTitle(13);
  2549. break;
  2550. case 54:
  2551. playSoundAndDisplaySubTitle(15);
  2552. break;
  2553. case 61:
  2554. playSoundAndDisplaySubTitle(16);
  2555. break;
  2556. case 69:
  2557. playSoundAndDisplaySubTitle(14);
  2558. break;
  2559. case 77:
  2560. playSoundAndDisplaySubTitle(13);
  2561. break;
  2562. case 79:
  2563. _animCurrentFrame = 4;
  2564. break;
  2565. default:
  2566. break;
  2567. }
  2568. return frm;
  2569. }
  2570. int SeqPlayer_HOF::cbHOFDEMO_water(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2571. if (frm == 1)
  2572. playSoundAndDisplaySubTitle(11);
  2573. return frm;
  2574. }
  2575. int SeqPlayer_HOF::cbHOFDEMO_bail(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2576. return frm;
  2577. }
  2578. int SeqPlayer_HOF::cbHOFDEMO_dig(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2579. return frm;
  2580. }
  2581. #ifdef ENABLE_LOL
  2582. int SeqPlayer_HOF::cbLOLDEMO_scene1(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2583. Palette &tmpPal = _screen->getPalette(2);
  2584. if (!(_callbackCurrentFrame % 100)) {
  2585. if (_callbackCurrentFrame == 0) {
  2586. _vm->sound()->haltTrack();
  2587. _vm->sound()->playTrack(6);
  2588. }
  2589. tmpPal.copy(_screen->getPalette(0));
  2590. for (int i = 3; i < 768; i++) {
  2591. tmpPal[i] = ((int)tmpPal[i] * 120) / 64;
  2592. if (tmpPal[i] > 0x3F)
  2593. tmpPal[i] = 0x3F;
  2594. }
  2595. playSoundAndDisplaySubTitle(_vm->_rnd.getRandomBit());
  2596. _screen->setScreenPalette(tmpPal);
  2597. _screen->updateScreen();
  2598. _vm->delay(8);
  2599. } else {
  2600. _screen->setScreenPalette(_screen->getPalette(0));
  2601. _screen->updateScreen();
  2602. if (_callbackCurrentFrame == 40)
  2603. playSoundAndDisplaySubTitle(3);
  2604. }
  2605. _callbackCurrentFrame++;
  2606. return frm;
  2607. }
  2608. int SeqPlayer_HOF::cbLOLDEMO_scene2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2609. switch (frm - 17) {
  2610. case 0:
  2611. _animDuration = 8;
  2612. break;
  2613. case 3:
  2614. case 6:
  2615. case 9:
  2616. playSoundEffect(8, 255 - ((26 - frm) << 3));
  2617. break;
  2618. case 15:
  2619. playSoundAndDisplaySubTitle(9);
  2620. break;
  2621. case 18:
  2622. playSoundAndDisplaySubTitle(2);
  2623. break;
  2624. default:
  2625. break;
  2626. }
  2627. _callbackCurrentFrame++;
  2628. return frm;
  2629. }
  2630. int SeqPlayer_HOF::cbLOLDEMO_scene3(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2631. if (frm == 1)
  2632. playSoundAndDisplaySubTitle(6);
  2633. else if (frm == 24)
  2634. playSoundAndDisplaySubTitle(7);
  2635. _callbackCurrentFrame++;
  2636. return frm;
  2637. }
  2638. int SeqPlayer_HOF::cbLOLDEMO_scene4(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2639. switch (frm) {
  2640. case 11:
  2641. case 14:
  2642. case 17:
  2643. case 20:
  2644. playSoundEffect(8, 255 - ((22 - frm) << 3));
  2645. break;
  2646. case 22:
  2647. playSoundAndDisplaySubTitle(11);
  2648. break;
  2649. case 24:
  2650. playSoundAndDisplaySubTitle(8);
  2651. break;
  2652. case 30:
  2653. playSoundAndDisplaySubTitle(15);
  2654. break;
  2655. case 34:
  2656. playSoundAndDisplaySubTitle(14);
  2657. break;
  2658. case 38:
  2659. playSoundAndDisplaySubTitle(13);
  2660. break;
  2661. case 42:
  2662. playSoundAndDisplaySubTitle(12);
  2663. break;
  2664. default:
  2665. break;
  2666. }
  2667. _callbackCurrentFrame++;
  2668. return frm;
  2669. }
  2670. int SeqPlayer_HOF::cbLOLDEMO_scene5(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2671. switch (_callbackCurrentFrame++) {
  2672. case 0:
  2673. case 4:
  2674. case 6:
  2675. case 8:
  2676. case 10:
  2677. case 14:
  2678. case 16:
  2679. case 18:
  2680. case 20:
  2681. case 22:
  2682. case 24:
  2683. case 26:
  2684. case 28:
  2685. case 30:
  2686. playSoundEffect(15, 255 - ((31 - frm) << 3));
  2687. break;
  2688. case 32:
  2689. playSoundAndDisplaySubTitle(16);
  2690. break;
  2691. case 42:
  2692. playSoundAndDisplaySubTitle(6);
  2693. break;
  2694. default:
  2695. break;
  2696. }
  2697. return frm;
  2698. }
  2699. int SeqPlayer_HOF::cbLOLDEMO_text5(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2700. if (_callbackCurrentFrame++ == 100)
  2701. playSoundAndDisplaySubTitle(5);
  2702. return frm;
  2703. }
  2704. int SeqPlayer_HOF::cbLOLDEMO_scene6(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
  2705. while (_scrollProgressCounter < 290) {
  2706. setCountDown(6);
  2707. if (!_callbackCurrentFrame) {
  2708. _screen->loadBitmap("adtext.cps", 4, 4, 0);
  2709. _screen->loadBitmap("adtext2.cps", 6, 6, 0);
  2710. _screen->copyPageMemory(6, 0, 4, 64000, 1024);
  2711. _screen->copyPageMemory(6, 1023, 6, 0, 64000);
  2712. _scrollProgressCounter = 0;
  2713. }
  2714. if (_callbackCurrentFrame % 175) {
  2715. _screen->setScreenPalette(_screen->getPalette(0));
  2716. } else {
  2717. Palette &tmpPal = _screen->getPalette(2);
  2718. tmpPal.copy(_screen->getPalette(0));
  2719. for (int i = 3; i < 0x300; i++) {
  2720. tmpPal[i] = ((int)tmpPal[i] * 120) / 64;
  2721. if (tmpPal[i] > 0x3F)
  2722. tmpPal[i] = 0x3F;
  2723. }
  2724. playSoundAndDisplaySubTitle(_vm->_rnd.getRandomBit());
  2725. _screen->setScreenPalette(tmpPal);
  2726. _screen->updateScreen();
  2727. _vm->delay(8);
  2728. }
  2729. if (_callbackCurrentFrame == 40 || _callbackCurrentFrame == 80 || _callbackCurrentFrame == 150 || _callbackCurrentFrame == 300)
  2730. playSoundAndDisplaySubTitle(3);
  2731. _screen->copyPage(12, 2);
  2732. updateDemoAdText(70, 130);
  2733. _screen->copyPage(2, 0);
  2734. _screen->updateScreen();
  2735. _callbackCurrentFrame++;
  2736. if (_callbackCurrentFrame < 128 || _callbackCurrentFrame > 207)
  2737. _scrollProgressCounter++;
  2738. while (countDownRunning())
  2739. delayTicks(1);
  2740. }
  2741. _screen->copyPage(2, 12);
  2742. return 0;
  2743. }
  2744. #endif // ENABLE_LOL
  2745. #undef CASE_ALT
  2746. const uint8 SeqPlayer_HOF::_textColorPresets[] = { 0x01, 0x01, 0x00, 0x3F, 0x3F, 0x3F };
  2747. void KyraEngine_HoF::seq_showStarcraftLogo() {
  2748. WSAMovie_v2 *ci = new WSAMovie_v2(this);
  2749. assert(ci);
  2750. _screen->clearPage(2);
  2751. _res->loadPakFile("INTROGEN.PAK");
  2752. int endframe = ci->open("CI.WSA", 0, &_screen->getPalette(0));
  2753. _res->unloadPakFile("INTROGEN.PAK");
  2754. if (!ci->opened()) {
  2755. delete ci;
  2756. return;
  2757. }
  2758. _screen->hideMouse();
  2759. ci->displayFrame(0, 2, 0, 0, 0, 0, 0);
  2760. _screen->copyPage(2, 0);
  2761. _screen->fadeFromBlack();
  2762. for (int i = 1; i < endframe; i++) {
  2763. uint32 end = _system->getMillis() + 50;
  2764. if (skipFlag())
  2765. break;
  2766. ci->displayFrame(i, 2, 0, 0, 0, 0, 0);
  2767. _screen->copyPage(2, 0);
  2768. _screen->updateScreen();
  2769. uint32 cur = _system->getMillis();
  2770. if (end > cur)
  2771. delay(end - cur);
  2772. else
  2773. updateInput();
  2774. }
  2775. if (!skipFlag()) {
  2776. uint32 end = _system->getMillis() + 50;
  2777. ci->displayFrame(0, 2, 0, 0, 0, 0, 0);
  2778. _screen->copyPage(2, 0);
  2779. _screen->updateScreen();
  2780. uint32 cur = _system->getMillis();
  2781. if (end > cur)
  2782. delay(end - cur);
  2783. else
  2784. updateInput();
  2785. }
  2786. _screen->fadeToBlack();
  2787. _screen->showMouse();
  2788. _eventList.clear();
  2789. delete ci;
  2790. }
  2791. int KyraEngine_HoF::seq_playIntro() {
  2792. bool startupSaveLoadable = saveFileLoadable(0);
  2793. return SeqPlayer_HOF(this, _screen, _system, startupSaveLoadable).play(kSequenceVirgin, startupSaveLoadable ? kSequenceTitle : kSequenceNoLooping);
  2794. }
  2795. int KyraEngine_HoF::seq_playOutro() {
  2796. return SeqPlayer_HOF(this, _screen, _system).play(kSequenceFunters, kSequenceFrash);
  2797. }
  2798. int KyraEngine_HoF::seq_playDemo() {
  2799. SeqPlayer_HOF(this, _screen, _system).play(kSequenceHoFDemoVirgin, kSequenceHoFDemoVirgin);
  2800. return 4;
  2801. }
  2802. void KyraEngine_HoF::seq_pausePlayer(bool toggle) {
  2803. SeqPlayer_HOF *activePlayer = SeqPlayer_HOF::instance();
  2804. if (activePlayer)
  2805. activePlayer->pause(toggle);
  2806. }
  2807. #ifdef ENABLE_LOL
  2808. int LoLEngine::playDemo() {
  2809. SeqPlayer_HOF(this, _screen, _system).play(kSequenceLoLDemoScene1, kSequenceLoLDemoScene1);
  2810. return -1;
  2811. }
  2812. void LoLEngine::pauseDemoPlayer(bool toggle) {
  2813. SeqPlayer_HOF *activePlayer = SeqPlayer_HOF::instance();
  2814. if (activePlayer)
  2815. activePlayer->pause(toggle);
  2816. }
  2817. #endif // ENABLE_LOL
  2818. #pragma mark -
  2819. #pragma mark - Ingame sequences
  2820. #pragma mark -
  2821. void KyraEngine_HoF::seq_makeBookOrCauldronAppear(int type) {
  2822. _screen->hideMouse();
  2823. showMessage(0, 0xCF);
  2824. if (type == 1)
  2825. seq_makeBookAppear();
  2826. else if (type == 2)
  2827. loadInvWsa("CAULDRON.WSA", 1, 6, 0, -2, -2, 1);
  2828. _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _screenBuffer);
  2829. _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0);
  2830. static const uint8 bookCauldronRects[] = {
  2831. 0x46, 0x90, 0x7F, 0x2B, // unknown rect (maybe unused?)
  2832. 0xCE, 0x90, 0x2C, 0x2C, // book rect
  2833. 0xFA, 0x90, 0x46, 0x2C // cauldron rect
  2834. };
  2835. int x = bookCauldronRects[type*4+0];
  2836. int y = bookCauldronRects[type*4+1];
  2837. int w = bookCauldronRects[type*4+2];
  2838. int h = bookCauldronRects[type*4+3];
  2839. _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
  2840. _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer);
  2841. if (type == 2) {
  2842. int32 countdown = _rnd.getRandomNumberRng(45, 80);
  2843. _timer->setCountdown(2, countdown * 60);
  2844. }
  2845. _screen->showMouse();
  2846. }
  2847. void KyraEngine_HoF::seq_makeBookAppear() {
  2848. _screen->hideMouse();
  2849. displayInvWsaLastFrame();
  2850. showMessage(0, 0xCF);
  2851. loadInvWsa("BOOK2.WSA", 0, 4, 2, -1, -1, 0);
  2852. uint8 *rect = new uint8[_screen->getRectSize(_invWsa.w, _invWsa.h)];
  2853. assert(rect);
  2854. _screen->copyRegionToBuffer(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect);
  2855. _invWsa.running = false;
  2856. snd_playSoundEffect(0xAF);
  2857. while (true) {
  2858. _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength;
  2859. _screen->copyBlockToPage(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect);
  2860. _invWsa.wsa->displayFrame(_invWsa.curFrame, _invWsa.page, 0, 0, 0x4000, 0, 0);
  2861. if (_invWsa.page)
  2862. _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK);
  2863. ++_invWsa.curFrame;
  2864. if (_invWsa.curFrame >= _invWsa.lastFrame && !shouldQuit())
  2865. break;
  2866. switch (_invWsa.curFrame) {
  2867. case 39:
  2868. snd_playSoundEffect(0xCA);
  2869. break;
  2870. case 50:
  2871. snd_playSoundEffect(0x6A);
  2872. break;
  2873. case 72:
  2874. snd_playSoundEffect(0xCB);
  2875. break;
  2876. case 85:
  2877. snd_playSoundEffect(0x38);
  2878. break;
  2879. default:
  2880. break;
  2881. }
  2882. do {
  2883. update();
  2884. } while (_invWsa.timer > _system->getMillis() && !skipFlag());
  2885. }
  2886. closeInvWsa();
  2887. delete[] rect;
  2888. _invWsa.running = false;
  2889. _screen->showMouse();
  2890. }
  2891. } // End of namespace Kyra