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 #ifndef DRAGONS_DRAGONS_H
23 #define DRAGONS_DRAGONS_H
24 
25 #include "gui/EventRecorder.h"
26 #include "engines/engine.h"
27 #include "dragons/specialopcodes.h"
28 #include "dragons/detection.h"
29 
30 namespace Dragons {
31 
32 struct SaveHeader {
33 	Common::String description;
34 	uint32 version;
35 	uint32 flags;
36 	uint32 saveDate;
37 	uint32 saveTime;
38 	uint32 playTime;
39 	Graphics::Surface *thumbnail;
40 };
41 
42 enum kReadSaveHeaderError {
43 	kRSHENoError = 0,
44 	kRSHEInvalidType = 1,
45 	kRSHEInvalidVersion = 2,
46 	kRSHEIoError = 3
47 };
48 
49 enum Flags {
50 	ENGINE_FLAG_1 = 1,
51 	ENGINE_FLAG_2 = 2,
52 	ENGINE_FLAG_4 = 4,
53 	ENGINE_FLAG_8 = 8,
54 	ENGINE_FLAG_10 = 0x10,
55 	ENGINE_FLAG_20 = 0x20,
56 	ENGINE_FLAG_40 = 0x40,
57 	ENGINE_FLAG_80 = 0x80, // Inventory bag visible
58 	ENGINE_FLAG_100 = 0x100,
59 	ENGINE_FLAG_200 = 0x200,
60 	ENGINE_FLAG_400 = 0x400,
61 	ENGINE_FLAG_800 = 0x800,
62 	ENGINE_FLAG_1000_SUBTITLES_DISABLED = 0x1000,
63 	ENGINE_FLAG_8000     =     0x8000, // speech dialog is playing.
64 
65 	ENGINE_FLAG_10000    =    0x10000,
66 	ENGINE_FLAG_20000    =    0x20000,
67 	ENGINE_FLAG_80000    =    0x80000,
68 	ENGINE_FLAG_100000   =   0x100000,
69 	ENGINE_FLAG_200000   =   0x200000,
70 	ENGINE_FLAG_400000   =   0x400000,
71 	ENGINE_FLAG_2000000  =  0x2000000,
72 	ENGINE_FLAG_4000000  =  0x4000000,
73 	ENGINE_FLAG_8000000  =  0x8000000,
74 	ENGINE_FLAG_20000000 = 0x20000000,
75 	ENGINE_FLAG_80000000 = 0x80000000   //Flicker idle animation running.
76 };
77 
78 enum UnkFlags {
79 	ENGINE_UNK1_FLAG_1 = 1,
80 	ENGINE_UNK1_FLAG_2 = 2,
81 	ENGINE_UNK1_FLAG_4 = 4,
82 	ENGINE_UNK1_FLAG_8 = 8,
83 	ENGINE_UNK1_FLAG_10 = 0x10,
84 	ENGINE_UNK1_FLAG_20 = 0x20,
85 	ENGINE_UNK1_FLAG_40 = 0x40,
86 	ENGINE_UNK1_FLAG_80 = 0x80
87 };
88 
89 enum MouseWheel {
90 	MOUSE_WHEEL_NO_EVENT,
91 	MOUSE_WHEEL_DOWN,
92 	MOUSE_WHEEL_UP
93 };
94 
95 struct PaletteCyclingInstruction {
96 	int16 paletteType;
97 	int16 startOffset;
98 	int16 endOffset;
99 	int16 updateInterval;
100 	int16 updateCounter;
101 };
102 
103 enum DragonsAction {
104 	kDragonsActionNone,
105 	kDragonsActionUp,
106 	kDragonsActionDown,
107 	kDragonsActionLeft,
108 	kDragonsActionRight,
109 	kDragonsActionSquare,
110 	kDragonsActionTriangle,
111 	kDragonsActionCircle,
112 	kDragonsActionCross,
113 	kDragonsActionL1,
114 	kDragonsActionR1,
115 	kDragonsActionSelect,
116 	kDragonsActionChangeCommand,
117 	kDragonsActionInventory,
118 	kDragonsActionEnter,
119 	kDragonsActionMenu,
120 	kDragonsActionPause,
121 	kDragonsActionDebug,
122 	kDragonsActionDebugGfx,
123 	kDragonsActionQuit
124 };
125 
126 class BigfileArchive;
127 class BackgroundResourceLoader;
128 class Cursor;
129 class Credits;
130 class DragonFLG;
131 class DragonImg;
132 class DragonOBD;
133 class DragonRMS;
134 class DragonVAR;
135 class DragonINIResource;
136 class FontManager;
137 class Inventory;
138 class Scene;
139 class Screen;
140 class ActorManager;
141 class Actor;
142 class SequenceOpcodes;
143 class ScriptOpcodes;
144 class Talk;
145 class SoundManager;
146 class StrPlayer;
147 struct DragonINI;
148 
149 struct LoadingScreenState {
150 	Actor *flames[10];
151 	uint16 quads[10];
152 	int16 baseYOffset;
153 	int16 flameOffsetIdx;
154 	int16 loadingFlamesUpdateCounter;
155 	int16 loadingFlamesRiseCounter;
156 
LoadingScreenStateLoadingScreenState157 	LoadingScreenState() {
158 		baseYOffset = 0;
159 		flameOffsetIdx = 0;
160 		loadingFlamesUpdateCounter = 0;
161 		loadingFlamesRiseCounter = 0;
162 
163 		memset(flames, 0, ARRAYSIZE(flames)*sizeof(flames[0]));
164 		memset(quads, 0, ARRAYSIZE(quads)*sizeof(quads[0]));
165 	}
166 };
167 
168 class DragonsEngine : public Engine {
169 public:
170 	DragonOBD *_dragonOBD;
171 	DragonImg *_dragonImg;
172 	DragonRMS *_dragonRMS;
173 	ActorManager *_actorManager;
174 	DragonINIResource *_dragonINIResource;
175 	FontManager *_fontManager;
176 	ScriptOpcodes *_scriptOpcodes;
177 	Scene *_scene;
178 	uint16 _flickerInitialSceneDirection;
179 	Inventory *_inventory;
180 	Cursor *_cursor;
181 	Credits *_credits;
182 	Talk *_talk;
183 	SoundManager *_sound;
184 	StrPlayer *_strPlayer;
185 
186 	PaletteCyclingInstruction _paletteCyclingTbl[8];
187 
188 	bool _isLoadingDialogAudio;
189 	uint16 _videoFlags; // TODO move to screen?
190 
191 	void loadCurrentSceneMsf();
192 
193 	Screen *_screen;
194 	uint16 _sceneId1; //TODO wire this up. I think it might be where to restore save game from?
195 
196 private:
197 	Common::Language _language;
198 	BigfileArchive *_bigfileArchive;
199 	DragonFLG *_dragonFLG;
200 	DragonVAR *_dragonVAR;
201 	BackgroundResourceLoader *_backgroundResourceLoader;
202 	SequenceOpcodes *_sequenceOpcodes;
203 	uint32 _nextUpdatetime;
204 	uint32 _flags;
205 	uint32 _unkFlags1;
206 	Common::Point _cursorPosition;
207 	uint32 _flickerIdleCounter;
208 	uint32 _bit_flags_8006fbd8;
209 	//unk
210 
211 	uint16 _run_func_ptr_unk_countdown_timer;
212 
213 	uint32 _randomState;
214 
215 	LoadingScreenState *_loadingScreenState;
216 
217 	// input
218 	bool _leftMouseButtonUp;
219 	bool _leftMouseButtonDown;
220 	bool _rightMouseButtonUp;
221 	bool _iKeyUp;
222 	bool _downKeyDown;
223 	bool _downKeyUp;
224 	bool _upKeyDown;
225 	bool _upKeyUp;
226 	bool _enterKeyUp;
227 
228 	bool _leftKeyDown;
229 	bool _leftKeyUp;
230 	bool _rightKeyDown;
231 	bool _rightKeyUp;
232 	bool _wKeyDown;
233 	bool _aKeyDown;
234 	bool _sKeyDown;
235 	bool _dKeyDown;
236 	bool _oKeyDown;
237 	bool _pKeyDown;
238 	MouseWheel _mouseWheel;
239 
240 	bool _debugMode;
241 	bool _isGamePaused;
242 	bool _inMenu;
243 
244 	void (*_sceneUpdateFunction)();
245 	void (*_vsyncUpdateFunction)();
246 protected:
247 	virtual bool hasFeature(EngineFeature f) const override;
248 public:
249 	DragonsEngine(OSystem *syst, const ADGameDescription *desc);
250 	~DragonsEngine();
251 
252 	void updateEvents();
253 	Common::Error run() override;
254 
255 	Common::String getSavegameFilename(int num);
256 	static Common::String getSavegameFilename(const Common::String &target, int num);
257 	static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
258 
259 	Common::Error loadGameState(int slot) override;
260 	bool canLoadGameStateCurrently() override;
261 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave) override;
262 	bool canSaveGameStateCurrently() override;
263 	void syncSoundSettings() override;
264 
265 	void updateActorSequences();
266 	void setFlags(uint32 flags);
267 	void clearFlags(uint32 flags);
268 	uint32 getMultipleFlags(uint32 flags);
269 	uint32 getAllFlags();
270 	void setAllFlags(uint32 flags);
271 	bool isFlagSet(uint32 flag);
272 	bool isUnkFlagSet(uint32 flag);
273 
274 	void setUnkFlags(uint32 flags);
275 	void clearUnkFlags(uint32 flags);
276 
277 	byte *getBackgroundPalette();
278 	DragonINI *getINI(uint32 index);
279 	uint16 getVar(uint16 offset);
280 	void setVar(uint16 offset, uint16 value);
281 	uint16 getCurrentSceneId() const;
282 
283 	void waitForFrames(uint16 numFrames);
284 	void waitForFramesAllowSkip(uint16 numFrames);
285 
286 
287 	void playOrStopSound(uint16 soundId);
288 
289 	void fadeFromBlack();
290 	void fadeFromBlackExcludingFont();
291 	void fadeFromBlack(uint32 flags);
292 
293 	void fadeToBlack();
294 	void fadeToBlackExcludingFont();
295 	void fadeToBlack(uint32 flags);
296 
297 	uint16 ipt_img_file_related();
298 	void performAction();
299 
300 	void reset_screen_maybe();
301 
302 	void init();
303 	void loadScene(uint16 sceneId);
304 
305 	void reset();
306 
307 	void runSceneUpdaterFunction();
308 	void setSceneUpdateFunction(void (*newUpdateFunction)());
309 	void clearSceneUpdateFunction();
310 	void (*getSceneUpdateFunction())();
311 
312 	void setVsyncUpdateFunction(void (*newUpdateFunction)());
313 	bool isVsyncUpdaterFunctionRunning();
314 	void runVsyncUpdaterFunction();
315 
316 	bool isActionButtonPressed();
317 	bool isLeftKeyPressed();
318 	bool isRightKeyPressed();
319 	bool isUpKeyPressed();
320 	bool isDownKeyPressed();
321 	bool isSquareButtonPressed();
322 	bool isTriangleButtonPressed();
323 	bool isCircleButtonPressed();
324 	bool isCrossButtonPressed();
325 	bool isL1ButtonPressed();
326 	bool isR1ButtonPressed();
327 	bool checkForActionButtonRelease();
328 	bool checkForDownKeyRelease();
329 	bool checkForUpKeyRelease();
330 	bool checkForWheelUp();
331 	bool checkForWheelDown();
332 
333 	bool isDebugMode();
334 
335 	uint16 getRand(uint16 max);
336 
337 	void setupPalette1();
338 
339 	bool isInMenu();
340 
341 	void loadingScreenUpdate();
342 
343 	void clearAllText();
344 
345 	//TODO this logic should probably go in its own class.
346 	uint16 getBigFileTotalRecords();
347 	uint32 getBigFileInfoTblFromDragonEXE();
348 	uint32 getFontOffsetFromDragonEXE();
349 	uint32 getSpeechTblOffsetFromDragonEXE();
350 	uint32 getCutscenePaletteOffsetFromDragonEXE();
351 	uint32 defaultResponseOffsetFromDragonEXE();
352 	uint16 getCursorHandPointerSequenceID();
353 	uint32 getMiniGame3StartingDialog();
354 	uint32 getMiniGame3PickAHatDialog();
355 	uint32 getMiniGame3DataOffset();
356 	uint32 getDialogTextId(uint32 textId);
357 private:
358 	bool savegame(const char *filename, const char *description);
359 	bool loadgame(const char *filename);
360 	void gameLoop();
361 	void updateHandler();
362 	void updatePathfindingActors();
363 	void updatePaletteCycling();
364 	void updateFlickerIdleAnimation();
365 	void updateCamera();
366 
367 	uint32 calulateTimeLeft();
368 	void wait();
369 	uint16 getIniFromImg();
370 	void runINIScripts();
371 	void engineFlag0x20UpdateFunction();
372 
373 
374 	bool isInputEnabled();
375 	bool checkForInventoryButtonRelease();
376 
377 	void walkFlickerToObject();
378 
379 	void seedRandom(int32 seed);
380 	uint32 shuffleRandState();
381 
382 	void initializeSound();
383 
384 	void SomeInitSound_fun_8003f64c();
385 
386 	void initSubtitleFlag();
387 
388 	void loadingScreen();
389 
390 	void mainMenu();
391 
392 	bool checkAudioVideoFiles();
393 	bool validateAVFile(const char *filename);
394 
395 	uint32 getDialogTextIdGrb(uint32 textId);
396 	uint32 getDialogTextIdDe(uint32 textId);
397 	uint32 getDialogTextIdFr(uint32 textId);
398 };
399 
400 DragonsEngine *getEngine();
401 
402 } // End of namespace Dragons
403 
404 #endif //DRAGONS_DRAGONS_H
405