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  * aint32 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  * Based on the original sources
23  *   Faery Tale II -- The Halls of the Dead
24  *   (c) 1993-1996 The Wyrmkeep Entertainment Co.
25  */
26 
27 #include "saga2/saga2.h"
28 #include "saga2/towerwin.h"
29 #include "saga2/towerfta.h"
30 #include "saga2/fta.h"
31 #include "saga2/mainmap.h"
32 #include "saga2/tromode.h"
33 #include "saga2/script.h"
34 #include "saga2/vpal.h"
35 #include "saga2/palette.h"
36 #include "saga2/intrface.h"
37 #include "saga2/mouseimg.h"
38 #include "saga2/patrol.h"
39 #include "saga2/weapons.h"
40 #include "saga2/saveload.h"
41 #include "saga2/display.h"
42 #include "saga2/tile.h"
43 #include "saga2/vpal.h"
44 
45 namespace Saga2 {
46 
47 /* ===================================================================== *
48    FTA initialization & cleanup records
49  * ===================================================================== */
50 
51 int maxInitState = fullyInitialized;
52 
53 TowerLayer tower[fullyInitialized] = {
54 	{ nothingInitialized,        &initTowerBase,        &termTowerBase },
55 	{ errHandlersInitialized,    &initErrorManagers,    &termErrorManagers },
56 	{ delayedErrInitialized,     &initDelayedErrors,    &termDelayedErrors },
57 	{ activeErrInitialized,      &initActiveErrors,     &termActiveErrors },
58 	{ configTestInitialized,     &initSystemConfig,     &termTowerBase },
59 	{ introInitialized,          &initPlayIntro,        &termPlayOutro },
60 	{ timerInitialized,          &initSystemTimer,      &termSystemTimer },
61 	{ audioInitialized,          &initAudio,            &termAudio},
62 	{ resourcesInitialized,      &initResourceFiles,    &termResourceFiles },
63 	{ serversInitialized,        &initResourceServers,  &termResourceServers },
64 	{ pathFinderInitialized,     &initPathFinders,      &termPathFinders },
65 	{ scriptsInitialized,        &initSAGAInterpreter,  &termSAGAInterpreter },
66 	{ audStartInitialized,       &initAudioChannels,    &termAudioChannels },
67 	{ tileResInitialized,        &initResourceHandles,  &termResourceHandles },
68 	{ palettesInitialized,       &initPalettes,         &termPalettes },
69 	{ mainWindowInitialized,     &initDisplayPort,      &termDisplayPort },
70 	{ panelsInitialized,         &initPanelSystem,      &termPanelSystem },
71 	{ mainWindowOpenInitialized, &initMainWindow,       &termMainWindow },
72 	{ guiMessInitialized,        &initGUIMessagers,     &termGUIMessagers },
73 	{ mouseImageInitialized,     &initMousePointer,     &termMousePointer },
74 	{ displayInitialized,        &initDisplay,          &termDisplay },
75 	{ mapsInitialized,           &initGameMaps,         &termGameMaps },
76 	{ patrolsInitialized,        &initRouteData,        &termRouteData },
77 	{ spritesInitialized,        &initActorSprites,     &termActorSprites },
78 	{ weaponsInitialized,        &initWeaponData,       &termWeaponData },
79 	{ magicInitialized,          &initSpellData,        &termSpellData },
80 	{ objectSoundFXInitialized,  &initObjectSoundFX,    &termObjectSoundFX },
81 	{ prototypesInitialized,     &initObjectPrototypes, &termObjectPrototypes },
82 	{ gameStateInitialized,      &initDynamicGameData,  &termDynamicGameData },
83 	{ gameModeInitialized,       &initGameMode,         &termGameMode },
84 	{ gameDisplayEnabled,        &initTop,              &termTop },
85 	{ procResEnabled,            &initProcessResources, &termProcessResources }
86 };
87 
88 /* ===================================================================== *
89    Declarations for FTA initialization & cleanup
90  * ===================================================================== */
91 
92 //#include "saga2/loadmsg.h"
93 bool initGUIMessagers(void);
94 void cleanupMessagers(void);
95 void cleanupGUIMessagers(void);
96 bool openResources(void);
97 void closeResources(void);
98 void initServers(void);
99 void cleanupServers(void);
100 void initMagic(void);
101 void cleanupMagic(void);
102 void cleanupMousePointer(void);
103 void resetInputDevices(void);
104 
105 extern hResContext      *tileRes;       // tile resource handle
106 extern hResContext      *listRes;
107 extern ResImportTable   *resImports;
108 extern BackWindow       *mainWindow;            // main window...
109 extern gPanelList       *trioControls;
110 extern gPanelList       *indivControls;
111 
112 /* ===================================================================== *
113    Actual FTA initialization & cleanup pairs
114  * ===================================================================== */
115 
116 
117 // ------------------------------------------------------------------------
118 
INITIALIZER(initSystemConfig)119 INITIALIZER(initSystemConfig) {
120 	return true;
121 }
122 
123 // uses null cleanup
124 
125 // ------------------------------------------------------------------------
126 
INITIALIZER(initPlayIntro)127 INITIALIZER(initPlayIntro) {
128 	setIntroMode();
129 	return true;
130 }
131 
TERMINATOR(termPlayOutro)132 TERMINATOR(termPlayOutro) {
133 	setOutroMode();
134 }
135 
136 
137 // ------------------------------------------------------------------------
138 
139 extern INITIALIZER(initSystemTimer);
140 
TERMINATOR(termSystemTimer)141 TERMINATOR(termSystemTimer) {
142 	cleanupSystemTimer();
143 }
144 
145 // ------------------------------------------------------------------------
146 
147 extern INITIALIZER(initAudio);
148 
TERMINATOR(termAudio)149 TERMINATOR (termAudio)
150 {
151 	cleanupAudio();
152 }
153 
154 // ------------------------------------------------------------------------
155 
INITIALIZER(initResourceFiles)156 INITIALIZER(initResourceFiles) {
157 	return openResources();
158 }
159 
TERMINATOR(termResourceFiles)160 TERMINATOR(termResourceFiles) {
161 	closeResources();
162 }
163 
164 
165 // ------------------------------------------------------------------------
166 
INITIALIZER(initResourceServers)167 INITIALIZER(initResourceServers) {
168 	return true;
169 }
170 
TERMINATOR(termResourceServers)171 TERMINATOR(termResourceServers) {
172 }
173 
174 
175 // ------------------------------------------------------------------------
176 
INITIALIZER(initPathFinders)177 INITIALIZER(initPathFinders) {
178 	initPathFinder();
179 	return true;
180 }
181 
TERMINATOR(termPathFinders)182 TERMINATOR(termPathFinders) {
183 	cleanupPathFinder();                    // cleanup pathfinder server
184 }
185 
186 
187 // ------------------------------------------------------------------------
188 
INITIALIZER(initSAGAInterpreter)189 INITIALIZER(initSAGAInterpreter) {
190 	initScripts();
191 	return true;
192 }
193 
TERMINATOR(termSAGAInterpreter)194 TERMINATOR(termSAGAInterpreter) {
195 	cleanupScripts();                       // cleanup SAGA interpreter
196 }
197 
198 
199 // ------------------------------------------------------------------------
200 
INITIALIZER(initAudioChannels)201 INITIALIZER(initAudioChannels) {
202 	startAudio();
203 	return true;
204 }
205 
TERMINATOR(termAudioChannels)206 TERMINATOR(termAudioChannels) {
207 }
208 
209 
210 // ------------------------------------------------------------------------
211 
INITIALIZER(initResourceHandles)212 INITIALIZER(initResourceHandles) {
213 	tileRes = resFile->newContext(MKTAG('T', 'I', 'L', 'E'), "tile resources");
214 	if (!tileRes->_valid)
215 		return false;
216 	listRes = objResFile->newContext(MKTAG('L', 'I', 'S', 'T'), "list resources");
217 	if (!listRes->_valid)
218 		return false;
219 	resImports = (ResImportTable *)LoadResource(listRes, MKTAG('I', 'M', 'P', 'O'), "res imports");
220 	if (!resImports)
221 		return false;
222 	return true;
223 }
224 
TERMINATOR(termResourceHandles)225 TERMINATOR(termResourceHandles) {
226 	if (resImports) {
227 		free(resImports);
228 		resImports = nullptr;
229 	}
230 	if (listRes) objResFile->disposeContext(listRes);
231 	listRes = nullptr;
232 	if (tileRes) resFile->disposeContext(tileRes);
233 	tileRes = nullptr;
234 }
235 
236 
237 // ------------------------------------------------------------------------
238 
INITIALIZER(initPalettes)239 INITIALIZER(initPalettes) {
240 	g_vm->_pal->loadPalettes();
241 	return true;
242 }
243 
TERMINATOR(termPalettes)244 TERMINATOR(termPalettes) {
245 	cleanupPaletteData();
246 }
247 
248 
249 // ------------------------------------------------------------------------
250 
INITIALIZER(initDisplayPort)251 INITIALIZER(initDisplayPort) {
252 	initBackPanel();
253 	return true;
254 }
255 
TERMINATOR(termDisplayPort)256 TERMINATOR(termDisplayPort) {
257 	if (mainWindow) delete mainWindow;
258 	mainWindow = nullptr;
259 }
260 
261 
262 // ------------------------------------------------------------------------
263 
INITIALIZER(initPanelSystem)264 INITIALIZER(initPanelSystem) {
265 	initPanels(g_vm->_mainPort);
266 	if (g_vm->_mainPort.map == nullptr) {
267 		gPixelMap *tmap = new gPixelMap;
268 		tmap->size = Point16(screenWidth, screenHeight);
269 		tmap->data = new uint8[tmap->bytes()];
270 		g_vm->_mainPort.setMap(tmap);
271 	}
272 	return true;
273 }
274 
TERMINATOR(termPanelSystem)275 TERMINATOR(termPanelSystem) {
276 	cleanupPanels();                        // restore mouse state
277 }
278 
279 
280 // ------------------------------------------------------------------------
281 
INITIALIZER(initMainWindow)282 INITIALIZER(initMainWindow) {
283 	mainWindow->open();
284 	return true;
285 }
286 
TERMINATOR(termMainWindow)287 TERMINATOR(termMainWindow) {
288 }
289 
290 
291 // ------------------------------------------------------------------------
292 
293 extern INITIALIZER(initGUIMessagers);
294 
TERMINATOR(termGUIMessagers)295 TERMINATOR(termGUIMessagers) {
296 	cleanupGUIMessagers();
297 }
298 
299 
300 // ------------------------------------------------------------------------
301 
INITIALIZER(initMousePointer)302 INITIALIZER(initMousePointer) {
303 	//pointer.hide();
304 	setMouseImage(kMouseArrowImage, 0, 0);
305 	return g_vm->_pointer->init(640, 480);
306 }
307 
TERMINATOR(termMousePointer)308 TERMINATOR(termMousePointer) {
309 	cleanupMousePointer();
310 }
311 
312 
313 // ------------------------------------------------------------------------
314 
INITIALIZER(initDisplay)315 INITIALIZER(initDisplay) {
316 	g_vm->_mainPort.setColor(0);            //  fill screen with color
317 	drawPage = &g_vm->_mainPort.protoPage;
318 	//lightsOut();
319 	//g_vm->_mainPort.fillRect( Rect16( 0, 0, screenWidth, screenHeight ) );
320 
321 	//  Create a panelList to contain the controls which are
322 	//  only active when all three brothers are shown
323 	if ((trioControls = new gPanelList(*mainWindow)) == nullptr)
324 		return false;
325 
326 	//  Create a panelList to contain the controls which are
327 	//  only active when a single brother is shown
328 	if ((indivControls = new gPanelList(*mainWindow)) == nullptr)
329 		return false;
330 
331 	//  Since we start in "trio" mode, turn off the "individual"
332 	//  controls...
333 	indivControls->enable(false);
334 
335 	return true;
336 }
337 
TERMINATOR(termDisplay)338 TERMINATOR(termDisplay) {
339 	if (trioControls) {
340 		delete trioControls;
341 		trioControls = NULL;
342 	}
343 	if (indivControls) {
344 		delete indivControls;
345 		indivControls = NULL;
346 	}
347 }
348 
349 
350 // ------------------------------------------------------------------------
351 
INITIALIZER(initGameMaps)352 INITIALIZER(initGameMaps) {
353 	initMaps();
354 	return true;
355 }
356 
TERMINATOR(termGameMaps)357 TERMINATOR(termGameMaps) {
358 	cleanupMaps();
359 }
360 
361 
362 // ------------------------------------------------------------------------
363 
INITIALIZER(initRouteData)364 INITIALIZER(initRouteData) {
365 	initPatrolRoutes();
366 	return true;
367 }
368 
TERMINATOR(termRouteData)369 TERMINATOR(termRouteData) {
370 	cleanupPatrolRoutes();
371 }
372 
373 
374 // ------------------------------------------------------------------------
375 
INITIALIZER(initActorSprites)376 INITIALIZER(initActorSprites) {
377 	initSprites();
378 	return true;
379 }
380 
TERMINATOR(termActorSprites)381 TERMINATOR(termActorSprites) {
382 	cleanupSprites();
383 }
384 
385 
386 // ------------------------------------------------------------------------
387 
INITIALIZER(initWeaponData)388 INITIALIZER(initWeaponData) {
389 	initWeapons();
390 	return true;
391 }
392 
TERMINATOR(termWeaponData)393 TERMINATOR(termWeaponData) {
394 	cleanupWeapons();
395 }
396 
397 
398 // ------------------------------------------------------------------------
399 
INITIALIZER(initSpellData)400 INITIALIZER(initSpellData) {
401 	initMagic();
402 	return true;
403 }
404 
TERMINATOR(termSpellData)405 TERMINATOR(termSpellData) {
406 	cleanupMagic();
407 }
408 
409 
410 // ------------------------------------------------------------------------
411 
INITIALIZER(initObjectSoundFX)412 INITIALIZER(initObjectSoundFX) {
413 	initObjectSoundFXTable();
414 	return true;
415 }
416 
TERMINATOR(termObjectSoundFX)417 TERMINATOR(termObjectSoundFX) {
418 	cleanupObjectSoundFXTable();
419 }
420 
421 // ------------------------------------------------------------------------
422 
INITIALIZER(initObjectPrototypes)423 INITIALIZER(initObjectPrototypes) {
424 	initPrototypes();
425 	return true;
426 }
427 
TERMINATOR(termObjectPrototypes)428 TERMINATOR(termObjectPrototypes) {
429 	cleanupPrototypes();
430 }
431 
432 
433 // ------------------------------------------------------------------------
434 
INITIALIZER(initDynamicGameData)435 INITIALIZER(initDynamicGameData) {
436 	initGameState();
437 	return true;
438 }
439 
TERMINATOR(termDynamicGameData)440 TERMINATOR(termDynamicGameData) {
441 	cleanupGameState();
442 }
443 
444 
445 // ------------------------------------------------------------------------
446 
INITIALIZER(initGameMode)447 INITIALIZER(initGameMode) {
448 	GameMode *gameModes[] = {&PlayMode, &TileMode};
449 	GameMode::SetStack(gameModes, 2);
450 	if (GameMode::newmodeFlag)
451 		GameMode::update();
452 	return true;
453 }
454 
TERMINATOR(termGameMode)455 TERMINATOR(termGameMode) {
456 	GameMode::modeUnStack(0); //Zero Equals Unstack All
457 	cleanupSystemTasks();
458 }
459 
460 
461 // ------------------------------------------------------------------------
462 void RMemFastCleanup(void);
463 
INITIALIZER(initTop)464 INITIALIZER(initTop) {
465 	niceScreenStartup();
466 	return true;
467 }
468 
TERMINATOR(termTop)469 TERMINATOR(termTop) {
470 	mainDisable();
471 }
472 
473 } // end of namespace Saga2
474