mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
484 lines
13 KiB
C++
484 lines
13 KiB
C++
/* 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
|