/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 3 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 * aint32 with this program; if not, write to the Free Software * * * Based on the original sources * Faery Tale II -- The Halls of the Dead * (c) 1993-1996 The Wyrmkeep Entertainment Co. */ #include "saga2/saga2.h" #include "saga2/detection.h" #include "saga2/towerwin.h" #include "saga2/towerfta.h" #include "saga2/fta.h" #include "saga2/mainmap.h" #include "saga2/tromode.h" #include "saga2/script.h" #include "saga2/vpal.h" #include "saga2/palette.h" #include "saga2/intrface.h" #include "saga2/mouseimg.h" #include "saga2/patrol.h" #include "saga2/weapons.h" #include "saga2/saveload.h" #include "saga2/display.h" #include "saga2/tile.h" #include "saga2/vpal.h" namespace Saga2 { /* ===================================================================== * FTA initialization & cleanup records * ===================================================================== */ int maxInitState = kFullyInitialized; TowerLayer tower[kFullyInitialized] = { { kNothingInitialized, &initTowerBase, &termTowerBase }, { kErrHandlersInitialized, &initErrorManagers, &termErrorManagers }, { kDelayedErrInitialized, &initDelayedErrors, &termDelayedErrors }, { kActiveErrInitialized, &initActiveErrors, &termActiveErrors }, { kConfigTestInitialized, &initSystemConfig, &termTowerBase }, { kIntroInitialized, &initPlayIntro, &termPlayOutro }, { kTimerInitialized, &initSystemTimer, &termSystemTimer }, { kAudioInitialized, &initAudio, &termAudio}, { kResourcesInitialized, &initResourceFiles, &termResourceFiles }, { kServersInitialized, &initResourceServers, &termResourceServers }, { kPathFinderInitialized, &initPathFinders, &termPathFinders }, { kScriptsInitialized, &initSAGAInterpreter, &termSAGAInterpreter }, { kAudStartInitialized, &initAudioChannels, &termAudioChannels }, { kTileResInitialized, &initResourceHandles, &termResourceHandles }, { kPalettesInitialized, &initPalettes, &termPalettes }, { kMainWindowInitialized, &initDisplayPort, &termDisplayPort }, { kPanelsInitialized, &initPanelSystem, &termPanelSystem }, { kMainWindowOpenInitialized, &initMainWindow, &termMainWindow }, { kGuiMessInitialized, &initGUIMessagers, &termGUIMessagers }, { kMouseImageInitialized, &initMousePointer, &termMousePointer }, { kDisplayInitialized, &initDisplay, &termDisplay }, { kMapsInitialized, &initGameMaps, &termGameMaps }, { kPatrolsInitialized, &initRouteData, &termRouteData }, { kSpritesInitialized, &initActorSprites, &termActorSprites }, { kWeaponsInitialized, &initWeaponData, &termWeaponData }, { kMagicInitialized, &initSpellData, &termSpellData }, { kObjectSoundFXInitialized, &initObjectSoundFX, &termObjectSoundFX }, { kPrototypesInitialized, &initObjectPrototypes, &termObjectPrototypes }, { kGameStateInitialized, &initDynamicGameData, &termDynamicGameData }, { kGameModeInitialized, &initGameMode, &termGameMode }, { kGameDisplayEnabled, &initTop, &termTop }, { kProcResEnabled, &initProcessResources, &termProcessResources } }; /* ===================================================================== * Declarations for FTA initialization & cleanup * ===================================================================== */ //#include "saga2/loadmsg.h" void cleanupGUIMessagers(); bool openResources(); void closeResources(); void initMagic(); void cleanupMagic(); void cleanupMousePointer(); void resetInputDevices(); extern hResContext *tileRes; // tile resource handle extern hResContext *listRes; extern ResImportTable *resImports; extern BackWindow *mainWindow; // main window... extern gPanelList *trioControls; extern gPanelList *indivControls; /* ===================================================================== * Actual FTA initialization & cleanup pairs * ===================================================================== */ // ------------------------------------------------------------------------ INITIALIZER(initSystemConfig) { return true; } // uses null cleanup // ------------------------------------------------------------------------ INITIALIZER(initPlayIntro) { setIntroMode(); return true; } TERMINATOR(termPlayOutro) { setOutroMode(); } // ------------------------------------------------------------------------ TERMINATOR(termSystemTimer) { cleanupSystemTimer(); } // ------------------------------------------------------------------------ TERMINATOR (termAudio) { cleanupAudio(); } // ------------------------------------------------------------------------ INITIALIZER(initResourceFiles) { return openResources(); } TERMINATOR(termResourceFiles) { closeResources(); } // ------------------------------------------------------------------------ INITIALIZER(initResourceServers) { return true; } TERMINATOR(termResourceServers) { } // ------------------------------------------------------------------------ INITIALIZER(initPathFinders) { initPathFinder(); return true; } TERMINATOR(termPathFinders) { cleanupPathFinder(); // cleanup pathfinder server } // ------------------------------------------------------------------------ INITIALIZER(initSAGAInterpreter) { initScripts(); return true; } TERMINATOR(termSAGAInterpreter) { cleanupScripts(); // cleanup SAGA interpreter } // ------------------------------------------------------------------------ INITIALIZER(initAudioChannels) { startAudio(); return true; } TERMINATOR(termAudioChannels) { } // ------------------------------------------------------------------------ INITIALIZER(initResourceHandles) { tileRes = resFile->newContext(MKTAG('T', 'I', 'L', 'E'), "tile resources"); if (!tileRes->_valid) return false; listRes = objResFile->newContext(MKTAG('L', 'I', 'S', 'T'), "list resources"); if (!listRes->_valid) return false; if (g_vm->getGameId() == GID_FTA2) { // Only FTA2 has resource imports Common::SeekableReadStream *stream = loadResourceToStream(listRes, MKTAG('I', 'M', 'P', 'O'), "res imports"); if (!stream) return false; resImports = (ResImportTable *)malloc(sizeof(ResImportTable)); resImports->deadActorProto = (int16)stream->readSint16LE(); (void)stream->readSint16LE(); (void)stream->readSint16LE(); resImports->EXP_spellEffect_CreateFireWisp = stream->readSint16LE(); resImports->EXP_spellEffect_CreateWindWisp = stream->readSint16LE(); resImports->EXP_spellEffect_CreateWraith = stream->readSint16LE(); resImports->EXP_spellEffect_TeleportToShrine = stream->readSint16LE(); resImports->EXP_spellEffect_Rejoin = stream->readSint16LE(); resImports->EXP_spellEffect_Timequake = stream->readSint16LE(); resImports->EXP_spellEffect_CreateFood = stream->readSint16LE(); delete stream; } return true; } TERMINATOR(termResourceHandles) { if (resImports) { free(resImports); resImports = nullptr; } if (listRes) objResFile->disposeContext(listRes); listRes = nullptr; if (tileRes) resFile->disposeContext(tileRes); tileRes = nullptr; } // ------------------------------------------------------------------------ INITIALIZER(initPalettes) { g_vm->_pal->loadPalettes(); return true; } TERMINATOR(termPalettes) { cleanupPaletteData(); } // ------------------------------------------------------------------------ INITIALIZER(initDisplayPort) { initBackPanel(); return true; } TERMINATOR(termDisplayPort) { if (mainWindow) delete mainWindow; mainWindow = nullptr; } // ------------------------------------------------------------------------ INITIALIZER(initPanelSystem) { initPanels(g_vm->_mainPort); if (g_vm->_mainPort._map == nullptr) { gPixelMap *tmap = new gPixelMap; tmap->_size = Point16(kScreenWidth, kScreenHeight); tmap->_data = new uint8[tmap->bytes()]; g_vm->_mainPort.setMap(tmap); } return true; } TERMINATOR(termPanelSystem) { cleanupPanels(); // restore mouse state } // ------------------------------------------------------------------------ INITIALIZER(initMainWindow) { mainWindow->open(); return true; } TERMINATOR(termMainWindow) { } // ------------------------------------------------------------------------ TERMINATOR(termGUIMessagers) { cleanupGUIMessagers(); } // ------------------------------------------------------------------------ INITIALIZER(initMousePointer) { //pointer.hide(); setMouseImage(kMouseArrowImage, 0, 0); return g_vm->_pointer->init(640, 480); } TERMINATOR(termMousePointer) { cleanupMousePointer(); } // ------------------------------------------------------------------------ INITIALIZER(initDisplay) { g_vm->_mainPort.setColor(0); // fill screen with color drawPage = &g_vm->_mainPort._protoPage; //lightsOut(); //g_vm->_mainPort.fillRect( Rect16( 0, 0, screenWidth, screenHeight ) ); // Create a panelList to contain the controls which are // only active when all three brothers are shown if ((trioControls = new gPanelList(*mainWindow)) == nullptr) return false; // Create a panelList to contain the controls which are // only active when a single brother is shown if ((indivControls = new gPanelList(*mainWindow)) == nullptr) return false; // Since we start in "trio" mode, turn off the "individual" // controls... indivControls->enable(false); return true; } TERMINATOR(termDisplay) { if (trioControls) { delete trioControls; trioControls = nullptr; } if (indivControls) { delete indivControls; indivControls = nullptr; } } // ------------------------------------------------------------------------ INITIALIZER(initGameMaps) { initMaps(); return true; } TERMINATOR(termGameMaps) { cleanupMaps(); } // ------------------------------------------------------------------------ INITIALIZER(initRouteData) { initPatrolRoutes(); return true; } TERMINATOR(termRouteData) { cleanupPatrolRoutes(); } // ------------------------------------------------------------------------ INITIALIZER(initActorSprites) { initSprites(); return true; } TERMINATOR(termActorSprites) { cleanupSprites(); } // ------------------------------------------------------------------------ INITIALIZER(initWeaponData) { if (g_vm->getGameId() == GID_FTA2) initWeapons(); return true; } TERMINATOR(termWeaponData) { cleanupWeapons(); } // ------------------------------------------------------------------------ INITIALIZER(initSpellData) { if (g_vm->getGameId() == GID_FTA2) initMagic(); return true; } TERMINATOR(termSpellData) { cleanupMagic(); } // ------------------------------------------------------------------------ INITIALIZER(initObjectSoundFX) { if (g_vm->getGameId() == GID_FTA2) initObjectSoundFXTable(); return true; } TERMINATOR(termObjectSoundFX) { cleanupObjectSoundFXTable(); } // ------------------------------------------------------------------------ INITIALIZER(initObjectPrototypes) { if (g_vm->getGameId() == GID_FTA2) initPrototypes(); return true; } TERMINATOR(termObjectPrototypes) { cleanupPrototypes(); } // ------------------------------------------------------------------------ INITIALIZER(initDynamicGameData) { initGameState(); return true; } TERMINATOR(termDynamicGameData) { cleanupGameState(); } // ------------------------------------------------------------------------ INITIALIZER(initGameMode) { GameMode *gameModes[] = {&PlayMode, &TileMode}; GameMode::SetStack(gameModes, 2); if (GameMode::_newmodeFlag) GameMode::update(); return true; } TERMINATOR(termGameMode) { GameMode::modeUnStack(0); //Zero Equals Unstack All cleanupSystemTasks(); } // ------------------------------------------------------------------------ INITIALIZER(initTop) { niceScreenStartup(); return true; } TERMINATOR(termTop) { mainDisable(); } } // end of namespace Saga2