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  * along 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 
23 // Scene management module private header file
24 
25 #ifndef SAGA_SCENE_H
26 #define SAGA_SCENE_H
27 
28 #include "saga/font.h"
29 #include "saga/actor.h"
30 #include "saga/interface.h"
31 #include "saga/puzzle.h"
32 #include "saga/events.h"
33 
34 namespace Saga {
35 
36 //#define SCENE_DEBUG // for scene debugging
37 
38 #define SCENE_DOORS_MAX 16
39 #define NO_CHAPTER_CHANGE -2
40 
41 // Scenes
42 #define ITE_SCENE_INV -1
43 #define ITE_SCENE_PUZZLE 26
44 #define ITE_SCENE_LODGE 21
45 #define ITE_SCENE_ENDCREDIT1 295
46 #define ITE_SCENE_OVERMAP 226
47 
48 // Default scenes
49 #define ITE_DEFAULT_SCENE 32
50 #define IHNM_DEFAULT_SCENE 151
51 #define ITEDEMO_DEFAULT_SCENE 68
52 #define IHNMDEMO_DEFAULT_SCENE 144
53 
54 class ObjectMap;
55 
56 enum SceneFlags {
57 	kSceneFlagISO        = 1,
58 	kSceneFlagShowCursor = 2
59 };
60 
61 // FTA2 possible endings
62 enum FTA2Endings {
63 	kFta2BadEndingLaw = 0,
64 	kFta2BadEndingChaos = 1,
65 	kFta2GoodEnding1 = 2,
66 	kFta2GoodEnding2 = 3,
67 	kFta2BadEndingDeath = 4
68 };
69 
70 struct BGInfo {
71 	Rect bounds;
72 	byte *buffer;
73 };
74 
75 typedef int (SceneProc) (int, void *);
76 
77 
78 enum SCENE_PROC_PARAMS {
79 	SCENE_BEGIN = 0,
80 	SCENE_END
81 };
82 
83 // Resource type numbers
84 enum SAGAResourceTypes {
85 	SAGA_UNKNOWN,
86 	SAGA_ACTOR,
87 	SAGA_OBJECT,
88 	SAGA_BG_IMAGE,
89 	SAGA_BG_MASK,
90 	SAGA_STRINGS,
91 	SAGA_OBJECT_MAP,
92 	SAGA_ACTION_MAP,
93 	SAGA_ISO_IMAGES,
94 	SAGA_ISO_MAP,
95 	SAGA_ISO_PLATFORMS,
96 	SAGA_ISO_METATILES,
97 	SAGA_ENTRY,
98 	SAGA_ANIM,
99 	SAGA_ISO_MULTI,
100 	SAGA_PAL_ANIM,
101 	SAGA_FACES,
102 	SAGA_PALETTE
103 };
104 
105 #define SAGA_RESLIST_ENTRY_LEN 4
106 
107 struct SceneResourceData {
108 	uint32 resourceId;
109 	int resourceType;
110 	bool invalid;
111 
SceneResourceDataSceneResourceData112 	SceneResourceData() : resourceId(0), resourceType(0),  invalid(false) {
113 	}
114 };
115 
116 typedef Common::Array<SceneResourceData> SceneResourceDataArray;
117 
118 #define SAGA_SCENE_DESC_LEN 16
119 
120 struct SceneDescription {
121 	int16 flags;
122 	int16 resourceListResourceId;
123 	int16 endSlope;
124 	int16 beginSlope;
125 	uint16 scriptModuleNumber;
126 	uint16 sceneScriptEntrypointNumber;
127 	uint16 startScriptEntrypointNumber;
128 	int16 musicResourceId;
129 
resetSceneDescription130 	void reset()  {
131 		flags = resourceListResourceId = endSlope = beginSlope = scriptModuleNumber = sceneScriptEntrypointNumber = startScriptEntrypointNumber = musicResourceId = 0;
132 	}
133 };
134 
135 struct SceneEntry {
136 	Location location;
137 	uint16 facing;
138 };
139 
140 typedef Common::Array<SceneEntry> SceneEntryList;
141 
142 struct SceneImage {
143 	bool loaded;
144 	int w;
145 	int h;
146 	int p;
147 	ByteArray buffer;
148 	PalEntry pal[256];
149 
SceneImageSceneImage150 	SceneImage() : loaded(false), w(0), h(0), p(0) {
151 		memset(pal, 0, sizeof(pal));
152 	}
153 };
154 
155 
156 enum SceneTransitionType {
157 	kTransitionNoFade,
158 	kTransitionFade
159 };
160 
161 enum SceneLoadFlags {
162 	kLoadByResourceId,
163 	kLoadBySceneNumber
164 };
165 
166 struct LoadSceneParams {
167 	int32 sceneDescriptor;
168 	SceneLoadFlags loadFlag;
169 	SceneProc *sceneProc;
170 	bool sceneSkipTarget;
171 	SceneTransitionType transitionType;
172 	int actorsEntrance;
173 	int chapter;
174 };
175 
176 typedef Common::List<LoadSceneParams> SceneQueueList;
177 
178 ///// IHNM-specific stuff
179 #define IHNM_PALFADE_TIME    1000
180 #define IHNM_INTRO_FRAMETIME 80
181 #define IHNM_DGLOGO_TIME     8000
182 #define IHNM_TITLE_TIME_GM   28750
183 #define IHNM_TITLE_TIME_FM   19500
184 
185 #define CREDIT_DURATION1 4000
186 
187 class Scene {
188  public:
189 	Scene(SagaEngine *vm);
190 	~Scene();
191 
192 // Console functions
193 	void cmdActionMapInfo();
194 	void cmdObjectMapInfo();
195 
196 	void cmdSceneChange(int argc, const char **argv);
197 
198 	void startScene();
199 	void creditsScene();
200 	void nextScene();
201 	void skipScene();
202 	void endScene();
203 	void restoreScene();
queueScene(const LoadSceneParams & sceneQueue)204 	void queueScene(const LoadSceneParams &sceneQueue) {
205 		_sceneQueue.push_back(sceneQueue);
206 	}
207 
208 	void draw();
getFlags()209 	int getFlags() const { return _sceneDescription.flags; }
getScriptModuleNumber()210 	int getScriptModuleNumber() const { return _sceneDescription.scriptModuleNumber; }
isInIntro()211 	bool isInIntro() { return !_inGame; }
getSceneClip()212 	const Rect& getSceneClip() const { return _sceneClip; }
213 
214 	void getBGMaskInfo(int &width, int &height, byte *&buffer);
isBGMaskPresent()215 	int isBGMaskPresent() { return _bgMask.loaded; }
216 
getBGMaskType(const Point & testPoint)217 	int getBGMaskType(const Point &testPoint) {
218 		uint offset;
219 		if (!_bgMask.loaded) {
220 			return 0;
221 		}
222 		offset = testPoint.x + testPoint.y * _bgMask.w;
223 
224 		#ifdef SCENE_DEBUG
225 		if (offset >= _bgMask.buf_len) {
226 			error("Scene::getBGMaskType offset 0x%X exceed bufferLength 0x%X", offset, (int)_bgMask.buf_len);
227 		}
228 		#endif
229 
230 		return (_bgMask.buffer[offset] >> 4) & 0x0f;
231 	}
232 
validBGMaskPoint(const Point & testPoint)233 	bool validBGMaskPoint(const Point &testPoint) {
234 		#ifdef SCENE_DEBUG
235 		if (!_bgMask.loaded) {
236 			error("Scene::validBGMaskPoint _bgMask not loaded");
237 		}
238 		#endif
239 
240 		return !((testPoint.x < 0) || (testPoint.x >= _bgMask.w) ||
241 			(testPoint.y < 0) || (testPoint.y >= _bgMask.h));
242 	}
243 
244 	bool canWalk(const Point &testPoint);
245 	bool offscreenPath(Point &testPoint);
246 
setDoorState(int doorNumber,int doorState)247 	void setDoorState(int doorNumber, int doorState) {
248 		#ifdef SCENE_DEBUG
249 		if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX))
250 			error("Scene::setDoorState wrong doorNumber");
251 		#endif
252 
253 		_sceneDoors[doorNumber] = doorState;
254 	}
255 
getDoorState(int doorNumber)256 	int getDoorState(int doorNumber) {
257 		#ifdef SCENE_DEBUG
258 		if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX))
259 			error("Scene::getDoorState wrong doorNumber");
260 		#endif
261 
262 		return _sceneDoors[doorNumber];
263 	}
264 
265 	void initDoorsState();
266 
267 	void getBGInfo(BGInfo &bgInfo);
getBGPal(PalEntry * & pal)268 	void getBGPal(PalEntry *&pal) {
269 		pal = (PalEntry *)_bg.pal;
270 	}
271 
272 	void getSlopes(int &beginSlope, int &endSlope);
273 
clearSceneQueue()274 	void clearSceneQueue() {
275 		_sceneQueue.clear();
276 	}
277 	void changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionType transitionType, int chapter = NO_CHAPTER_CHANGE);
278 
isSceneLoaded()279 	bool isSceneLoaded() const { return _sceneLoaded; }
280 
getSceneResourceId(int sceneNumber)281 	uint16 getSceneResourceId(int sceneNumber) {
282 	#ifdef SCENE_DEBUG
283 		if ((sceneNumber < 0) || (sceneNumber >= _sceneCount)) {
284 			error("getSceneResourceId: wrong sceneNumber %i", sceneNumber);
285 		}
286 	#endif
287 		return _sceneLUT[sceneNumber];
288 	}
currentSceneNumber()289 	int currentSceneNumber() const { return _sceneNumber; }
currentChapterNumber()290 	int currentChapterNumber() const { return _chapterNumber; }
setChapterNumber(int ch)291 	void setChapterNumber(int ch) { _chapterNumber = ch; }
getOutsetSceneNumber()292 	int getOutsetSceneNumber() const { return _outsetSceneNumber; }
currentSceneResourceId()293 	int currentSceneResourceId() const { return _sceneResourceId; }
getCurrentMusicTrack()294 	int getCurrentMusicTrack() const { return _currentMusicTrack; }
setCurrentMusicTrack(int tr)295 	void setCurrentMusicTrack(int tr) { _currentMusicTrack = tr; }
getCurrentMusicRepeat()296 	int getCurrentMusicRepeat() const { return _currentMusicRepeat; }
setCurrentMusicRepeat(int rp)297 	void setCurrentMusicRepeat(int rp) { _currentMusicRepeat = rp; }
haveChapterPointsChanged()298 	bool haveChapterPointsChanged() const { return _chapterPointsChanged; }
setChapterPointsChanged(bool cp)299 	void setChapterPointsChanged(bool cp) { _chapterPointsChanged = cp; }
300 
cutawaySkip()301 	void cutawaySkip() {
302 		_vm->_framesEsc = _vm->_scene->isInIntro() ? 2 : 1;
303 	}
304 
305 	void drawTextList();
306 
307 	int getHeight(bool speech = false) const {
308 		if (_vm->getGameId() == GID_IHNM && _vm->_scene->currentChapterNumber() == 8 && !speech)
309 			return _vm->getDisplayInfo().height;
310 		else
311 			return _vm->getDisplayInfo().sceneHeight;
312 	}
313 
314 	void clearPlacard();
315 	void showPsychicProfile(const char *text);
316 	void clearPsychicProfile();
317 	void showIHNMDemoSpecialScreen();
318 
isNonInteractiveIHNMDemoPart()319 	bool isNonInteractiveIHNMDemoPart() {
320 		return _vm->isIHNMDemo() && (_sceneNumber >= 144 && _sceneNumber <= 149);
321 	}
322 
isITEPuzzleScene()323 	bool isITEPuzzleScene() {
324 		return _vm->getGameId() == GID_ITE && _vm->_puzzle->isActive();
325 	}
326 
327  private:
328 	void loadScene(LoadSceneParams &loadSceneParams);
329 	void loadSceneDescriptor(uint32 resourceId);
330 	void loadSceneResourceList(uint32 resourceId, SceneResourceDataArray &resourceList);
331 	void loadSceneEntryList(const ByteArray &resourceData);
332 	void processSceneResources(SceneResourceDataArray &resourceList);
333 	void getResourceTypes(SAGAResourceTypes *&types, int &typesCount);
334 
335 
336 	SagaEngine *_vm;
337 
338 	ResourceContext *_sceneContext;
339 	Common::Array<uint16> _sceneLUT;
340 	SceneQueueList _sceneQueue;
341 	bool _sceneLoaded;
342 	int _sceneNumber;
343 	int _chapterNumber;
344 	int _outsetSceneNumber;
345 	int _sceneResourceId;
346 	int _currentMusicTrack;
347 	int _currentMusicRepeat;
348 	bool _chapterPointsChanged;
349 	bool _inGame;
350 	SceneDescription _sceneDescription;
351 	SceneProc *_sceneProc;
352 	SceneImage _bg;
353 	SceneImage _bgMask;
354 	Common::Rect _sceneClip;
355 
356 	int _sceneDoors[SCENE_DOORS_MAX];
357 
358 
359  public:
360 	ObjectMap *_actionMap;
361 	ObjectMap *_objectMap;
362 	SceneEntryList _entryList;
363 	StringsTable _sceneStrings;
364 	TextList _textList;
365 
366  private:
367 	int ITEStartProc();
368 	int IHNMStartProc();
369 	int IHNMCreditsProc();
370 	int DinoStartProc();
371 	int FTA2StartProc();
372 	int FTA2EndProc(FTA2Endings whichEnding);
373 	void playMovie(const char *filename);
374 
375 	void IHNMLoadCutaways();
376 	bool checkKey();
377 
378 	bool playTitle(int title, int time, int mode = kPanelVideo);
379 	bool playLoopingTitle(int title, int seconds);
380 
381  public:
382 	static int SC_IHNMIntroMovieProc1(int param, void *refCon);
383 	static int SC_IHNMIntroMovieProc2(int param, void *refCon);
384 	static int SC_IHNMIntroMovieProc3(int param, void *refCon);
385 	static int SC_IHNMCreditsMovieProc(int param, void *refCon);
386 
387  private:
388 	int IHNMIntroMovieProc1(int param);
389 	int IHNMIntroMovieProc2(int param);
390 	int IHNMIntroMovieProc3(int param);
391 	int IHNMCreditsMovieProc(int param);
392 
393  public:
394 	static int SC_ITEIntroAnimProc(int param, void *refCon);
395 	static int SC_ITEIntroCave1Proc(int param, void *refCon);
396 	static int SC_ITEIntroCave2Proc(int param, void *refCon);
397 	static int SC_ITEIntroCave3Proc(int param, void *refCon);
398 	static int SC_ITEIntroCave4Proc(int param, void *refCon);
399 	static int SC_ITEIntroValleyProc(int param, void *refCon);
400 	static int SC_ITEIntroTreeHouseProc(int param, void *refCon);
401 	static int SC_ITEIntroFairePathProc(int param, void *refCon);
402 	static int SC_ITEIntroFaireTentProc(int param, void *refCon);
403 	static int SC_ITEIntroCaveDemoProc(int param, void *refCon);
404 
405  private:
406 	EventColumns *queueIntroDialogue(EventColumns *eventColumns, int n_dialogues, const IntroDialogue dialogue[]);
407 	EventColumns *queueCredits(int delta_time, int duration, int n_credits, const IntroCredit credits[]);
408 	int ITEIntroAnimProc(int param);
409 	int ITEIntroCaveCommonProc(int param, int caveScene);
410 	int ITEIntroCaveDemoProc(int param);
411 	int ITEIntroValleyProc(int param);
412 	int ITEIntroTreeHouseProc(int param);
413 	int ITEIntroFairePathProc(int param);
414 	int ITEIntroFaireTentProc(int param);
415 
416 };
417 
418 } // End of namespace Saga
419 
420 #endif
421