void KyraEngine_HoF::enterNewSceneUnk2(int unk1) { _savedMouseState = -1; if (_flags.isTalkie) { if (_mainCharX == -1 && _mainCharY == -1 && _mainCharacter.sceneId != 61 && !queryGameFlag(0x1F1) && !queryGameFlag(0x192) && !queryGameFlag(0x193) && _mainCharacter.sceneId != 70 && !queryGameFlag(0x159) && _mainCharacter.sceneId != 37) { _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; updateCharacterAnim(0); refreshAnimObjectsIfNeed(); } } else if (_mainCharX != -1 && _mainCharY != -1) { if (_characterFrameTable[_mainCharacter.facing] == 25) _mainCharacter.facing = 5; _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; updateCharacterAnim(0); refreshAnimObjectsIfNeed(); } if (!unk1) { runSceneScript4(0); zanthSceneStartupChat(); } _unk4 = 0; _savedMouseState = -1; }
int KyraEngine_HoF::cauldronClearButton(Button *button) { if (!queryGameFlag(2)) { updateCharFacing(); objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); return 0; } if (queryGameFlag(0xE4)) { snd_playSoundEffect(0x0D); return 0; } _screen->hideMouse(); displayInvWsaLastFrame(); snd_playSoundEffect(0x25); loadInvWsa("PULL.WSA", 1, 6, 0, -1, -1, 1); loadInvWsa("CAULD00.WSA", 1, 7, 0, 0xD4, 0x0F, 1); showMessage(0, 0xCF); setCauldronState(0, 0); clearCauldronTable(); snd_playSoundEffect(0x57); loadInvWsa("CAULDFIL.WSA", 1, 7, 0, -1, -1, 1); _screen->showMouse(); return 0; }
bool KyraEngine_HoF::handleInputUnkSub(int x, int y) { if (y > 143 || _deathHandler > -1 || queryGameFlag(0x164)) return false; if (_mouseState <= -3 && findItem(_mainCharacter.sceneId, 13) >= 0) { updateCharFacing(); objectChat(getTableString(0xFC, _cCodeBuffer, 1), 0, 0x83, 0xFC); return true; } else { _emc->init(&_sceneScriptState, &_sceneScriptData); _sceneScriptState.regs[1] = x; _sceneScriptState.regs[2] = y; _sceneScriptState.regs[3] = 0; _sceneScriptState.regs[4] = _itemInHand; _emc->start(&_sceneScriptState, 1); while (_emc->isValid(&_sceneScriptState)) _emc->run(&_sceneScriptState); if (queryGameFlag(0x1ED)) { _sound->beginFadeOut(); _screen->fadeToBlack(); _showOutro = true; _runFlag = false; } return _sceneScriptState.regs[3] != 0; } }
void KyraEngine_HoF::startSceneScript(int unk1) { uint16 sceneId = _mainCharacter.sceneId; char filename[14]; strcpy(filename, _sceneList[sceneId].filename1); if (sceneId == 68 && (queryGameFlag(0x1BC) || queryGameFlag(0x1BD))) strcpy(filename, "DOORX"); strcat(filename, ".CPS"); _screen->loadBitmap(filename, 3, 3, 0); resetScaleTable(); _useCharPal = false; memset(_charPalTable, 0, sizeof(_charPalTable)); memset(_layerFlagTable, 0, sizeof(_layerFlagTable)); memset(_specialSceneScriptState, 0, sizeof(_specialSceneScriptState)); _sceneEnterX1 = 160; _sceneEnterY1 = 0; _sceneEnterX2 = 296; _sceneEnterY2 = 72; _sceneEnterX3 = 160; _sceneEnterY3 = 128; _sceneEnterX4 = 24; _sceneEnterY4 = 72; _sceneCommentString = "Undefined scene comment string!"; _emc->init(&_sceneScriptState, &_sceneScriptData); strcpy(filename, _sceneList[sceneId].filename1); strcat(filename, "."); strcat(filename, _scriptLangExt[(_flags.platform == Common::kPlatformPC && !_flags.isTalkie) ? 0 : _lang]); _res->exists(filename, true); _emc->load(filename, &_sceneScriptData, &_opcodes); runSceneScript7(); _emc->start(&_sceneScriptState, 0); _sceneScriptState.regs[0] = sceneId; _sceneScriptState.regs[5] = unk1; while (_emc->isValid(&_sceneScriptState)) _emc->run(&_sceneScriptState); memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); for (int i = 0; i < 10; ++i) { _emc->init(&_sceneSpecialScripts[i], &_sceneScriptData); _emc->start(&_sceneSpecialScripts[i], i+8); _sceneSpecialScriptsTimer[i] = 0; } _sceneEnterX1 &= ~3; _sceneEnterX2 &= ~3; _sceneEnterX3 &= ~3; _sceneEnterX4 &= ~3; _sceneEnterY1 &= ~1; _sceneEnterY2 &= ~1; _sceneEnterY3 &= ~1; _sceneEnterY4 &= ~1; }
void KyraEngine_LoK::setItemCreationFlags(int offset, int count) { int rndNr = _rnd.getRandomNumberRng(0, count); for (int i = 0; i <= count; i++) { if (!queryGameFlag(rndNr + offset)) { setGameFlag(rndNr + offset); break; } else { rndNr++; if (rndNr > count) rndNr = 0; } } }
void KyraEngine_LoK::timerSetFlags1(int timerNum) { if (_currentCharacter->sceneId == 0x1C) return; int rndNr = _rnd.getRandomNumberRng(0, 3); for (int i = 0; i < 4; i++) { if (!queryGameFlag(rndNr + 17)) { setGameFlag(rndNr + 17); break; } else { rndNr++; if (rndNr > 3) rndNr = 0; } } }
int KyraEngine_HoF::cauldronButton(Button *button) { if (!queryGameFlag(2)) { objectChat(getTableString(0xF0, _cCodeBuffer, 1), 0, 0x83, 0xF0); return 0; } if (!_screen->isMouseVisible() || _mouseState < -1) return 0; if (queryGameFlag(0xE4)) { snd_playSoundEffect(0x0D); return 0; } updateCharFacing(); for (int i = 0; _cauldronProtectedItems[i] != -1; ++i) { if (_itemInHand == _cauldronProtectedItems[i]) { objectChat(getTableString(0xF1, _cCodeBuffer, 1), 0, 0x83, 0xF1); return 0; } } if (_itemInHand == -1) { listItemsInCauldron(); return 0; } for (int i = 0; _cauldronBowlTable[i] != -1; i += 2) { if (_itemInHand == _cauldronBowlTable[i]) { addFrontCauldronTable(_itemInHand); setHandItem(_cauldronBowlTable[i+1]); if (!updateCauldron()) { _cauldronState = 0; cauldronRndPaletteFade(); } return 0; } } if (_itemInHand == 18) { const int16 *magicTable = (_mainCharacter.sceneId == 77) ? _cauldronMagicTableScene77 : _cauldronMagicTable; while (magicTable[0] != -1) { if (_cauldronState == magicTable[0]) { setHandItem(magicTable[1]); snd_playSoundEffect(0x6C); ++_cauldronUseCount; if (_cauldronStateTable[_cauldronState] <= _cauldronUseCount && _cauldronUseCount) { showMessage(0, 0xCF); setCauldronState(0, true); clearCauldronTable(); } return 0; } magicTable += 2; } } else if (_itemInHand >= 0) { int item = _itemInHand; cauldronItemAnim(item); addFrontCauldronTable(item); if (!updateCauldron()) { _cauldronState = 0; cauldronRndPaletteFade(); } } return 0; }
int KyraEngine_HoF::bookButton(Button *button) { if (!queryGameFlag(1)) { objectChat(getTableString(0xEB, _cCodeBuffer, 1), 0, 0x83, 0xEB); return 0; } if (!_screen->isMouseVisible()) return 0; if (queryGameFlag(0xE5)) { snd_playSoundEffect(0x0D); return 0; } if (_itemInHand == 72) { if (!queryGameFlag(0xE2)) { _bookMaxPage += 2; removeHandItem(); snd_playSoundEffect(0x6C); setGameFlag(0xE2); } if (!queryGameFlag(0x18A) && queryGameFlag(0x170)) { _bookMaxPage += 2; removeHandItem(); snd_playSoundEffect(0x6C); setGameFlag(0x18A); } return 0; } if (_mouseState != -1) { snd_playSoundEffect(0x0D); return 0; } _screen->hideMouse(); showMessage(0, 0xCF); displayInvWsaLastFrame(); _bookNewPage = _bookCurPage; if (_screenBuffer) { memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); } _screen->copyPalette(2, 0); _screen->fadeToBlack(7, &_updateFunctor); _screen->loadPalette("_BOOK.COL", _screen->getPalette(0)); loadBookBkgd(); showBookPage(); _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); int oldItemInHand = _itemInHand; removeHandItem(); _screen->fadePalette(_screen->getPalette(0), 7); _screen->showMouse(); bookLoop(); _screen->fadeToBlack(7); _screen->hideMouse(); setHandItem(oldItemInHand); updateMouse(); restorePage3(); if (_screenBuffer) { _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); } setHandItem(_itemInHand); _screen->copyPalette(0, 2); _screen->fadePalette(_screen->getPalette(0), 7, &_updateFunctor); _screen->showMouse(); if (!queryGameFlag(4) && !queryGameFlag(0xB8)) { objectChat(getTableString(0xEC, _cCodeBuffer, 1), 0, 0x83, 0xEC); objectChat(getTableString(0xED, _cCodeBuffer, 1), 0, 0x83, 0xED); objectChat(getTableString(0xEE, _cCodeBuffer, 1), 0, 0x83, 0xEE); objectChat(getTableString(0xEF, _cCodeBuffer, 1), 0, 0x83, 0xEF); setGameFlag(4); } return 0; }
void KyraEngine_HoF::handleInput(int x, int y) { setNextIdleAnimTimer(); if (_unk5) { _unk5 = 0; return; } if (!_screen->isMouseVisible()) return; if (_savedMouseState == -2) { snd_playSoundEffect(13); return; } setNextIdleAnimTimer(); if (x <= 6 || x >= 312 || y <= 6 || y >= 135) { bool exitOk = false; assert(_savedMouseState + 6 >= 0); switch (_savedMouseState + 6) { case 0: if (_sceneExit1 != 0xFFFF) exitOk = true; break; case 1: if (_sceneExit2 != 0xFFFF) exitOk = true; break; case 2: if (_sceneExit3 != 0xFFFF) exitOk = true; break; case 3: if (_sceneExit4 != 0xFFFF) exitOk = true; break; default: break; } if (exitOk) { inputSceneChange(x, y, 1, 1); return; } } if (checkCharCollision(x, y) && _savedMouseState >= -1) { runSceneScript2(); return; } else if (pickUpItem(x, y)) { return; } else { int skipHandling = 0; if (checkItemCollision(x, y) == -1) { resetGameFlag(0x1EF); skipHandling = handleInputUnkSub(x, y) ? 1 : 0; if (queryGameFlag(0x1EF)) { resetGameFlag(0x1EF); return; } if (_unk5) { _unk5 = 0; return; } } if (_deathHandler > -1) skipHandling = 1; if (skipHandling) return; if (checkCharCollision(x, y)) { runSceneScript2(); return; } if (_itemInHand >= 0) { if (y > 136) return; dropItem(0, _itemInHand, x, y, 1); } else { if (_savedMouseState == -2 || y > 135) return; if (!_unk5) { inputSceneChange(x, y, 1, 1); return; } _unk5 = 0; } } }
void KyraEngine_HoF::runLoop() { _screen->updateScreen(); _runFlag = true; while (!shouldQuit() && _runFlag) { if (_deathHandler >= 0) { removeHandItem(); delay(5); _drawNoShapeFlag = 0; _gui->optionsButton(0); _deathHandler = -1; if (!_runFlag || shouldQuit()) break; } if (_system->getMillis() > _nextIdleAnim) showIdleAnim(); if (queryGameFlag(0x159)) { dinoRide(); resetGameFlag(0x159); } if (queryGameFlag(0x124) && !queryGameFlag(0x125)) { _mainCharacter.animFrame = 32; enterNewScene(39, -1, 0, 0, 0); } if (queryGameFlag(0xD8)) { resetGameFlag(0xD8); if (_mainCharacter.sceneId == 34) { if (queryGameFlag(0xD1)) { initTalkObject(28); npcChatSequence(getTableString(0xFA, _cCodeBuffer, 1), 28, 0x83, 0xFA); deinitTalkObject(28); enterNewScene(35, 4, 0, 0, 0); } else if (queryGameFlag(0xD0)) { initTalkObject(29); npcChatSequence(getTableString(0xFB, _cCodeBuffer, 1), 29, 0x83, 0xFB); deinitTalkObject(29); enterNewScene(33, 6, 0, 0, 0); } } } int inputFlag = checkInput(_buttonList, true); removeInputTop(); update(); if (inputFlag == 198 || inputFlag == 199) { _savedMouseState = _mouseState; handleInput(_mouseX, _mouseY); } //if (queryGameFlag(0x1EE) && inputFlag) // sub_13B19(inputFlag); _system->delayMillis(10); } }
void KyraEngine_LoK::timerRedrawAmulet(int timerNum) { if (queryGameFlag(0xF1)) { drawAmulet(); _timer->setCountdown(19, -1); } }
Common::Error KyraEngine_HoF::loadGameState(int slot) { const char *fileName = getSavegameFilename(slot); SaveHeader header; Common::InSaveFile *saveFile = openSaveForReading(fileName, header); if (!saveFile) { showMessageFromCCode(0x35, 0x84, 0); snd_playSoundEffect(0x0D); return Common::kUnknownError; } if (header.originalSave) warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported"); bool setFlag1EE = (queryGameFlag(0x1EE) != 0); _deathHandler = -1; if (!_unkSceneScreenFlag1) { _sound->beginFadeOut(); _system->delayMillis(5 * _tickLength); _lastMusicCommand = -1; } int loadedZTable = _characterShapeFile; Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES); _screen->hideMouse(); if (!header.originalSave) { _timer->loadDataFromFile(in, header.version); uint32 flagsSize = in.readUint32BE(); assert(flagsSize <= sizeof(_flagsTable)); in.read(_flagsTable, flagsSize); } // usually we have to save the flag set by opcode 10 here //word_2AB05 = in.readUint16(); if (header.originalSave) in.readUint16(); _lastMusicCommand = in.readSint16(); _newChapterFile = in.readByte(); _characterShapeFile = in.readByte(); _cauldronState = in.readByte(); _colorCodeFlag1 = in.readByte(); _colorCodeFlag2 = in.readByte(); _bookCurPage = in.readByte(); _bookMaxPage = in.readByte(); for (int i = 0; i < 7; ++i) _presetColorCode[i] = in.readByte(); for (int i = 0; i < 7; ++i) _inputColorCode[i] = in.readByte(); for (int i = 0; i < 25; ++i) _cauldronTable[i] = in.readSint16(); for (int i = 0; i < 20; ++i) _hiddenItems[i] = in.readSint16(); if (header.originalSave) { assert(sizeof(_flagsTable) >= 0x41); in.read(_flagsTable, 0x41); } for (int i = 0; i < 19; ++i) in.read(_conversationState[i], 14); if (!header.originalSave) { in.read(_newSceneDlgState, 32); } else { for (int i = 0; i < 31; ++i) _newSceneDlgState[i] = in.readUint16(); } _cauldronUseCount = in.readSint16(); if (header.originalSave) in.seek(6, SEEK_CUR); _mainCharacter.sceneId = in.readUint16(); _mainCharacter.dlgIndex = in.readSint16(); _mainCharacter.height = in.readByte(); _mainCharacter.facing = in.readByte(); _mainCharacter.animFrame = in.readUint16(); if (header.version <= 10 || header.originalSave) in.seek(3, SEEK_CUR); for (int i = 0; i < 20; ++i) _mainCharacter.inventory[i] = in.readUint16(); _mainCharacter.x1 = in.readSint16(); _mainCharacter.y1 = in.readSint16(); _mainCharacter.x2 = in.readSint16(); _mainCharacter.y2 = in.readSint16(); for (int i = 0; i < 30; ++i) { _itemList[i].id = in.readSint16(); _itemList[i].sceneId = in.readUint16(); _itemList[i].x = in.readSint16(); _itemList[i].y = in.readByte(); if (header.version <= 9 || header.originalSave) in.readUint16(); } for (int i = 0; i < 72; ++i) { in.read(_talkObjectList[i].filename, 13); _talkObjectList[i].scriptId = in.readByte(); _talkObjectList[i].x = in.readSint16(); _talkObjectList[i].y = in.readSint16(); _talkObjectList[i].color = in.readByte(); } for (int i = 0; i < 86; ++i) { if (!header.originalSave) { in.read(_sceneList[i].filename1, 10); } else { in.read(_sceneList[i].filename1, 9); _sceneList[i].filename1[9] = 0; } _sceneList[i].exit1 = in.readUint16(); _sceneList[i].exit2 = in.readUint16(); _sceneList[i].exit3 = in.readUint16(); _sceneList[i].exit4 = in.readUint16(); _sceneList[i].flags = in.readByte(); _sceneList[i].sound = in.readByte(); } _itemInHand = in.readSint16(); if (header.originalSave) { uint32 currentTime = _system->getMillis(); for (int i = 0; i < 6; ++i) _timer->setDelay(i, in.readSint32LE()); for (int i = 0; i < 6; ++i) { if (in.readUint16LE()) _timer->enable(i); else _timer->disable(i); } for (int i = 0; i < 6; ++i) _timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength)); _timer->resetNextRun(); } _sceneExit1 = in.readUint16(); _sceneExit2 = in.readUint16(); _sceneExit3 = in.readUint16(); _sceneExit4 = in.readUint16(); if (saveFile->err() || saveFile->eos()) { warning("Load failed ('%s', '%s').", fileName, header.description.c_str()); return Common::kUnknownError; } else { debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str()); } if (loadedZTable != _characterShapeFile) loadCharacterShapes(_characterShapeFile); _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); if (!queryGameFlag(1)) _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); if (!queryGameFlag(2)) _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0); if (queryGameFlag(1)) _screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); if (queryGameFlag(2)) _screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK); redrawInventory(0); int cauldronUseCount = _cauldronUseCount; setCauldronState(_cauldronState, 0); _cauldronUseCount = cauldronUseCount; _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; _mainCharacter.facing = 4; enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); setDelayedCursorUpdate(); if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) snd_playWanderScoreViaMap(_lastMusicCommand, 1); while (!_screen->isMouseVisible()) _screen->showMouse(); setTimer1DelaySecs(7); _shownMessage = " "; _fadeMessagePalette = false; if (setFlag1EE) setGameFlag(0x1EE); // We didn't explicitly set the walk speed, but it's saved as part of // the _timers array, so we need to re-sync it with _configWalkspeed. setWalkspeed(_configWalkspeed); return Common::kNoError; }
int KyraEngine_v1::o1_queryGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return queryGameFlag(stackPos(0)); }
void KyraEngine_MR::handleInput(int x, int y) { if (_inventoryState) return; setNextIdleAnimTimer(); if (_unk5) { _unk5 = 0; return; } if (!_screen->isMouseVisible()) return; if (_savedMouseState == -3) { snd_playSoundEffect(0x0D, 0x80); return; } setNextIdleAnimTimer(); int skip = 0; if (checkCharCollision(x, y) && _savedMouseState >= -1 && runSceneScript2()) { return; } else if (_itemInHand != 27 && pickUpItem(x, y, 1)) { return; } else if (checkItemCollision(x, y) == -1) { resetGameFlag(1); skip = runSceneScript1(x, y); if (queryGameFlag(1)) { resetGameFlag(1); return; } else if (_unk5) { _unk5 = 0; return; } } if (_deathHandler >= 0) skip = 1; if (skip) return; if (checkCharCollision(x, y)) { if (runSceneScript2()) return; } else if (_itemInHand >= 0 && _savedMouseState >= 0) { if (_itemInHand == 27) { makeCharFacingMouse(); } else if (y <= 187) { if (_itemInHand == 43) removeHandItem(); else dropItem(0, _itemInHand, x, y, 1); } return; } else if (_savedMouseState == -3) { return; } else { if (y > 187 && _savedMouseState > -4) return; if (_unk5) { _unk5 = 0; return; } } inputSceneChange(x, y, 1, 1); }