PageRenderTime 74ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/engines/kyra/script/script_hof.cpp

http://github.com/scummvm/scummvm
C++ | 1744 lines | 1375 code | 260 blank | 109 comment | 242 complexity | 82ce63348b31085f7f0b5b93e9e73c6d MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  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/engine/timer.h"
  24. #include "kyra/resource/resource.h"
  25. #include "kyra/sound/sound.h"
  26. #include "common/system.h"
  27. namespace Kyra {
  28. int KyraEngine_HoF::o2_setCharacterFacingRefresh(EMCState *script) {
  29. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
  30. int animFrame = stackPos(2);
  31. if (animFrame >= 0)
  32. _mainCharacter.animFrame = animFrame;
  33. _mainCharacter.facing = stackPos(1);
  34. updateCharacterAnim(0);
  35. refreshAnimObjectsIfNeed();
  36. return 0;
  37. }
  38. int KyraEngine_HoF::o2_setCharacterPos(EMCState *script) {
  39. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterFacingRefresh(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
  40. int x = stackPos(1);
  41. int y = stackPos(2);
  42. if (x != -1 && y != -1) {
  43. x &= ~3;
  44. y &= ~1;
  45. }
  46. restorePage3();
  47. _mainCharacter.x2 = _mainCharacter.x1 = x;
  48. _mainCharacter.y2 = _mainCharacter.y1 = y;
  49. return 0;
  50. }
  51. int KyraEngine_HoF::o2_defineObject(EMCState *script) {
  52. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineObject(%p) (%d, '%s', %d, %d, %d, %d)", (const void *)script,
  53. stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
  54. TalkObject *object = &_talkObjectList[stackPos(0)];
  55. strcpy(object->filename, stackPosString(1));
  56. object->scriptId = stackPos(2);
  57. object->x = stackPos(3);
  58. object->y = stackPos(4);
  59. object->color = stackPos(5);
  60. return 0;
  61. }
  62. int KyraEngine_HoF::o2_refreshCharacter(EMCState *script) {
  63. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_refreshCharacter(%p) (-, %d, %d, %d)", (const void *)script, stackPos(1), stackPos(2), stackPos(3));
  64. int unk = stackPos(1);
  65. int facing = stackPos(2);
  66. int refresh = stackPos(3);
  67. if (facing >= 0)
  68. _mainCharacter.facing = facing;
  69. if (unk >= 0 && unk != 32)
  70. _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
  71. updateCharacterAnim(0);
  72. if (refresh)
  73. refreshAnimObjectsIfNeed();
  74. return 0;
  75. }
  76. int KyraEngine_HoF::o2_setSceneComment(EMCState *script) {
  77. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneComment(%p) ('%s')", (const void *)script, stackPosString(0));
  78. _sceneCommentString = stackPosString(0);
  79. return 0;
  80. }
  81. int KyraEngine_HoF::o2_setCharacterAnimFrame(EMCState *script) {
  82. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharacterAnimFrame(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
  83. int animFrame = stackPos(1);
  84. int updateAnim = stackPos(2);
  85. _mainCharacter.animFrame = animFrame;
  86. if (updateAnim)
  87. updateCharacterAnim(0);
  88. return 0;
  89. }
  90. int KyraEngine_HoF::o2_customCharacterChat(EMCState *script) {
  91. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customCharacterChat(%p) ('%s', %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
  92. playVoice(_vocHigh, stackPos(4));
  93. _text->printCustomCharacterText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), 0, 2);
  94. return 0;
  95. }
  96. int KyraEngine_HoF::o2_soundFadeOut(EMCState *script) {
  97. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_soundFadeOut(%p) ()", (const void *)script);
  98. _sound->beginFadeOut();
  99. return 0;
  100. }
  101. int KyraEngine_HoF::o2_showChapterMessage(EMCState *script) {
  102. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showChapterMessage(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  103. showChapterMessage(stackPos(0), stackPos(1));
  104. return 0;
  105. }
  106. int KyraEngine_HoF::o2_restoreTalkTextMessageBkgd(EMCState *script) {
  107. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreTalkTextMessageBkgd(%p) ()", (const void *)script);
  108. _text->restoreTalkTextMessageBkgd(2, 0);
  109. return 0;
  110. }
  111. int KyraEngine_HoF::o2_wsaClose(EMCState *script) {
  112. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wsaClose(%p) (%d)", (const void *)script, stackPos(0));
  113. assert(stackPos(0) >= 0 && stackPos(0) < ARRAYSIZE(_wsaSlots));
  114. _wsaSlots[stackPos(0)]->close();
  115. return 0;
  116. }
  117. int KyraEngine_HoF::o2_meanWhileScene(EMCState *script) {
  118. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_meanWhileScene(%p) (%d)", (const void *)script, stackPos(0));
  119. static const uint8 jpSubtitle[] = { 0x88, 0xEA, 0x95, 0xFB, 0x81, 0x45, 0x81, 0x45, 0x81, 0x45 };
  120. const char *cpsfile = stackPosString(0);
  121. const char *palfile = stackPosString(1);
  122. _screen->loadBitmap(cpsfile, 3, 3, 0);
  123. _screen->copyPalette(2, 0);
  124. _screen->loadPalette(palfile, _screen->getPalette(2));
  125. _screen->fillRect(0, 0, 319, 199, 207);
  126. _screen->setScreenPalette(_screen->getPalette(2));
  127. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  128. if (!scumm_stricmp(cpsfile, "_MEANWIL.CPS") && _flags.lang == Common::JA_JPN) {
  129. Screen::FontId o = _screen->setFont(Screen::FID_SJIS_FNT);
  130. _screen->printText((const char *)jpSubtitle, 140, 176, 255, 132);
  131. _screen->setFont(o);
  132. }
  133. _screen->updateScreen();
  134. return 0;
  135. }
  136. int KyraEngine_HoF::o2_backUpScreen(EMCState *script) {
  137. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_backUpScreen(%p) (%d)", (const void *)script, stackPos(0));
  138. _screen->copyRegionToBuffer(stackPos(0), 0, 0, 320, 144, _screenBuffer);
  139. return 0;
  140. }
  141. int KyraEngine_HoF::o2_restoreScreen(EMCState *script) {
  142. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreScreen(%p) (%d)", (const void *)script, stackPos(0));
  143. _screen->copyBlockToPage(stackPos(0), 0, 0, 320, 144, _screenBuffer);
  144. return 0;
  145. }
  146. int KyraEngine_HoF::o2_displayWsaFrame(EMCState *script) {
  147. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaFrame(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
  148. stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8));
  149. int frame = stackPos(0);
  150. int x = stackPos(1);
  151. int y = stackPos(2);
  152. int waitTime = stackPos(3);
  153. int slot = stackPos(4);
  154. int copyParam = stackPos(5);
  155. int doUpdate = stackPos(6);
  156. int dstPage = stackPos(7);
  157. int backUp = stackPos(8);
  158. _screen->hideMouse();
  159. const uint32 endTime = _system->getMillis() + waitTime * _tickLength;
  160. _wsaSlots[slot]->displayFrame(frame, dstPage, x, y, copyParam | 0xC000, 0, 0);
  161. _screen->updateScreen();
  162. if (backUp)
  163. memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
  164. delayUntil(endTime, false, doUpdate != 0);
  165. _screen->showMouse();
  166. return 0;
  167. }
  168. int KyraEngine_HoF::o2_displayWsaSequentialFramesLooping(EMCState *script) {
  169. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaSequentialFramesLooping(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script,
  170. stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
  171. int startFrame = stackPos(0);
  172. int endFrame = stackPos(1);
  173. int x = stackPos(2);
  174. int y = stackPos(3);
  175. int waitTime = stackPos(4);
  176. int slot = stackPos(5);
  177. int maxTimes = stackPos(6);
  178. int copyFlags = stackPos(7);
  179. if (maxTimes > 1)
  180. maxTimes = 1;
  181. _screen->hideMouse();
  182. int curTime = 0;
  183. while (curTime < maxTimes) {
  184. if (startFrame < endFrame) {
  185. for (int i = startFrame; i <= endFrame; ++i) {
  186. const uint32 endTime = _system->getMillis() + waitTime * _tickLength;
  187. _wsaSlots[slot]->displayFrame(i, 0, x, y, 0xC000 | copyFlags, 0, 0);
  188. if (!skipFlag()) {
  189. _screen->updateScreen();
  190. delayUntil(endTime, false, true);
  191. }
  192. }
  193. } else {
  194. for (int i = startFrame; i >= endFrame; --i) {
  195. const uint32 endTime = _system->getMillis() + waitTime * _tickLength;
  196. _wsaSlots[slot]->displayFrame(i, 0, x, y, 0xC000 | copyFlags, 0, 0);
  197. if (!skipFlag()) {
  198. _screen->updateScreen();
  199. delayUntil(endTime, false, true);
  200. }
  201. }
  202. }
  203. ++curTime;
  204. }
  205. resetSkipFlag();
  206. _screen->showMouse();
  207. return 0;
  208. }
  209. int KyraEngine_HoF::o2_wsaOpen(EMCState *script) {
  210. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wsaOpen(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
  211. assert(stackPos(1) >= 0 && stackPos(1) < ARRAYSIZE(_wsaSlots));
  212. _wsaSlots[stackPos(1)]->open(stackPosString(0), 1, 0);
  213. return 0;
  214. }
  215. int KyraEngine_HoF::o2_displayWsaSequentialFrames(EMCState *script) {
  216. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaSequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6));
  217. uint16 frameDelay = stackPos(2) * _tickLength;
  218. uint16 currentFrame = stackPos(3);
  219. uint16 lastFrame = stackPos(4);
  220. uint16 index = stackPos(5);
  221. uint16 copyParam = stackPos(6) | 0xC000;
  222. _screen->hideMouse();
  223. while (currentFrame <= lastFrame) {
  224. const uint32 endTime = _system->getMillis() + frameDelay;
  225. _wsaSlots[index]->displayFrame(currentFrame++, 0, stackPos(0), stackPos(1), copyParam, 0, 0);
  226. if (!skipFlag()) {
  227. _screen->updateScreen();
  228. delayUntil(endTime);
  229. }
  230. }
  231. resetSkipFlag();
  232. _screen->showMouse();
  233. return 0;
  234. }
  235. int KyraEngine_HoF::o2_displayWsaSequence(EMCState *script) {
  236. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_displayWsaSequence(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
  237. const int frameDelay = stackPos(2) * _tickLength;
  238. const int index = stackPos(3);
  239. const bool doUpdate = (stackPos(4) != 0);
  240. const uint16 copyParam = stackPos(5) | 0xC000;
  241. _screen->hideMouse();
  242. int currentFrame = 0;
  243. const int lastFrame = _wsaSlots[index]->frames();
  244. while (currentFrame <= lastFrame) {
  245. const uint32 endTime = _system->getMillis() + frameDelay;
  246. _wsaSlots[index]->displayFrame(currentFrame++, 0, stackPos(0), stackPos(1), copyParam, 0, 0);
  247. if (!skipFlag()) {
  248. if (doUpdate)
  249. update();
  250. _screen->updateScreen();
  251. delayUntil(endTime);
  252. }
  253. }
  254. resetSkipFlag();
  255. _screen->showMouse();
  256. return 0;
  257. }
  258. int KyraEngine_HoF::o2_addItemToInventory(EMCState *script) {
  259. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addItemToInventory(%p) (%d, -, %d)", (const void *)script, stackPos(0), stackPos(2));
  260. int slot = findFreeVisibleInventorySlot();
  261. if (slot != -1) {
  262. _mainCharacter.inventory[slot] = stackPos(0);
  263. if (stackPos(2))
  264. redrawInventory(0);
  265. }
  266. return slot;
  267. }
  268. int KyraEngine_HoF::o2_drawShape(EMCState *script) {
  269. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
  270. uint8 *shp = getShapePtr(stackPos(0) + 64);
  271. int x = stackPos(1);
  272. int y = stackPos(2);
  273. uint8 dsFlag = stackPos(3) & 0xFF;
  274. uint8 modeFlag = stackPos(4) & 0xFF;
  275. if (modeFlag) {
  276. _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0);
  277. } else {
  278. restorePage3();
  279. _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0);
  280. memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
  281. _screen->drawShape(0, shp, x, y, 2, dsFlag ? 1 : 0);
  282. flagAnimObjsForRefresh();
  283. flagAnimObjsSpecialRefresh();
  284. refreshAnimObjectsIfNeed();
  285. }
  286. return 0;
  287. }
  288. int KyraEngine_HoF::o2_addItemToCurScene(EMCState *script) {
  289. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addItemToCurScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
  290. const int16 id = stackPos(0);
  291. int x = stackPos(1);
  292. int y = stackPos(2);
  293. int freeItem = findFreeItem();
  294. x = MAX(14, x);
  295. x = MIN(304, x);
  296. y = MAX(14, y);
  297. y = MIN(136, y);
  298. if (freeItem >= 0) {
  299. _itemList[freeItem].id = id;
  300. _itemList[freeItem].x = x;
  301. _itemList[freeItem].y = y;
  302. _itemList[freeItem].sceneId = _mainCharacter.sceneId;
  303. addItemToAnimList(freeItem);
  304. refreshAnimObjectsIfNeed();
  305. }
  306. return 0;
  307. }
  308. int KyraEngine_HoF::o2_loadSoundFile(EMCState *script) {
  309. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0));
  310. if (_flags.platform == Common::kPlatformDOS)
  311. snd_loadSoundFile(stackPos(0));
  312. return 0;
  313. }
  314. int KyraEngine_HoF::o2_removeSlotFromInventory(EMCState *script) {
  315. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeSlotFromInventory(%p) (%d)", (const void *)script, stackPos(0));
  316. removeSlotFromInventory(stackPos(0));
  317. return 0;
  318. }
  319. int KyraEngine_HoF::o2_removeItemFromInventory(EMCState *script) {
  320. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeItemFromInventory(%p) (%d)", (const void *)script, stackPos(0));
  321. uint16 item = stackPos(0);
  322. int slot = -1;
  323. while ((slot = getInventoryItemSlot(item)) != -1)
  324. removeSlotFromInventory(slot);
  325. return 0;
  326. }
  327. int KyraEngine_HoF::o2_countItemInInventory(EMCState *script) {
  328. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemInInventory(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  329. uint16 item = stackPos(1);
  330. int count = 0;
  331. for (int i = 0; i < 20; ++i) {
  332. if (_mainCharacter.inventory[i] == item)
  333. ++count;
  334. }
  335. if ((stackPos(0) == 0) && _itemInHand == int16(item))
  336. ++count;
  337. return count;
  338. }
  339. int KyraEngine_HoF::o2_countItemsInScene(EMCState *script) {
  340. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemsInScene(%p) (%d)", (const void *)script, stackPos(0));
  341. int count = 0;
  342. for (int i = 0; i < 30; ++i) {
  343. if (_itemList[i].sceneId == stackPos(0) && _itemList[i].id != kItemNone)
  344. ++count;
  345. }
  346. return count;
  347. }
  348. int KyraEngine_HoF::o2_wipeDownMouseItem(EMCState *script) {
  349. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_wipeDownMouseItem(%p) (-, %d, %d)", (const void *)script, stackPos(1), stackPos(2));
  350. _screen->hideMouse();
  351. const int x = stackPos(1) - 8;
  352. const int y = stackPos(2) - 15;
  353. if (_itemInHand >= 0) {
  354. backUpGfxRect32x32(x, y);
  355. uint8 *shape = getShapePtr(_itemInHand+64);
  356. for (int curY = y, height = 16; height > 0; height -= 2, curY += 2) {
  357. restoreGfxRect32x32(x, y);
  358. _screen->setNewShapeHeight(shape, height);
  359. uint32 waitTime = _system->getMillis() + _tickLength;
  360. _screen->drawShape(0, shape, x, curY, 0, 0);
  361. _screen->updateScreen();
  362. delayUntil(waitTime);
  363. }
  364. restoreGfxRect32x32(x, y);
  365. _screen->resetShapeHeight(shape);
  366. }
  367. _screen->showMouse();
  368. removeHandItem();
  369. return 0;
  370. }
  371. int KyraEngine_HoF::o2_getElapsedSecs(EMCState *script) {
  372. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getElapsedSecs(%p) ()", (const void *)script);
  373. return _system->getMillis() / 1000;
  374. }
  375. int KyraEngine_HoF::o2_getTimerDelay(EMCState *script) {
  376. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getTimerDelay(%p) (%d)", (const void *)script, stackPos(0));
  377. return _timer->getDelay(stackPos(0));
  378. }
  379. int KyraEngine_HoF::o2_playCompleteSoundEffect(EMCState *script) {
  380. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playCompleteSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
  381. snd_playSoundEffect(stackPos(0));
  382. // The following code is derived from HOFCD MAINWIN.EXE. MAINDOS.EXE has the "normal" o1_playSoundEffect() opcode here (the
  383. // way we had implemented it before this fix). This was actually the cause of bug #3721. I have verified with the DOSBox
  384. // debugger that it really runs the MAINWIN.EXE code and in particular this opcode with the wait loop.
  385. // This loop waits for complete silence on all 4 pcm sound channels. Meanwhile it prevents any scripts from starting more
  386. // sound effects while the loop is active (actually, only opcode 0x59 gets blocked). The whole thing looks a bit like a last
  387. // minute hack....
  388. while (_sound->voiceIsPlaying() && !skipFlag() && !shouldQuit()) {
  389. _preventScriptSfx = true;
  390. delay(10, true);
  391. _preventScriptSfx = false;
  392. }
  393. return 0;
  394. }
  395. int KyraEngine_HoF::o2_delaySecs(EMCState *script) {
  396. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_delaySecs(%p) (%d)", (const void *)script, stackPos(0));
  397. delay(stackPos(0) * 1000, true);
  398. return 0;
  399. }
  400. int KyraEngine_HoF::o2_setTimerDelay(EMCState *script) {
  401. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setTimerDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  402. _timer->setDelay(stackPos(0), stackPos(1));
  403. return 0;
  404. }
  405. int KyraEngine_HoF::o2_setScaleTableItem(EMCState *script) {
  406. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setScaleTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  407. setScaleTableItem(stackPos(0), stackPos(1));
  408. return 0;
  409. }
  410. int KyraEngine_HoF::o2_setDrawLayerTableItem(EMCState *script) {
  411. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setDrawLayerTableItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  412. setDrawLayerTableEntry(stackPos(0), stackPos(1));
  413. return 0;
  414. }
  415. int KyraEngine_HoF::o2_setCharPalEntry(EMCState *script) {
  416. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCharPalEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  417. setCharPalEntry(stackPos(0), stackPos(1));
  418. return 0;
  419. }
  420. int KyraEngine_HoF::o2_loadZShapes(EMCState *script) {
  421. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadZShapes(%p) (%d)", (const void *)script, stackPos(0));
  422. loadCharacterShapes(stackPos(0));
  423. return 0;
  424. }
  425. int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) {
  426. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShape(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1),
  427. stackPos(2), stackPos(3));
  428. int shape = stackPos(0);
  429. int x = stackPos(1);
  430. int y = stackPos(2);
  431. int flag = (stackPos(3) != 0) ? 1 : 0;
  432. restorePage3();
  433. _screen->drawShape(2, _sceneShapeTable[shape], x, y, 2, flag);
  434. memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
  435. _screen->drawShape(0, _sceneShapeTable[shape], x, y, 2, flag);
  436. flagAnimObjsSpecialRefresh();
  437. flagAnimObjsForRefresh();
  438. refreshAnimObjectsIfNeed();
  439. return 0;
  440. }
  441. int KyraEngine_HoF::o2_drawSceneShapeOnPage(EMCState *script) {
  442. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShapeOnPage(%p) (%d, %d, %d, %d, %d)", (const void *)script,
  443. stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
  444. int shape = stackPos(0);
  445. int x = stackPos(1);
  446. int y = stackPos(2);
  447. int flag = stackPos(3);
  448. int drawPage = stackPos(4);
  449. _screen->drawShape(drawPage, _sceneShapeTable[shape], x, y, 2, flag ? 1 : 0);
  450. return 0;
  451. }
  452. int KyraEngine_HoF::o2_disableAnimObject(EMCState *script) {
  453. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_disableAnimObject(%p) (%d)", (const void *)script, stackPos(0));
  454. _animObjects[stackPos(0)+1].enabled = false;
  455. return 0;
  456. }
  457. int KyraEngine_HoF::o2_enableAnimObject(EMCState *script) {
  458. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enableAnimObject(%p) (%d)", (const void *)script, stackPos(0));
  459. _animObjects[stackPos(0)+1].enabled = true;
  460. return 0;
  461. }
  462. int KyraEngine_HoF::o2_loadPalette384(EMCState *script) {
  463. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadPalette384(%p) ('%s')", (const void *)script, stackPosString(0));
  464. _screen->copyPalette(1, 0);
  465. _res->loadFileToBuf(stackPosString(0), _screen->getPalette(1).getData(), 384);
  466. return 0;
  467. }
  468. int KyraEngine_HoF::o2_setPalette384(EMCState *script) {
  469. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setPalette384(%p) ()", (const void *)script);
  470. _screen->getPalette(0).copy(_screen->getPalette(1), 0, 128);
  471. _screen->setScreenPalette(_screen->getPalette(0));
  472. return 0;
  473. }
  474. int KyraEngine_HoF::o2_restoreBackBuffer(EMCState *script) {
  475. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreBackBuffer(%p) (%d)", (const void *)script, stackPos(0));
  476. int disable = stackPos(0);
  477. int oldState = 0;
  478. if (disable) {
  479. oldState = _animObjects[0].enabled;
  480. _animObjects[0].enabled = 0;
  481. }
  482. restorePage3();
  483. if (disable)
  484. _animObjects[0].enabled = (oldState != 0);
  485. return 0;
  486. }
  487. int KyraEngine_HoF::o2_backUpInventoryGfx(EMCState *script) {
  488. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_backUpInventoryGfx(%p) ()", (const void *)script);
  489. _screen->copyRegionToBuffer(1, 0, 144, 320, 56, _screenBuffer);
  490. _inventorySaved = true;
  491. return 0;
  492. }
  493. int KyraEngine_HoF::o2_disableSceneAnim(EMCState *script) {
  494. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_disableSceneAnim(%p) (%d)", (const void *)script, stackPos(0));
  495. _sceneAnims[stackPos(0)].flags &= ~1;
  496. return 0;
  497. }
  498. int KyraEngine_HoF::o2_enableSceneAnim(EMCState *script) {
  499. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enableSceneAnim(%p) (%d)", (const void *)script, stackPos(0));
  500. _sceneAnims[stackPos(0)].flags |= 1;
  501. return 0;
  502. }
  503. int KyraEngine_HoF::o2_restoreInventoryGfx(EMCState *script) {
  504. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_restoreInventoryGfx(%p) ()", (const void *)script);
  505. _screen->copyBlockToPage(1, 0, 144, 320, 56, _screenBuffer);
  506. _inventorySaved = false;
  507. return 0;
  508. }
  509. int KyraEngine_HoF::o2_setSceneAnimPos2(EMCState *script) {
  510. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneAnimPos2(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
  511. _sceneAnims[stackPos(0)].x2 = stackPos(1);
  512. _sceneAnims[stackPos(0)].y2 = stackPos(2);
  513. return 0;
  514. }
  515. int KyraEngine_HoF::o2_fadeScenePal(EMCState *script) {
  516. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_fadeScenePal(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  517. fadeScenePal(stackPos(0), stackPos(1));
  518. return 0;
  519. }
  520. int KyraEngine_HoF::o2_enterNewScene(EMCState *script) {
  521. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0),
  522. stackPos(1), stackPos(2), stackPos(3), stackPos(4));
  523. int skipNpcScript = stackPos(3);
  524. enterNewScene(stackPos(0), stackPos(1), stackPos(2), skipNpcScript, stackPos(4));
  525. if (!skipNpcScript)
  526. runSceneScript4(0);
  527. _unk5 = 1;
  528. if (_mainCharX == -1 || _mainCharY == -1) {
  529. _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
  530. updateCharacterAnim(0);
  531. }
  532. return 0;
  533. }
  534. int KyraEngine_HoF::o2_switchScene(EMCState *script) {
  535. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_switchScene(%p) (%d)", (const void *)script, stackPos(0));
  536. setGameFlag(0x1EF);
  537. _mainCharX = _mainCharacter.x1;
  538. _mainCharY = _mainCharacter.y1;
  539. _noScriptEnter = false;
  540. enterNewScene(stackPos(0), _mainCharacter.facing, 0, 0, 0);
  541. _noScriptEnter = true;
  542. return 0;
  543. }
  544. int KyraEngine_HoF::o2_setPathfinderFlag(EMCState *script) {
  545. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setPathfinderFlag(%p) (%d)", (const void *)script, stackPos(0));
  546. _pathfinderFlag = stackPos(0);
  547. return 0;
  548. }
  549. int KyraEngine_HoF::o2_getSceneExitToFacing(EMCState *script) {
  550. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getSceneExitToFacing(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  551. const int scene = stackPos(0);
  552. const int facing = stackPos(1);
  553. if (facing == 0)
  554. return (int16)_sceneList[scene].exit1;
  555. else if (facing == 2)
  556. return (int16)_sceneList[scene].exit2;
  557. else if (facing == 4)
  558. return (int16)_sceneList[scene].exit3;
  559. else if (facing == 6)
  560. return (int16)_sceneList[scene].exit4;
  561. return -1;
  562. }
  563. int KyraEngine_HoF::o2_setLayerFlag(EMCState *script) {
  564. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setLayerFlag(%p) (%d)", (const void *)script, stackPos(0));
  565. int layer = stackPos(0);
  566. if (layer >= 1 && layer <= 16)
  567. _layerFlagTable[layer] = 1;
  568. return 0;
  569. }
  570. int KyraEngine_HoF::o2_setZanthiaPos(EMCState *script) {
  571. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setZanthiaPos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  572. _mainCharX = stackPos(0);
  573. _mainCharY = stackPos(1);
  574. if (_mainCharX == -1 && _mainCharY == -1)
  575. _mainCharacter.animFrame = 32;
  576. else
  577. _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing];
  578. return 0;
  579. }
  580. int KyraEngine_HoF::o2_loadMusicTrack(EMCState *script) {
  581. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadMusicTrack(%p) (%d)", (const void *)script, stackPos(0));
  582. snd_loadSoundFile(stackPos(0));
  583. return 0;
  584. }
  585. int KyraEngine_HoF::o2_setSceneAnimPos(EMCState *script) {
  586. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setSceneAnimPos(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
  587. _sceneAnims[stackPos(0)].x = stackPos(1);
  588. _sceneAnims[stackPos(0)].y = stackPos(2);
  589. return 0;
  590. }
  591. int KyraEngine_HoF::o2_setCauldronState(EMCState *script) {
  592. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCauldronState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  593. setCauldronState(stackPos(0), stackPos(1) != 0);
  594. clearCauldronTable();
  595. return 0;
  596. }
  597. int KyraEngine_HoF::o2_showItemString(EMCState *script) {
  598. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showItemString(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  599. const int item = stackPos(0);
  600. int string = 0;
  601. if (stackPos(1) == 1) {
  602. if (_lang == 1)
  603. string = getItemCommandStringPickUp(item);
  604. else
  605. string = 7;
  606. } else {
  607. if (_lang == 1)
  608. string = getItemCommandStringInv(item);
  609. else
  610. string = 8;
  611. }
  612. updateCommandLineEx(item+54, string, 0xD6);
  613. return 0;
  614. }
  615. int KyraEngine_HoF::o2_isAnySoundPlaying(EMCState *script) {
  616. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isAnySoundPlaying(%p) ()", (const void *)script);
  617. // WORKAROUND
  618. //
  619. // The input script function in the skull scene does busy wait
  620. // for the sound effect, which is played after completing the
  621. // song, to finish. To avoid too much CPU use, we add some slight
  622. // delay here.
  623. //
  624. // Also the Nintendo DS backend seems only to update the sound, when
  625. // either OSystem::updateScreen or OSystem::delayMillis is called.
  626. // So we have to call delay here, since otherwise the game would hang.
  627. #ifndef __DS__
  628. if (_currentScene == 16 && _currentChapter == 1)
  629. #endif
  630. delay(_tickLength);
  631. return _sound->voiceIsPlaying() ? 1 : 0;
  632. }
  633. int KyraEngine_HoF::o2_setDrawNoShapeFlag(EMCState *script) {
  634. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setDrawNoShapeFlag(%p) (%d)", (const void *)script, stackPos(0));
  635. _drawNoShapeFlag = (stackPos(0) != 0);
  636. return 0;
  637. }
  638. int KyraEngine_HoF::o2_setRunFlag(EMCState *script) {
  639. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setRunFlag(%p) (%d)", (const void *)script, stackPos(0));
  640. // this is usually just _runFlag, but since this is just used when the game should play the credits
  641. // we handle it a bit different :-)
  642. _showOutro = true;
  643. _runFlag = false;
  644. return 0;
  645. }
  646. int KyraEngine_HoF::o2_showLetter(EMCState *script) {
  647. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_showLetter(%p) (%d)", (const void *)script, stackPos(0));
  648. const int letter = stackPos(0);
  649. char filename[16];
  650. _screen->hideMouse();
  651. showMessage(0, 0xCF);
  652. displayInvWsaLastFrame();
  653. backUpPage0();
  654. _screen->copyPalette(2, 0);
  655. _screen->clearPage(3);
  656. _screen->loadBitmap("_NOTE.CPS", 3, 3, 0);
  657. sprintf(filename, "_NTEPAL%.1d.COL", letter+1);
  658. _screen->loadPalette(filename, _screen->getPalette(0));
  659. _screen->fadeToBlack(0x14);
  660. sprintf(filename, "LETTER%.1d.%s", letter, _languageExtension[_lang]);
  661. uint8 *letterBuffer = _res->fileData(filename, 0);
  662. if (!letterBuffer) {
  663. // some floppy versions use a TXT extension
  664. sprintf(filename, "LETTER%.1d.TXT", letter);
  665. letterBuffer = _res->fileData(filename, 0);
  666. }
  667. if (letterBuffer) {
  668. bookDecodeText(letterBuffer);
  669. bookPrintText(2, letterBuffer, 0xC, 0xA, 0x20);
  670. }
  671. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
  672. _screen->fadePalette(_screen->getPalette(0), 0x14);
  673. _screen->setMouseCursor(0, 0, getShapePtr(0));
  674. setMousePos(280, 160);
  675. _screen->showMouse();
  676. bool running = true;
  677. while (running) {
  678. int inputFlag = checkInput(0);
  679. removeInputTop();
  680. if (inputFlag == 198 || inputFlag == 199)
  681. running = false;
  682. _screen->updateScreen();
  683. _system->delayMillis(10);
  684. }
  685. _screen->hideMouse();
  686. _screen->fadeToBlack(0x14);
  687. restorePage0();
  688. _screen->copyPalette(0, 2);
  689. _screen->fadePalette(_screen->getPalette(0), 0x14);
  690. setHandItem(_itemInHand);
  691. _screen->showMouse();
  692. return 0;
  693. }
  694. int KyraEngine_HoF::o2_playFireflyScore(EMCState *script) {
  695. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playFireflyScore(%p) ()", (const void *)script);
  696. if ((_sound->getSfxType() == Sound::kAdLib || _sound->getSfxType() == Sound::kPCSpkr || _sound->getSfxType() == Sound::kMidiMT32 ||
  697. _sound->getSfxType() == Sound::kMidiGM) && !_sound->useDigitalSfx()) {
  698. snd_playWanderScoreViaMap(86, 1);
  699. return 1;
  700. } else {
  701. return 0;
  702. }
  703. }
  704. int KyraEngine_HoF::o2_encodeShape(EMCState *script) {
  705. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_encodeShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1),
  706. stackPos(2), stackPos(3), stackPos(4));
  707. _sceneShapeTable[stackPos(0)] = _screen->encodeShape(stackPos(1), stackPos(2), stackPos(3), stackPos(4), 2);
  708. return 0;
  709. }
  710. int KyraEngine_HoF::o2_defineSceneAnim(EMCState *script) {
  711. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script,
  712. stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8),
  713. stackPos(9), stackPos(10), stackPos(11), stackPosString(12));
  714. int animId = stackPos(0);
  715. SceneAnim &anim = _sceneAnims[animId];
  716. anim.flags = stackPos(1);
  717. anim.x = stackPos(2);
  718. anim.y = stackPos(3);
  719. anim.x2 = stackPos(4);
  720. anim.y2 = stackPos(5);
  721. anim.width = stackPos(6);
  722. anim.height = stackPos(7);
  723. anim.specialSize = stackPos(9);
  724. anim.shapeIndex = stackPos(11);
  725. if (stackPosString(12) != 0)
  726. strcpy(anim.filename, stackPosString(12));
  727. if (anim.flags & 0x40) {
  728. if (!_sceneAnimMovie[animId]->open(anim.filename, 1, 0))
  729. error("couldn't load '%s'", anim.filename);
  730. if (_sceneAnimMovie[animId]->xAdd() || _sceneAnimMovie[animId]->yAdd())
  731. anim.wsaFlag = 1;
  732. else
  733. anim.wsaFlag = 0;
  734. }
  735. return 0;
  736. }
  737. int KyraEngine_HoF::o2_updateSceneAnim(EMCState *script) {
  738. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  739. updateSceneAnim(stackPos(0), stackPos(1));
  740. // HACK: Some animations are really too fast because of missing delay times.
  741. // Notice that the delay time is purely subjective set here, it could look
  742. // slower or maybe faster in the original, but at least this looks OK for
  743. // Raziel^.
  744. //
  745. // We know currently of some different animations where this happens.
  746. // - Where Marco is dangling from the flesh-eating plant (see bug
  747. // #1923638 "HoF: Marco missing animation frames").
  748. // - After giving the ticket to the captain. He would move very fast
  749. // (barely noticeable) onto the ship without this delay.
  750. // - The scene after giving the sandwitch to the guards in the city.
  751. // (see bug #1926838 "HoF: Animation plays too fast")
  752. // This scene script calls o2_delay though, but since this updates
  753. // the scene animation scripts again there is no delay for the
  754. // animation.
  755. // - When the sheriff enters the jail, either to lock you up or to throw
  756. // away the key. (see bug #1926838 "HoF: Animation plays too fast").
  757. if ((stackPos(0) == 2 && _mainCharacter.sceneId == 3) ||
  758. (stackPos(0) == 3 && _mainCharacter.sceneId == 33) ||
  759. ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 19) ||
  760. ((stackPos(0) == 1 || stackPos(0) == 2) && _mainCharacter.sceneId == 27))
  761. _sceneSpecialScriptsTimer[_lastProcessedSceneScript] = _system->getMillis() + _tickLength * 6;
  762. _specialSceneScriptRunFlag = false;
  763. return 0;
  764. }
  765. int KyraEngine_HoF::o2_addToSceneAnimPosAndUpdate(EMCState *script) {
  766. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addToSceneAnimPosAndUpdate(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
  767. const int anim = stackPos(0);
  768. _sceneAnims[anim].x2 += stackPos(1);
  769. _sceneAnims[anim].y2 += stackPos(2);
  770. if (_sceneAnims[anim].flags & 2) {
  771. _sceneAnims[anim].x += stackPos(1);
  772. _sceneAnims[anim].y += stackPos(2);
  773. }
  774. updateSceneAnim(anim, stackPos(3));
  775. _specialSceneScriptRunFlag = false;
  776. return 0;
  777. }
  778. int KyraEngine_HoF::o2_useItemOnMainChar(EMCState *script) {
  779. EMCState tmpScript;
  780. _emc->init(&tmpScript, &_npcScriptData);
  781. _emc->start(&tmpScript, 0);
  782. tmpScript.regs[4] = _itemInHand;
  783. tmpScript.regs[0] = _mainCharacter.sceneId;
  784. int oldVocH = _vocHigh;
  785. _vocHigh = 0x5A;
  786. while (_emc->isValid(&tmpScript))
  787. _emc->run(&tmpScript);
  788. _vocHigh = oldVocH;
  789. return 0;
  790. }
  791. int KyraEngine_HoF::o2_startDialogue(EMCState *script) {
  792. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_startDialogue(%p) (%d)", (const void *)script, stackPos(0));
  793. startDialogue(stackPos(0));
  794. return 0;
  795. }
  796. int KyraEngine_HoF::o2_addCauldronStateTableEntry(EMCState *script) {
  797. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_addCauldronStateTableEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  798. return addToCauldronStateTable(stackPos(0), stackPos(1)) ? 1 : 0;
  799. }
  800. int KyraEngine_HoF::o2_setCountDown(EMCState *script) {
  801. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setCountDown(%p) (%d)", (const void *)script, stackPos(0));
  802. _scriptCountDown = _system->getMillis() + stackPos(0) * _tickLength;
  803. return 0;
  804. }
  805. int KyraEngine_HoF::o2_getCountDown(EMCState *script) {
  806. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getCountDown(%p)", (const void *)script);
  807. uint32 time = _system->getMillis();
  808. return (time > _scriptCountDown) ? 0 : (_scriptCountDown - time) / _tickLength;
  809. }
  810. int KyraEngine_HoF::o2_pressColorKey(EMCState *script) {
  811. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_pressColorKey(%p) (%d)", (const void *)script, stackPos(0));
  812. for (int i = 6; i; i--)
  813. _inputColorCode[i] = _inputColorCode[i - 1];
  814. _inputColorCode[0] = stackPos(0) & 0xFF;
  815. for (int i = 0; i < 7; i++) {
  816. if (_presetColorCode[i] != _inputColorCode[6 - i])
  817. return _dbgPass;
  818. }
  819. return 1;
  820. }
  821. int KyraEngine_HoF::o2_objectChat(EMCState *script) {
  822. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
  823. if (_flags.isTalkie)
  824. warning("Unexpected call: o2_objectChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
  825. else
  826. objectChat(stackPosString(0), stackPos(1));
  827. return 0;
  828. }
  829. int KyraEngine_HoF::o2_changeChapter(EMCState *script) {
  830. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_changeChapter(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  831. const int chapter = stackPos(0);
  832. const int scene = stackPos(1);
  833. resetItemList();
  834. _newChapterFile = chapter;
  835. runStartScript(chapter, 0);
  836. _mainCharacter.dlgIndex = 0;
  837. memset(_newSceneDlgState, 0, 32);
  838. static const int zShapeList[] = { 1, 2, 2, 2, 4 };
  839. assert(chapter > 1 && chapter <= ARRAYSIZE(zShapeList));
  840. loadCharacterShapes(zShapeList[chapter-1]);
  841. enterNewScene(scene, (chapter == 2) ? 2 : 0, 0, 0, 0);
  842. return 0;
  843. }
  844. int KyraEngine_HoF::o2_getColorCodeFlag1(EMCState *script) {
  845. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag1(%p) ()", (const void *)script);
  846. return _colorCodeFlag1;
  847. }
  848. int KyraEngine_HoF::o2_setColorCodeFlag1(EMCState *script) {
  849. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag1(%p) (%d)", (const void *)script, stackPos(0));
  850. _colorCodeFlag1 = stackPos(0);
  851. return 0;
  852. }
  853. int KyraEngine_HoF::o2_getColorCodeFlag2(EMCState *script) {
  854. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag2(%p) ()", (const void *)script);
  855. return _colorCodeFlag2;
  856. }
  857. int KyraEngine_HoF::o2_setColorCodeFlag2(EMCState *script) {
  858. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeFlag2(%p) (%d)", (const void *)script, stackPos(0));
  859. _colorCodeFlag2 = stackPos(0);
  860. return 0;
  861. }
  862. int KyraEngine_HoF::o2_getColorCodeValue(EMCState *script) {
  863. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getColorCodeValue(%p) (%d)", (const void *)script, stackPos(0));
  864. return _presetColorCode[stackPos(0)];
  865. }
  866. int KyraEngine_HoF::o2_setColorCodeValue(EMCState *script) {
  867. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setColorCodeValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  868. _presetColorCode[stackPos(0)] = stackPos(1) & 0xFF;
  869. return stackPos(1) & 0xFF;
  870. }
  871. int KyraEngine_HoF::o2_countItemInstances(EMCState *script) {
  872. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_countItemInstances(%p) (%d)", (const void *)script, stackPos(0));
  873. Item item = stackPos(0);
  874. int count = 0;
  875. for (int i = 0; i < 20; ++i) {
  876. if (_mainCharacter.inventory[i] == item)
  877. ++count;
  878. }
  879. if (_itemInHand == item)
  880. ++count;
  881. for (int i = 0; i < 30; ++i) {
  882. if (_itemList[i].id == item)
  883. ++count;
  884. }
  885. if (_hiddenItems[0] == item && _newChapterFile == 1)
  886. ++count;
  887. if (_hiddenItems[1] == item && _newChapterFile == 1)
  888. ++count;
  889. if (_hiddenItems[2] == item && _newChapterFile == 2)
  890. ++count;
  891. if (_hiddenItems[3] == item && _newChapterFile == 2)
  892. ++count;
  893. if (_hiddenItems[4] == item && _newChapterFile == 1)
  894. ++count;
  895. return count;
  896. }
  897. int KyraEngine_HoF::o2_removeItemFromScene(EMCState *script) {
  898. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_removeItemFromScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  899. const int scene = stackPos(0);
  900. const uint16 item = stackPos(1);
  901. for (int i = 0; i < 30; ++i) {
  902. if (_itemList[i].sceneId == scene && _itemList[i].id == item)
  903. _itemList[i].id = kItemNone;
  904. }
  905. return 0;
  906. }
  907. int KyraEngine_HoF::o2_initObject(EMCState *script) {
  908. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_initObject(%p) (%d)", (const void *)script, stackPos(0));
  909. initTalkObject(stackPos(0));
  910. return 0;
  911. }
  912. int KyraEngine_HoF::o2_npcChat(EMCState *script) {
  913. if (_flags.isTalkie) {
  914. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_npcChat(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), _vocHigh, stackPos(2));
  915. npcChatSequence(stackPosString(0), stackPos(1), _vocHigh, stackPos(2));
  916. } else {
  917. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_npcChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
  918. npcChatSequence(stackPosString(0), stackPos(1));
  919. }
  920. return 0;
  921. }
  922. int KyraEngine_HoF::o2_deinitObject(EMCState *script) {
  923. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0));
  924. deinitTalkObject(stackPos(0));
  925. return 0;
  926. }
  927. int KyraEngine_HoF::o2_playTimSequence(EMCState *script) {
  928. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_playTimSequence(%p) ('%s')", (const void *)script, stackPosString(0));
  929. playTim(stackPosString(0));
  930. return 0;
  931. }
  932. int KyraEngine_HoF::o2_makeBookOrCauldronAppear(EMCState *script) {
  933. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_makeBookOrCauldronAppear(%p) (%d)", (const void *)script, stackPos(0));
  934. seq_makeBookOrCauldronAppear(stackPos(0));
  935. return 0;
  936. }
  937. int KyraEngine_HoF::o2_resetInputColorCode(EMCState *script) {
  938. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_resetInputColorCode(%p)", (const void *)script);
  939. memset(_inputColorCode, 255, 7);
  940. return 0;
  941. }
  942. int KyraEngine_HoF::o2_mushroomEffect(EMCState *script) {
  943. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_mushroomEffect(%p)", (const void *)script);
  944. _screen->copyPalette(2, 0);
  945. for (int i = 1; i < 768; i += 3)
  946. _screen->getPalette(0)[i] = 0;
  947. snd_playSoundEffect(106);
  948. _screen->fadePalette(_screen->getPalette(0), 90, &_updateFunctor);
  949. _screen->copyPalette(0, 2);
  950. for (int i = 0; i < 768; i += 3) {
  951. _screen->getPalette(0)[i] = _screen->getPalette(0)[i + 1] = 0;
  952. _screen->getPalette(0)[i + 2] += (((int8)_screen->getPalette(0)[i + 2]) >> 1);
  953. if (_screen->getPalette(0)[i + 2] > 63)
  954. _screen->getPalette(0)[i + 2] = 63;
  955. }
  956. snd_playSoundEffect(106);
  957. _screen->fadePalette(_screen->getPalette(0), 90, &_updateFunctor);
  958. _screen->copyPalette(0, 2);
  959. _screen->fadePalette(_screen->getPalette(0), 30, &_updateFunctor);
  960. return 0;
  961. }
  962. int KyraEngine_HoF::o2_customChat(EMCState *script) {
  963. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customChat(%p) ('%s', %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2));
  964. strcpy((char *)_unkBuf500Bytes, stackPosString(0));
  965. _chatText = (char *)_unkBuf500Bytes;
  966. _chatObject = stackPos(1);
  967. _chatVocHigh = _chatVocLow = -1;
  968. objectChatInit(_chatText, _chatObject, _vocHigh, stackPos(2));
  969. playVoice(_vocHigh, stackPos(2));
  970. return 0;
  971. }
  972. int KyraEngine_HoF::o2_customChatFinish(EMCState *script) {
  973. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_customChatFinish(%p) ()", (const void *)script);
  974. _text->restoreScreen();
  975. _chatText = 0;
  976. _chatObject = -1;
  977. return 0;
  978. }
  979. int KyraEngine_HoF::o2_setupSceneAnimation(EMCState *script) {
  980. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setupSceneAnimation(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script,
  981. stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9), stackPos(10), stackPos(11), stackPosString(12));
  982. const int index = stackPos(0);
  983. const uint16 flags = stackPos(1);
  984. restorePage3();
  985. SceneAnim &anim = _sceneAnims[index];
  986. anim.flags = flags;
  987. anim.x = stackPos(2);
  988. anim.y = stackPos(3);
  989. anim.x2 = stackPos(4);
  990. anim.y2 = stackPos(5);
  991. anim.width = stackPos(6);
  992. anim.height = stackPos(7);
  993. anim.specialSize = stackPos(9);
  994. anim.shapeIndex = stackPos(11);
  995. if (stackPosString(12))
  996. strcpy(anim.filename, stackPosString(12));
  997. if (flags & 0x40) {
  998. _sceneAnimMovie[index]->open(stackPosString(12), 0, 0);
  999. if (_sceneAnimMovie[index]->xAdd() || _sceneAnimMovie[index]->yAdd())
  1000. anim.wsaFlag = 1;
  1001. else
  1002. anim.wsaFlag = 0;
  1003. }
  1004. AnimObj *obj = &_animObjects[1+index];
  1005. obj->enabled = 1;
  1006. obj->needRefresh = 1;
  1007. obj->specialRefresh = 1;
  1008. obj->animFlags = anim.flags & 8;
  1009. if (anim.flags & 2)
  1010. obj->flags = 0x800;
  1011. else
  1012. obj->flags = 0;
  1013. if (anim.flags & 4)
  1014. obj->flags |= 1;
  1015. obj->xPos1 = anim.x;
  1016. obj->yPos1 = anim.y;
  1017. if ((anim.flags & 0x20) && anim.shapeIndex >= 0)
  1018. obj->shapePtr = _sceneShapeTable[anim.shapeIndex];
  1019. else
  1020. obj->shapePtr = 0;
  1021. if (anim.flags & 0x40) {
  1022. obj->shapeIndex3 = anim.shapeIndex;
  1023. obj->animNum = index;
  1024. } else {
  1025. obj->shapeIndex3 = 0xFFFF;
  1026. obj->animNum = 0xFFFF;
  1027. }
  1028. obj->shapeIndex2 = 0xFFFF;
  1029. obj->xPos2 = obj->xPos3 = anim.x2;
  1030. obj->yPos2 = obj->yPos3 = anim.y2;
  1031. obj->width = anim.width;
  1032. obj->height = anim.height;
  1033. obj->width2 = obj->height2 = anim.specialSize;
  1034. _animList = addToAnimListSorted(_animList, obj);
  1035. obj->needRefresh = 1;
  1036. obj->specialRefresh = 1;
  1037. return 0;
  1038. }
  1039. int KyraEngine_HoF::o2_stopSceneAnimation(EMCState *script) {
  1040. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_stopSceneAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  1041. const int index = stackPos(0);
  1042. AnimObj &obj = _animObjects[1+index];
  1043. restorePage3();
  1044. obj.shapeIndex3 = 0xFFFF;
  1045. obj.animNum = 0xFFFF;
  1046. obj.needRefresh = 1;
  1047. obj.specialRefresh = 1;
  1048. if (stackPos(1))
  1049. refreshAnimObjectsIfNeed();
  1050. obj.enabled = 0;
  1051. _animList = deleteAnimListEntry(_animList, &_animObjects[1+index]);
  1052. if (_sceneAnimMovie[index]->opened())
  1053. _sceneAnimMovie[index]->close();
  1054. return 0;
  1055. }
  1056. int KyraEngine_HoF::o2_processPaletteIndex(EMCState *script) {
  1057. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_processPaletteIndex(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
  1058. Palette &palette = _screen->getPalette(0);
  1059. const int index = stackPos(0);
  1060. const bool updatePalette = (stackPos(4) != 0);
  1061. const int delayTime = stackPos(5);
  1062. palette[index*3+0] = (stackPos(1) * 0x3F) / 100;
  1063. palette[index*3+1] = (stackPos(2) * 0x3F) / 100;
  1064. palette[index*3+2] = (stackPos(3) * 0x3F) / 100;
  1065. if (updatePalette) {
  1066. if (delayTime > 0)
  1067. _screen->fadePalette(palette, delayTime, &_updateFunctor);
  1068. else
  1069. _screen->setScreenPalette(palette);
  1070. }
  1071. return 0;
  1072. }
  1073. int KyraEngine_HoF::o2_updateTwoSceneAnims(EMCState *script) {
  1074. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_updateTwoSceneAnims(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
  1075. updateSceneAnim(stackPos(0), stackPos(1));
  1076. updateSceneAnim(stackPos(2), stackPos(3));
  1077. _specialSceneScriptRunFlag = false;
  1078. return 0;
  1079. }
  1080. int KyraEngine_HoF::o2_getRainbowRoomData(EMCState *script) {
  1081. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getRainbowRoomData(%p) (%d)", (const void *)script, stackPos(0));
  1082. return _rainbowRoomData[stackPos(0)];
  1083. }
  1084. int KyraEngine_HoF::o2_drawSceneShapeEx(EMCState *script) {
  1085. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_drawSceneShapeEx(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
  1086. const int itemShape = stackPos(0) + 64;
  1087. const int x = stackPos(1);
  1088. const int y = stackPos(2);
  1089. const bool skipFronUpdate = (stackPos(3) != 0);
  1090. _screen->drawShape(2, _sceneShapeTable[6], x, y, 2, 0);
  1091. _screen->drawShape(2, getShapePtr(itemShape), x+2, y+2, 2, 0);
  1092. if (!skipFronUpdate) {
  1093. _screen->copyRegion(x, y, x, y, 0x15, 0x14, 2, 0, Screen::CR_NO_P_CHECK);
  1094. _screen->updateScreen();
  1095. }
  1096. return 0;
  1097. }
  1098. int KyraEngine_HoF::o2_midiSoundFadeout(EMCState *script) {
  1099. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_midiSoundFadeout(%p) ()", (const void *)script);
  1100. if (!stackPos(0)) {
  1101. if ((_sound->getMusicType() == Sound::kMidiMT32 || _sound->getMusicType() == Sound::kMidiGM) &&
  1102. (_sound->getSfxType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiGM)) {
  1103. _sound->beginFadeOut();
  1104. delay(2000, true);
  1105. _lastMusicCommand = -1;
  1106. } else {
  1107. return 0;
  1108. }
  1109. }
  1110. return 1;
  1111. }
  1112. int KyraEngine_HoF::o2_getSfxDriver(EMCState *script) {
  1113. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getSfxDriver(%p) ()", (const void *)script);
  1114. if (_sound->getSfxType() == Sound::kAdLib)
  1115. return 1;
  1116. else if (_sound->getSfxType() == Sound::kPCSpkr)
  1117. return 4;
  1118. else if (_sound->getSfxType() == Sound::kMidiMT32)
  1119. return 6;
  1120. else if (_sound->getSfxType() == Sound::kMidiGM)
  1121. return 7;
  1122. // TODO: find nice default value
  1123. return 0;
  1124. }
  1125. int KyraEngine_HoF::o2_getVocSupport(EMCState *script) {
  1126. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getVocSupport(%p) ()", (const void *)script);
  1127. // we always support VOC file playback
  1128. return 1;
  1129. }
  1130. int KyraEngine_HoF::o2_getMusicDriver(EMCState *script) {
  1131. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getMusicDriver(%p) ()", (const void *)script);
  1132. if (_sound->getMusicType() == Sound::kAdLib)
  1133. return 1;
  1134. else if (_sound->getMusicType() == Sound::kPCSpkr)
  1135. return 4;
  1136. else if (_sound->getMusicType() == Sound::kMidiMT32)
  1137. return 6;
  1138. else if (_sound->getMusicType() == Sound::kMidiGM)
  1139. return 7;
  1140. // TODO: find nice default value
  1141. return 0;
  1142. }
  1143. int KyraEngine_HoF::o2_zanthiaChat(EMCState *script) {
  1144. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_zanthiaChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
  1145. objectChat(stackPosString(0), 0, _vocHigh, stackPos(1));
  1146. return 0;
  1147. }
  1148. int KyraEngine_HoF::o2_isVoiceEnabled(EMCState *script) {
  1149. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isVoiceEnabled(%p) ()", (const void *)script);
  1150. return speechEnabled() ? 1 : 0;
  1151. }
  1152. int KyraEngine_HoF::o2_isVoicePlaying(EMCState *script) {
  1153. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_isVoicePlaying(%p) ()", (const void *)script);
  1154. return (snd_voiceIsPlaying() && !skipFlag()) ? 1 : 0;
  1155. }
  1156. int KyraEngine_HoF::o2_stopVoicePlaying(EMCState *script) {
  1157. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_stopVoicePlaying(%p) ()", (const void *)script);
  1158. snd_stopVoice();
  1159. return 0;
  1160. }
  1161. int KyraEngine_HoF::o2_getGameLanguage(EMCState *script) {
  1162. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_getGameLanguage(%p) ()", (const void *)script);
  1163. return _lang;
  1164. }
  1165. int KyraEngine_HoF::o2_demoFinale(EMCState *script) {
  1166. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_demoFinale(%p) ()", (const void *)script);
  1167. if (!_flags.isDemo)
  1168. return 0;
  1169. int tmpSize;
  1170. const char *const *strings = _staticres->loadStrings(k2IngameTlkDemoStrings, tmpSize);
  1171. assert(strings);
  1172. _screen->clearPage(0);
  1173. _screen->loadPalette("THANKS.COL", _screen->getPalette(0));
  1174. _screen->loadBitmap("THANKS.CPS", 3, 3, 0);
  1175. _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
  1176. _screen->_curPage = 0;
  1177. int y = _lang == 1 ? 70 : 65;
  1178. for (int i = 0; i < 6; i++)
  1179. _text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0);
  1180. _screen->setScreenPalette(_screen->getPalette(0));
  1181. _screen->updateScreen();
  1182. _eventList.clear();
  1183. while (!skipFlag() && !shouldQuit())
  1184. delay(10);
  1185. _sound->beginFadeOut();
  1186. _screen->fadeToBlack();
  1187. _runFlag = 0;
  1188. return 0;
  1189. }
  1190. int KyraEngine_HoF::o2_dummy(EMCState *script) {
  1191. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_dummy(%p) ()", (const void *)script);
  1192. return 0;
  1193. }
  1194. #pragma mark -
  1195. int KyraEngine_HoF::o2a_setCharacterFrame(EMCState *script) {
  1196. debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2a_setCharacterFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
  1197. _animNewFrame = stackPos(0);
  1198. _animDelayTime = stackPos(1);
  1199. _animNeedUpdate = true;
  1200. return 0;
  1201. }
  1202. #pragma

Large files files are truncated, but you can click here to view the full file