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 #ifndef ASYLUM_ASYLUM_H
24 #define ASYLUM_ASYLUM_H
25 
26 #include "common/random.h"
27 #include "common/rect.h"
28 #include "common/scummsys.h"
29 #include "common/serializer.h"
30 #include "common/system.h"
31 
32 #include "engines/advancedDetector.h"
33 #include "engines/engine.h"
34 
35 #include "asylum/resources/data.h"
36 
37 #include "asylum/console.h"
38 #include "asylum/eventhandler.h"
39 #include "asylum/shared.h"
40 
41 /**
42  * This is the namespace of the Asylum engine.
43  *
44  * Status of this engine:
45  *  - Script interpreters for main game and encounters are implemented
46  *  - Object handling, player reaction and special chapter logic is implemented
47  *  - Scene parsing and drawing, movie playing, mouse cursor and menu handling are almost complete
48  *  - Sound code is almost complete (music is still WIP)
49  *  - Almost all puzzles are implemented
50  *  - Walking is partialy implemented but the primitive pathfinding is missing
51  *
52  * Maintainers:
53  *  alexbevi, alexandrefontoura, bluegr, littleboy, midstream, deledrius
54  *
55  * Supported games:
56  *  - Sanitarium
57  */
58 
59 struct ADGameDescription;
60 
61 namespace Asylum {
62 
63 class Cursor;
64 class Encounter;
65 class Menu;
66 class Puzzles;
67 class ResourceManager;
68 class Savegame;
69 class Scene;
70 class Screen;
71 class ScriptManager;
72 class Special;
73 class Speech;
74 class Sound;
75 class Text;
76 class VideoPlayer;
77 
78 class AsylumEngine: public Engine, public Common::Serializable {
79 protected:
80 	// Engine APIs
81 	virtual Common::Error run();
82 	virtual bool hasFeature(EngineFeature f) const;
83 
84 public:
85 	enum StartGameType {
86 		kStartGamePlayIntro,
87 		kStartGameLoad,
88 		kStartGameScene
89 	};
90 
91 	AsylumEngine(OSystem *system, const ADGameDescription *gd);
92 	virtual ~AsylumEngine();
93 
94 	/**
95 	 * Start a new the game
96 	 */
97 	void startGame(ResourcePackId sceneId, StartGameType type);
98 
99 	/**
100 	 * Restarts the game
101 	 */
102 	void restart();
103 
104 	/**
105 	 * Run event loop
106 	 */
107 	void handleEvents();
108 
109 	/**
110 	 * Switch to a new scene
111 	 *
112 	 * @param sceneId ResourcePack for the scene
113 	 */
switchScene(ResourcePackId sceneId)114 	void switchScene(ResourcePackId sceneId) { startGame(sceneId, kStartGameScene); }
115 
116 	/**
117 	 * Get the number of engine ticks
118 	 *
119 	 * @return The tick.
120 	 */
getTick()121 	uint32 getTick() { return _system->getMillis() + _tickOffset; }
122 
123 	/**
124 	 * Sets the tick value
125 	 *
126 	 * @param offset The offset.
127 	 */
setTick(uint32 offset)128 	void setTick(uint32 offset) { _tickOffset = offset - _system->getMillis(); }
129 
130 	/**
131 	 * Resets the game
132 	 */
133 	void reset();
134 
135 	/**
136 	 * This is the global tick counter.
137 	 */
138 	uint32 screenUpdateCount;
139 	uint32 lastScreenUpdate;
140 
141 	// Game
cursor()142 	Cursor          *cursor()    { return _cursor; }
encounter()143 	Encounter       *encounter() { return _encounter; }
menu()144 	Menu            *menu()      { return _menu; }
resource()145 	ResourceManager *resource()  { return _resource; }
savegame()146 	Savegame        *savegame()  { return _savegame; }
scene()147 	Scene           *scene()     { return _scene; }
screen()148 	Screen          *screen()    { return _screen; }
script()149 	ScriptManager   *script()    { return _script; }
special()150 	Special         *special()   { return _special; }
speech()151 	Speech          *speech()    { return _speech; }
sound()152 	Sound           *sound()     { return _sound; }
text()153 	Text            *text()      { return _text; }
video()154 	VideoPlayer     *video()     { return _video; }
155 
data()156 	SharedData      *data()      { return &_data; }
puzzles()157 	Puzzles         *puzzles()   { return _puzzles; }
158 
159 	// Flags
160 	void setGameFlag(GameFlag flag);
161 	void clearGameFlag(GameFlag flag);
162 	void toggleGameFlag(GameFlag flag);
163 	bool isGameFlagSet(GameFlag flag) const;
164 	bool isGameFlagNotSet(GameFlag flag) const;
165 	bool areGameFlagsSet(uint from, uint to) const;
166 	void resetFlags();
167 
168 	// Misc
getRandom(uint max)169 	uint getRandom(uint max) { return max ? _rnd->getRandomNumber(max - 1) : 0; }
getRandomBit()170 	uint getRandomBit()      { return _rnd->getRandomBit(); }
171 
172 	bool rectContains(const int16 (*rectPtr)[4], const Common::Point &p) const;
173 
174 	// Steam achievements
175 	void unlockAchievement(const Common::String &id);
176 	void checkAchievements();
177 
178 	/**
179 	 * Switch message handler.
180 	 *
181 	 * @param handler If non-null, a pointer to an EventHandler class.
182 	 */
183 	void switchEventHandler(EventHandler *handler);
184 
185 	/**
186 	 * Notifies the current event handler of an event
187 	 *
188 	 * @param type The event type.
189 	 */
190 	void notify(AsylumEventType type, int32 param1 = 0, int32 param2 = 0);
191 
192 	/**
193 	 * Updates the reverse stereo scene status from the config
194 	 */
195 	void updateReverseStereo();
196 
197 	// Serializable
198 	void saveLoadWithSerializer(Common::Serializer &s);
199 
checkGameVersion(const char * version)200 	bool checkGameVersion(const char *version) { return !strcmp(_gameDescription->extra, version); }
201 
202 private:
203 	const ADGameDescription *_gameDescription;
204 
205 	// Misc
206 	Console              *_console;
207 	Common::RandomSource *_rnd;
208 
209 	// Game
210 	Cursor          *_cursor;
211 	Encounter       *_encounter;
212 	Menu            *_menu;
213 	ResourceManager *_resource;
214 	Savegame        *_savegame;
215 	Scene           *_scene;
216 	Screen          *_screen;
217 	ScriptManager   *_script;
218 	Special         *_special;
219 	Speech          *_speech;
220 	Sound           *_sound;
221 	Text            *_text;
222 	VideoPlayer     *_video;
223 
224 	// Current EventHandler class instance
225 	EventHandler *_handler;
226 
227 	// Game data
228 	Puzzles     *_puzzles;
229 	SharedData   _data;
230 	uint32       _gameFlags[130];
231 	bool         _introPlayed;
232 	int32        _tickOffset;
233 
234 	void updateMouseCursor();
235 	void processDelayedEvents();
236 
237 	/**
238 	 * Play the intro
239 	 */
240 	void playIntro();
241 
242 	// Debug
243 	friend class Console;
244 	Scene *_previousScene;
245 	ResourcePackId _delayedSceneIndex;
246 	int32 _delayedVideoIndex;
247 };
248 
249 } // namespace Asylum
250 
251 #endif // ASYLUM_ASYLUM_H
252