diff options
Diffstat (limited to 'kyra/kyra.cpp')
-rw-r--r-- | kyra/kyra.cpp | 1215 |
1 files changed, 0 insertions, 1215 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp deleted file mode 100644 index c85ce9b323..0000000000 --- a/kyra/kyra.cpp +++ /dev/null @@ -1,1215 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" - -#include "backends/fs/fs.h" - -#include "base/gameDetector.h" -#include "base/plugins.h" - -#include "common/config-manager.h" -#include "common/file.h" -#include "common/system.h" -#include "common/md5.h" -#include "common/savefile.h" - -#include "sound/mixer.h" -#include "sound/mididrv.h" - -#include "gui/message.h" - -#include "kyra/kyra.h" -#include "kyra/resource.h" -#include "kyra/screen.h" -#include "kyra/script.h" -#include "kyra/seqplayer.h" -#include "kyra/sound.h" -#include "kyra/sprites.h" -#include "kyra/wsamovie.h" -#include "kyra/animator.h" -#include "kyra/text.h" -#include "kyra/debugger.h" - -using namespace Kyra; - -enum { - // We only compute MD5 of the first megabyte of our data files. - kMD5FileSizeLimit = 1024 * 1024 -}; - -// Kyra MD5 detection brutally ripped from the Gobliins engine. -struct KyraGameSettings { - const char *gameid; - const char *description; - byte id; - uint32 features; - const char *md5sum; - const char *checkFile; - GameSettings toGameSettings() const { - GameSettings dummy = { gameid, description, features }; - return dummy; - } -}; - -// We could get rid of md5 detection at least for kyra 1 since we can locate all -// needed files for detecting the right language and version (Floppy, Talkie) -static const KyraGameSettings kyra_games[] = { - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_FLOPPY, // english floppy 1.0 from Malice - "3c244298395520bb62b5edfe41688879", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_FLOPPY, - "796e44863dd22fa635b042df1bf16673", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_FRENCH | GF_FLOPPY, - "abf8eb360e79a6c2a837751fbd4d3d24", "GEMCUT.EMC" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_FLOPPY, - "6018e1dfeaca7fe83f8d0b00eb0dd049", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_FLOPPY, // from Arne.F - "f0b276781f47c130f423ec9679fe9ed9", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_SPANISH | GF_FLOPPY, // from VooD - "8909b41596913b3f5deaf3c9f1017b01", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_SPANISH | GF_FLOPPY, // floppy 1.8 from clemmy - "747861d2a9c643c59fdab570df5b9093", "GEMCUT.EMC"}, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_ENGLISH | GF_TALKIE, - "fac399fe62f98671e56a005c5e94e39f", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_GERMAN | GF_TALKIE, - "230f54e6afc007ab4117159181a1c722", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia", GI_KYRA1, GF_FRENCH | GF_TALKIE, - "b037c41768b652a040360ffa3556fd2a", "GEMCUT.PAK" }, - { "kyra1", "The Legend of Kyrandia Demo", GI_KYRA1, GF_DEMO | GF_ENGLISH, - "fb722947d94897512b13b50cc84fd648", "DEMO1.WSA" }, - { 0, 0, 0, 0, 0, 0 } -}; - -// Keep list of different supported games -struct KyraGameList { - const char *gameid; - const char *description; - uint32 features; - GameSettings toGameSettings() const { - GameSettings dummy = { gameid, description, features }; - return dummy; - } -}; - -static const KyraGameList kyra_list[] = { - { "kyra1", "The Legend of Kyrandia", 0 }, - { 0, 0, 0 } -}; - -struct KyraLanguageTable { - const char *file; - uint32 language; - Common::Language detLanguage; -}; - -static const KyraLanguageTable kyra_languages[] = { - { "MAIN15.CPS", GF_ENGLISH, Common::EN_USA }, - { "MAIN_ENG.CPS", GF_ENGLISH, Common::EN_USA }, - { "MAIN_FRE.CPS", GF_FRENCH, Common::FR_FRA }, - { "MAIN_GER.CPS", GF_GERMAN, Common::DE_DEU }, - { "MAIN_SPA.CPS", GF_SPANISH, Common::ES_ESP }, - { 0, 0, Common::UNK_LANG } -}; - -static Common::Language convertKyraLang(uint32 features) { - if (features & GF_ENGLISH) { - return Common::EN_USA; - } else if (features & GF_FRENCH) { - return Common::FR_FRA; - } else if (features & GF_GERMAN) { - return Common::DE_DEU; - } else if (features & GF_SPANISH) { - return Common::ES_ESP; - } - return Common::UNK_LANG; -} - -GameList Engine_KYRA_gameList() { - GameList games; - const KyraGameList *g = kyra_list; - - while (g->gameid) { - games.push_back(g->toGameSettings()); - g++; - } - return games; -} - -DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) { - DetectedGameList detectedGames; - const KyraGameSettings *g; - FSList::const_iterator file; - - // Iterate over all files in the given directory - bool isFound = false; - for (file = fslist.begin(); file != fslist.end(); file++) { - if (file->isDirectory()) - continue; - - for (g = kyra_games; g->gameid; g++) { - if (scumm_stricmp(file->displayName().c_str(), g->checkFile) == 0) - isFound = true; - } - if (isFound) - break; - } - - if (file == fslist.end()) - return detectedGames; - - uint8 md5sum[16]; - char md5str[32 + 1]; - - if (Common::md5_file(file->path().c_str(), md5sum, NULL, kMD5FileSizeLimit)) { - for (int i = 0; i < 16; i++) { - sprintf(md5str + i * 2, "%02x", (int)md5sum[i]); - } - for (g = kyra_games; g->gameid; g++) { - if (strcmp(g->md5sum, (char *)md5str) == 0) { - detectedGames.push_back(DetectedGame(g->toGameSettings(), convertKyraLang(g->features), Common::kPlatformUnknown)); - } - } - if (detectedGames.isEmpty()) { - debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str); - - const KyraGameList *g1 = kyra_list; - while (g1->gameid) { - detectedGames.push_back(g1->toGameSettings()); - g1++; - } - } - } - return detectedGames; -} - -Engine *Engine_KYRA_create(GameDetector *detector, OSystem *system) { - return new KyraEngine(detector, system); -} - -REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine") - -namespace Kyra { - -KyraEngine::KyraEngine(GameDetector *detector, OSystem *system) - : Engine(system) { - _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = - _seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 = - _seq_Demo4 = 0; - - _seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0; - _seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0; - - _roomFilenameTable = _characterImageTable = 0; - _roomFilenameTableSize = _characterImageTableSize = 0; - _itemList = _takenList = _placedList = _droppedList = _noDropList = 0; - _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0; - _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0; - _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0; - _thePoison = _fluteString = _wispJewelStrings = _magicJewelString = _flaskFull = _fullFlask = 0; - _thePoison_Size = _fluteString_Size = _wispJewelStrings_Size = 0; - _magicJewelString_Size = _flaskFull_Size = _fullFlask_Size = 0; - - _defaultShapeTable = _healingShapeTable = _healingShape2Table = 0; - _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0; - _posionDeathShapeTable = _fluteAnimShapeTable = 0; - _posionDeathShapeTableSize = _fluteAnimShapeTableSize = 0; - _winterScrollTable = _winterScroll1Table = _winterScroll2Table = 0; - _winterScrollTableSize = _winterScroll1TableSize = _winterScroll2TableSize = 0; - _drinkAnimationTable = _brandonToWispTable = _magicAnimationTable = _brandonStoneTable = 0; - _drinkAnimationTableSize = _brandonToWispTableSize = _magicAnimationTableSize = _brandonStoneTableSize = 0; - - // Setup mixer - if (!_mixer->isReady()) { - warning("Sound initialization failed."); - } - - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - - // Detect game features based on MD5. Again brutally ripped from Gobliins. - uint8 md5sum[16]; - char md5str[32 + 1]; - - const KyraGameSettings *g; - bool found = false; - - // TODO - // Fallback. Maybe we will be able to determine game type from game - // data contents - _features = 0; - - for (g = kyra_games; g->gameid; g++) { - if (!Common::File::exists(g->checkFile)) - continue; - - if (Common::md5_file(g->checkFile, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) { - for (int j = 0; j < 16; j++) { - sprintf(md5str + j*2, "%02x", (int)md5sum[j]); - } - } else - continue; - - if (strcmp(g->md5sum, (char *)md5str) == 0) { - _features = g->features; - _game = g->id; - - if (g->description) - g_system->setWindowCaption(g->description); - - found = true; - break; - } - } - - if (!found) { - debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team", md5str); - _features = 0; - _game = GI_KYRA1; - Common::File test; - if (test.open("INTRO.VRM")) { - _features |= GF_TALKIE; - } else { - _features |= GF_FLOPPY; - } - - // tries to detect the language - const KyraLanguageTable *lang = kyra_languages; - for (; lang->file; ++lang) { - if (test.open(lang->file)) { - _features |= lang->language; - found = true; - break; - } - } - - if (!found) { - _features |= GF_LNGUNK; - } - } -} - -int KyraEngine::init(GameDetector &detector) { - _system->beginGFXTransaction(); - initCommonGFX(detector); - //for debug reasons (see Screen::updateScreen) - //_system->initSize(640, 200); - _system->initSize(320, 200); - _system->endGFXTransaction(); - - // for now we prefer MIDI-to-Adlib conversion over native midi - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB/* | MDT_PREFER_MIDI*/); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - if (midiDriver == MD_ADLIB) { - // In this case we should play the Adlib tracks, but for now - // the automagic MIDI-to-Adlib conversion will do. - } else if (native_mt32) { - driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - } - - _sound = new SoundPC(driver, _mixer, this); - assert(_sound); - static_cast<SoundPC*>(_sound)->hasNativeMT32(native_mt32); - _sound->setVolume(255); - - _saveFileMan = _system->getSavefileManager(); - assert(_saveFileMan); - _res = new Resource(this); - assert(_res); - _screen = new Screen(this, _system); - assert(_screen); - _sprites = new Sprites(this, _system); - assert(_sprites); - _seq = new SeqPlayer(this, _system); - assert(_seq); - _animator = new ScreenAnimator(this, _system); - assert(_animator); - _animator->init(5, 11, 12); - assert(*_animator); - _text = new TextDisplayer(_screen); - assert(_text); - - _paletteChanged = 1; - _currentCharacter = 0; - _characterList = new Character[11]; - assert(_characterList); - for (int i = 0; i < 11; ++i) { - memset(&_characterList[i], 0, sizeof(Character)); - memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); - } - _characterList[0].sceneId = 5; - _characterList[0].height = 48; - _characterList[0].facing = 3; - _characterList[0].currentAnimFrame = 7; - - _scriptInterpreter = new ScriptHelper(this); - assert(_scriptInterpreter); - - _npcScriptData = new ScriptData; - memset(_npcScriptData, 0, sizeof(ScriptData)); - assert(_npcScriptData); - _npcScript = new ScriptState; - assert(_npcScript); - memset(_npcScript, 0, sizeof(ScriptState)); - - _scriptMain = new ScriptState; - assert(_scriptMain); - memset(_scriptMain, 0, sizeof(ScriptState)); - - _scriptClickData = new ScriptData; - assert(_scriptClickData); - memset(_scriptClickData, 0, sizeof(ScriptData)); - _scriptClick = new ScriptState; - assert(_scriptClick); - memset(_scriptClick, 0, sizeof(ScriptState)); - - _debugger = new Debugger(this); - assert(_debugger); - memset(_shapes, 0, sizeof(_shapes)); - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { - _movieObjects[i] = createWSAMovie(); - } - - memset(_flagsTable, 0, sizeof(_flagsTable)); - - _abortWalkFlag = false; - _abortWalkFlag2 = false; - _talkingCharNum = -1; - _charSayUnk3 = -1; - _mouseX = _mouseY = -1; - memset(_currSentenceColor, 0, 3); - _startSentencePalIndex = -1; - _fadeText = false; - - _cauldronState = 0; - _crystalState[0] = _crystalState[1] = -1; - - _brandonStatusBit = 0; - _brandonStatusBit0x02Flag = _brandonStatusBit0x20Flag = 10; - _brandonPosX = _brandonPosY = -1; - _deathHandler = 0xFF; - _poisonDeathCounter = 0; - - memset(_itemTable, 0, sizeof(_itemTable)); - memset(_exitList, 0xFFFF, sizeof(_exitList)); - _exitListPtr = 0; - _pathfinderFlag = _pathfinderFlag2 = 0; - _lastFindWayRet = 0; - _sceneChangeState = _loopFlag2 = 0; - _timerNextRun = 0; - - _movFacingTable = new int[150]; - assert(_movFacingTable); - _movFacingTable[0] = 8; - - _configTalkspeed = 1; - - _marbleVaseItem = -1; - memset(_foyerItemTable, -1, sizeof(_foyerItemTable)); - _mouseState = _itemInHand = -1; - _handleInput = false; - - _currentRoom = 0xFFFF; - _scenePhasingFlag = 0; - _lastProcessedItem = 0; - _lastProcessedItemHeight = 16; - - _unkScreenVar1 = 1; - _unkScreenVar2 = 0; - _unkScreenVar3 = 0; - _unkAmuletVar = 0; - - _endSequenceNeedLoading = 1; - _malcolmFlag = 0; - _beadStateVar = 0; - _endSequenceSkipFlag = 0; - _unkEndSeqVar2 = 0; - _endSequenceBackUpRect = 0; - _unkEndSeqVar4 = 0; - _unkEndSeqVar5 = 0; - _lastDisplayedPanPage = 0; - memset(_panPagesTable, 0, sizeof(_panPagesTable)); - _finalA = _finalB = _finalC = 0; - memset(&_kyragemFadingState, 0, sizeof(_kyragemFadingState)); - _kyragemFadingState.gOffset = 0x13; - _kyragemFadingState.bOffset = 0x13; - - memset(_specialPalettes, 0, sizeof(_specialPalettes)); - _mousePressFlag = false; - - _targetName = detector._targetName; - _menuDirectlyToLoad = false; - - _lastMusicCommand = 0; - - _gameSpeed = 60; - _tickLength = (uint8)(1000.0 / _gameSpeed); - - return 0; -} - -KyraEngine::~KyraEngine() { - closeFinalWsa(); - _scriptInterpreter->unloadScript(_npcScriptData); - _scriptInterpreter->unloadScript(_scriptClickData); - - delete _debugger; - delete _sprites; - delete _animator; - delete _screen; - delete _res; - delete _sound; - delete _saveFileMan; - delete _seq; - delete _scriptInterpreter; - delete _text; - - delete _npcScriptData; - delete _scriptMain; - - delete _scriptClickData; - delete _scriptClick; - - delete [] _characterList; - - delete [] _movFacingTable; - - free(_scrollUpButton.process0PtrShape); - free(_scrollUpButton.process1PtrShape); - free(_scrollUpButton.process2PtrShape); - free(_scrollDownButton.process0PtrShape); - free(_scrollDownButton.process1PtrShape); - free(_scrollDownButton.process2PtrShape); - - for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { - if (_shapes[i] != 0) { - free(_shapes[i]); - _shapes[i] = 0; - for (int i2 = 0; i2 < ARRAYSIZE(_shapes); i2++) { - if (_shapes[i2] == _shapes[i] && i2 != i) { - _shapes[i2] = 0; - } - } - } - } - for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) { - free(_sceneAnimTable[i]); - } -} - -void KyraEngine::errorString(const char *buf1, char *buf2) { - strcpy(buf2, buf1); -} - -int KyraEngine::go() { - _quitFlag = false; - uint32 sz; - - res_loadResources(); - if (_features & GF_FLOPPY) { - _screen->loadFont(Screen::FID_6_FNT, _res->fileData("6.FNT", &sz)); - } - _screen->loadFont(Screen::FID_8_FNT, _res->fileData("8FAT.FNT", &sz)); - _screen->setScreenDim(0); - - _abortIntroFlag = false; - - if (_features & GF_DEMO) { - seq_demo(); - } else { - setGameFlag(0xF3); - setGameFlag(0xFD); - setGameFlag(0xEF); - seq_intro(); - if (_skipIntroFlag &&_abortIntroFlag) - resetGameFlag(0xEF); - startup(); - resetGameFlag(0xEF); - mainLoop(); - } - quitGame(); - return 0; -} - -void KyraEngine::startup() { - debug(9, "KyraEngine::startup()"); - static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 }; - _screen->setTextColorMap(colorMap); -// _screen->setFont(Screen::FID_6_FNT); - _screen->setAnimBlockPtr(3750); - memset(_sceneAnimTable, 0, sizeof(_sceneAnimTable)); - loadMouseShapes(); - _currentCharacter = &_characterList[0]; - for (int i = 1; i < 5; ++i) - _animator->setCharacterDefaultFrame(i); - for (int i = 5; i <= 10; ++i) - setCharactersPositions(i); - _animator->setCharactersHeight(); - resetBrandonPoisonFlags(); - _maskBuffer = _screen->getPagePtr(5); - _screen->_curPage = 0; - // XXX - for (int i = 0; i < 0x0C; ++i) { - int size = _screen->getRectSize(3, 24); - _shapes[365+i] = (byte*)malloc(size); - } - _shapes[0] = (uint8*)malloc(_screen->getRectSize(3, 24)); - memset(_shapes[0], 0, _screen->getRectSize(3, 24)); - _shapes[1] = (uint8*)malloc(_screen->getRectSize(4, 32)); - memset(_shapes[1], 0, _screen->getRectSize(4, 32)); - _shapes[2] = (uint8*)malloc(_screen->getRectSize(8, 69)); - memset(_shapes[2], 0, _screen->getRectSize(8, 69)); - _shapes[3] = (uint8*)malloc(_screen->getRectSize(8, 69)); - memset(_shapes[3], 0, _screen->getRectSize(8, 69)); - for (int i = 0; i < _roomTableSize; ++i) { - for (int item = 0; item < 12; ++item) { - _roomTable[i].itemsTable[item] = 0xFF; - _roomTable[i].itemsXPos[item] = 0xFFFF; - _roomTable[i].itemsYPos[item] = 0xFF; - _roomTable[i].needInit[item] = 0; - } - } - loadCharacterShapes(); - loadSpecialEffectShapes(); - loadItems(); - loadButtonShapes(); - initMainButtonList(); - loadMainScreen(); - setupTimers(); - loadPalette("PALETTE.COL", _screen->_currentPalette); - - // XXX - _animator->initAnimStateList(); - setCharactersInDefaultScene(); - - if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, _opcodeTable, _opcodeTableSize, 0)) { - error("Could not load \"_STARTUP.EMC\" script"); - } - _scriptInterpreter->initScript(_scriptMain, _npcScriptData); - if (!_scriptInterpreter->startScript(_scriptMain, 0)) { - error("Could not start script function 0 of script \"_STARTUP.EMC\""); - } - while (_scriptInterpreter->validScript(_scriptMain)) { - _scriptInterpreter->runScript(_scriptMain); - } - - _scriptInterpreter->unloadScript(_npcScriptData); - if (!_scriptInterpreter->loadScript("_NPC.EMC", _npcScriptData, _opcodeTable, _opcodeTableSize, 0)) { - error("Could not load \"_NPC.EMC\" script"); - } - - snd_playTheme(1); - snd_setSoundEffectFile(1); - enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); - - if (_abortIntroFlag && _skipFlag) { - _menuDirectlyToLoad = true; - _screen->setMouseCursor(1, 1, _shapes[4]); - buttonMenuCallback(0); - _menuDirectlyToLoad = false; - } else - saveGame(getSavegameFilename(0), "New game"); -} - -void KyraEngine::mainLoop() { - debug(9, "KyraEngine::mainLoop()"); - - while (!_quitFlag) { - int32 frameTime = (int32)_system->getMillis(); - _skipFlag = false; - - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - if (seq_playEnd()) { - if (_deathHandler != 8) - break; - } - } - - if (_deathHandler != 0xFF) { - // this is only used until the original gui is implemented - GUI::MessageDialog dialog("Brandon is dead! Game over!", "Quit"); - dialog.runModal(); - break; - } - - if (_brandonStatusBit & 2) { - if (_brandonStatusBit0x02Flag) - _animator->animRefreshNPC(0); - } - if (_brandonStatusBit & 0x20) { - if (_brandonStatusBit0x20Flag) { - _animator->animRefreshNPC(0); - _brandonStatusBit0x20Flag = 0; - } - } - - _screen->showMouse(); - - processButtonList(_buttonList); - updateMousePointer(); - updateGameTimers(); - updateTextFade(); - - _handleInput = true; - delay((frameTime + _gameSpeed) - _system->getMillis(), true, true); - _handleInput = false; - } -} - -void KyraEngine::quitGame() { - res_unloadResources(RES_ALL); - - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { - _movieObjects[i]->close(); - delete _movieObjects[i]; - _movieObjects[i] = 0; - } - - _system->quit(); -} - -void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) { - OSystem::Event event; - char saveLoadSlot[20]; - char savegameName[14]; - - _mousePressFlag = false; - uint32 start = _system->getMillis(); - do { - while (_system->pollEvent(event)) { - switch (event.type) { - case OSystem::EVENT_KEYDOWN: - if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && - (event.kbd.flags == OSystem::KBD_CTRL || event.kbd.flags == OSystem::KBD_ALT) && isMainLoop) { - sprintf(saveLoadSlot, "%s.00%d", _targetName.c_str(), event.kbd.keycode - '0'); - if (event.kbd.flags == OSystem::KBD_CTRL) - loadGame(saveLoadSlot); - else { - sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); - saveGame(saveLoadSlot, savegameName); - } - } else if (event.kbd.flags == OSystem::KBD_CTRL) { - if (event.kbd.keycode == 'd') - _debugger->attach(); - else if (event.kbd.keycode == 'q') - _quitFlag = true; - } else if (event.kbd.keycode == '.') - _skipFlag = true; - else if (event.kbd.keycode == 13 || event.kbd.keycode == 32 || event.kbd.keycode == 27) { - _abortIntroFlag = true; - _skipFlag = true; - } - - break; - case OSystem::EVENT_MOUSEMOVE: - _mouseX = event.mouse.x; - _mouseY = event.mouse.y; - _system->updateScreen(); - break; - case OSystem::EVENT_QUIT: - quitGame(); - break; - case OSystem::EVENT_LBUTTONDOWN: - _mousePressFlag = true; - if (_abortWalkFlag2) { - _abortWalkFlag = true; - _mouseX = event.mouse.x; - _mouseY = event.mouse.y; - } - if (_handleInput) { - _mouseX = event.mouse.x; - _mouseY = event.mouse.y; - _handleInput = false; - processInput(_mouseX, _mouseY); - _handleInput = true; - } else - _skipFlag = true; - break; - default: - break; - } - } - if (_debugger->isAttached()) - _debugger->onFrame(); - - if (update) - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - - if (_currentCharacter && _currentCharacter->sceneId == 210) { - updateKyragemFading(); - } - - if (amount > 0 && !_skipFlag) { - _system->delayMillis((amount > 10) ? 10 : amount); - } - } while (!_skipFlag && _system->getMillis() < start + amount); - -} - -void KyraEngine::waitForEvent() { - bool finished = false; - OSystem::Event event; - while (!finished) { - while (_system->pollEvent(event)) { - switch (event.type) { - case OSystem::EVENT_KEYDOWN: - finished = true; - break; - case OSystem::EVENT_MOUSEMOVE: - _mouseX = event.mouse.x; - _mouseY = event.mouse.y; - break; - case OSystem::EVENT_QUIT: - quitGame(); - break; - case OSystem::EVENT_LBUTTONDOWN: - finished = true; - _skipFlag = true; - break; - default: - break; - } - } - - if (_debugger->isAttached()) - _debugger->onFrame(); - - _system->delayMillis(10); - } -} - -void KyraEngine::delayWithTicks(int ticks) { - uint32 nextTime = _system->getMillis() + ticks * _tickLength; - while (_system->getMillis() < nextTime && !_skipFlag) { - _sprites->updateSceneAnims(); - _animator->updateAllObjectShapes(); - if (_currentCharacter->sceneId == 210) { - updateKyragemFading(); - seq_playEnd(); - } - } -} - -#pragma mark - -#pragma mark - Animation/shape specific code -#pragma mark - - -void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags) { - debug(9, "KyraEngine::setupShapes123(0x%X, startShape, flags)", shapeTable, endShape, flags); - for (int i = 123; i <= 172; ++i) { - _shapes[4+i] = NULL; - } - uint8 curImage = 0xFF; - int curPageBackUp = _screen->_curPage; - _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff - int shapeFlags = 2; - if (flags) - shapeFlags = 3; - for (int i = 123; i < 123+endShape; ++i) { - uint8 newImage = shapeTable[i-123].imageIndex; - if (newImage != curImage && newImage != 0xFF) { - assert(_characterImageTable); - loadBitmap(_characterImageTable[newImage], 8, 8, 0); - curImage = newImage; - } - _shapes[4+i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); - assert(i-7 < _defaultShapeTableSize); - _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; - _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; - _defaultShapeTable[i-7].w = shapeTable[i-123].w; - _defaultShapeTable[i-7].h = shapeTable[i-123].h; - } - _screen->_curPage = curPageBackUp; -} - -void KyraEngine::freeShapes123() { - debug(9, "KyraEngine::freeShapes123()"); - for (int i = 123; i <= 172; ++i) { - free(_shapes[4+i]); - _shapes[4+i] = NULL; - } -} - -#pragma mark - -#pragma mark - Misc stuff -#pragma mark - - -Movie *KyraEngine::createWSAMovie() { - // for kyra2 here could be added then WSAMovieV2 - return new WSAMovieV1(this); -} - -int KyraEngine::setGameFlag(int flag) { - _flagsTable[flag >> 3] |= (1 << (flag & 7)); - return 1; -} - -int KyraEngine::queryGameFlag(int flag) { - return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1); -} - -int KyraEngine::resetGameFlag(int flag) { - _flagsTable[flag >> 3] &= ~(1 << (flag & 7)); - return 0; -} - -void KyraEngine::setBrandonPoisonFlags(int reset) { - debug(9, "KyraEngine::setBrandonPoisonFlags(%d)", reset); - _brandonStatusBit |= 1; - if (reset) - _poisonDeathCounter = 0; - for (int i = 0; i < 0x100; ++i) { - _brandonPoisonFlagsGFX[i] = i; - } - _brandonPoisonFlagsGFX[0x99] = 0x34; - _brandonPoisonFlagsGFX[0x9A] = 0x35; - _brandonPoisonFlagsGFX[0x9B] = 0x37; - _brandonPoisonFlagsGFX[0x9C] = 0x38; - _brandonPoisonFlagsGFX[0x9D] = 0x2B; -} - -void KyraEngine::resetBrandonPoisonFlags() { - debug(9, "KyraEngine::resetBrandonPoisonFlags()"); - _brandonStatusBit = 0; - for (int i = 0; i < 0x100; ++i) { - _brandonPoisonFlagsGFX[i] = i; - } -} - -#pragma mark - -#pragma mark - Input -#pragma mark - - -void KyraEngine::processInput(int xpos, int ypos) { - debug(9, "KyraEngine::processInput(%d, %d)", xpos, ypos); - _abortWalkFlag2 = false; - - if (processInputHelper(xpos, ypos)) { - return; - } - uint8 item = findItemAtPos(xpos, ypos); - if (item == 0xFF) { - _changedScene = false; - int handled = clickEventHandler(xpos, ypos); - if (_changedScene || handled) - return; - } - - // XXX _deathHandler specific - if (ypos <= 158) { - uint16 exit = 0xFFFF; - if (xpos < 12) { - exit = _walkBlockWest; - } else if (xpos >= 308) { - exit = _walkBlockEast; - } else if (ypos >= 136) { - exit = _walkBlockSouth; - } else if (ypos < 12) { - exit = _walkBlockNorth; - } - - if (exit != 0xFFFF) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } else { - int script = checkForNPCScriptRun(xpos, ypos); - if (script >= 0) { - runNpcScript(script); - return; - } - if (_itemInHand != -1) { - if (ypos < 155) { - if (hasClickedOnExit(xpos, ypos)) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - return; - } - dropItem(0, _itemInHand, xpos, ypos, 1); - } - } else { - if (ypos <= 155) { - _abortWalkFlag2 = true; - handleSceneChange(xpos, ypos, 1, 1); - _abortWalkFlag2 = false; - } - } - } - } -} - -int KyraEngine::processInputHelper(int xpos, int ypos) { - debug(9, "KyraEngine::processInputHelper(%d, %d)", xpos, ypos); - uint8 item = findItemAtPos(xpos, ypos); - if (item != 0xFF) { - if (_itemInHand == -1) { - _screen->hideMouse(); - _animator->animRemoveGameItem(item); - snd_playSoundEffect(53); - assert(_currentCharacter->sceneId < _roomTableSize); - Room *currentRoom = &_roomTable[_currentCharacter->sceneId]; - int item2 = currentRoom->itemsTable[item]; - currentRoom->itemsTable[item] = 0xFF; - setMouseItem(item2); - assert(_itemList && _takenList); - updateSentenceCommand(_itemList[item2], _takenList[0], 179); - _itemInHand = item2; - _screen->showMouse(); - clickEventHandler2(); - return 1; - } else { - exchangeItemWithMouseItem(_currentCharacter->sceneId, item); - return 1; - } - } - return 0; -} - -int KyraEngine::clickEventHandler(int xpos, int ypos) { - debug(9, "KyraEngine::clickEventHandler(%d, %d)", xpos, ypos); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptClick->variables[1] = xpos; - _scriptClick->variables[2] = ypos; - _scriptClick->variables[3] = 0; - _scriptClick->variables[4] = _itemInHand; - _scriptInterpreter->startScript(_scriptClick, 1); - - while (_scriptInterpreter->validScript(_scriptClick)) { - _scriptInterpreter->runScript(_scriptClick); - } - - return _scriptClick->variables[3]; -} - -void KyraEngine::updateMousePointer(bool forceUpdate) { - int shape = 0; - - int newMouseState = 0; - int newX = 0; - int newY = 0; - if (_mouseY <= 158) { - if (_mouseX >= 12) { - if (_mouseX >= 308) { - if (_walkBlockEast == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - } - } else if (_mouseY >= 136) { - if (_walkBlockSouth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - } - } else if (_mouseY < 12) { - if (_walkBlockNorth == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - } - } - } else { - if (_walkBlockWest == 0xFFFF) { - newMouseState = -2; - } else { - newMouseState = -3; - newX = 1; - newY = shape = 5; - } - } - } - - if (_mouseX >= _entranceMouseCursorTracks[0] && _mouseY >= _entranceMouseCursorTracks[1] - && _mouseX <= _entranceMouseCursorTracks[2] && _mouseY <= _entranceMouseCursorTracks[3]) { - switch (_entranceMouseCursorTracks[4]) { - case 0: - newMouseState = -6; - shape = 2; - newX = 5; - newY = 1; - break; - - case 2: - newMouseState = -5; - shape = 3; - newX = 7; - newY = 5; - break; - - case 4: - newMouseState = -4; - shape = 4; - newX = 5; - newY = 7; - break; - - case 6: - newMouseState = -3; - shape = 5; - newX = 1; - newY = 5; - break; - - default: - break; - } - } - - if (newMouseState == -2) { - shape = 6; - newX = 4; - newY = 4; - } - - if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { - _mouseState = newMouseState; - _screen->hideMouse(); - _screen->setMouseCursor(newX, newY, _shapes[4+shape]); - _screen->showMouse(); - } - - if (!newMouseState) { - if (_mouseState != _itemInHand || forceUpdate) { - if (_mouseY > 158 || (_mouseX >= 12 && _mouseX < 308 && _mouseY < 136 && _mouseY >= 12) || forceUpdate) { - _mouseState = _itemInHand; - _screen->hideMouse(); - if (_itemInHand == -1) { - _screen->setMouseCursor(1, 1, _shapes[4]); - } else { - _screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]); - } - _screen->showMouse(); - } - } - } -} - -bool KyraEngine::hasClickedOnExit(int xpos, int ypos) { - debug(9, "KyraEngine::hasClickedOnExit(%d, %d)", xpos, ypos); - if (xpos < 16 || xpos >= 304) { - return true; - } - if (ypos < 8) - return true; - if (ypos < 136 || ypos > 155) { - return false; - } - return true; -} - -void KyraEngine::clickEventHandler2() { - debug(9, "KyraEngine::clickEventHandler2()"); - _scriptInterpreter->initScript(_scriptClick, _scriptClickData); - _scriptClick->variables[0] = _currentCharacter->sceneId; - _scriptClick->variables[1] = _mouseX; - _scriptClick->variables[2] = _mouseY; - _scriptClick->variables[4] = _itemInHand; - _scriptInterpreter->startScript(_scriptClick, 6); - - while (_scriptInterpreter->validScript(_scriptClick)) { - _scriptInterpreter->runScript(_scriptClick); - } -} - -int KyraEngine::checkForNPCScriptRun(int xpos, int ypos) { - debug(9, "KyraEngine::checkForNPCScriptRun(%d, %d)", xpos, ypos); - int returnValue = -1; - const Character *currentChar = _currentCharacter; - int charLeft = 0, charRight = 0, charTop = 0, charBottom = 0; - - int scaleFactor = _scaleTable[currentChar->y1]; - int addX = (((scaleFactor*8)*3)>>8)>>1; - int addY = ((scaleFactor*3)<<4)>>8; - - charLeft = currentChar->x1 - addX; - charRight = currentChar->x1 + addX; - charTop = currentChar->y1 - addY; - charBottom = currentChar->y1; - - if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) { - return 0; - } - - if (xpos > 304 || xpos < 16) { - return -1; - } - - for (int i = 1; i < 5; ++i) { - currentChar = &_characterList[i]; - - if (currentChar->sceneId != _currentCharacter->sceneId) - continue; - - charLeft = currentChar->x1 - 12; - charRight = currentChar->x1 + 11; - charTop = currentChar->y1 - 48; - // if (!i) { - // charBottom = currentChar->y2 - 16; - // } else { - charBottom = currentChar->y1; - // } - - if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) { - continue; - } - - if (returnValue != -1) { - if (currentChar->y1 >= _characterList[returnValue].y1) { - returnValue = i; - } - } else { - returnValue = i; - } - } - - return returnValue; -} - -void KyraEngine::runNpcScript(int func) { - debug(9, "KyraEngine::runNpcScript(%d)", func); - _scriptInterpreter->initScript(_npcScript, _npcScriptData); - _scriptInterpreter->startScript(_npcScript, func); - _npcScript->variables[0] = _currentCharacter->sceneId; - _npcScript->variables[4] = _itemInHand; - _npcScript->variables[5] = func; - - while (_scriptInterpreter->validScript(_npcScript)) { - _scriptInterpreter->runScript(_npcScript); - } -} -} // End of namespace Kyra |