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 GLK_GLK_H
24 #define GLK_GLK_H
25 
26 #include "common/scummsys.h"
27 #include "common/random.h"
28 #include "common/system.h"
29 #include "common/serializer.h"
30 #include "engines/engine.h"
31 #include "glk/glk_types.h"
32 #include "glk/streams.h"
33 #include "glk/pc_speaker.h"
34 #include "glk/quetzal.h"
35 #include "glk/game_description.h"
36 
37 namespace Glk {
38 
39 class Clipboard;
40 class Blorb;
41 class Conf;
42 class Events;
43 class Pictures;
44 class Screen;
45 class Selection;
46 class Sounds;
47 class Streams;
48 class Windows;
49 
50 enum GlkDebugChannels {
51 	kDebugCore      = 1 << 0,
52 	kDebugScripts   = 1 << 1,
53 	kDebugGraphics  = 1 << 2,
54 	kDebugSound     = 1 << 3,
55 	kDebugSpeech    = 1 << 4
56 };
57 
58 
59 #define GLK_SAVEGAME_VERSION 1
60 
61 /**
62  * Base class for the different interpreters
63  */
64 class GlkEngine : public Engine {
65 private:
66 	/**
67 	 * Handles basic initialization
68 	 */
69 	void initialize();
70 protected:
71 	const GlkGameDescription _gameDescription;
72 	Common::RandomSource _random;
73 	int _loadSaveSlot;
74 	Common::File _gameFile;
75 	PCSpeaker *_pcSpeaker;
76 	bool _quitFlag;
77 
78 	// Engine APIs
79 	Common::Error run() override;
80 
81 	/**
82 	  * Returns true whether a given feature is supported by the engine
83 	  */
84 	bool hasFeature(EngineFeature f) const override;
85 
86 	/**
87 	 * Setup the video mode
88 	 */
89 	virtual void initGraphicsMode();
90 
91 	/**
92 	 * Create the debugger
93 	 */
94 	virtual void createDebugger();
95 
96 	/**
97 	 * Create the screen
98 	 */
99 	virtual Screen *createScreen();
100 
101 	/**
102 	 * Loads the configuration
103 	 */
104 	virtual void createConfiguration();
105 
106 	/**
107 	 * Main game loop for the individual interpreters
108 	 */
109 	virtual void runGame() = 0;
110 
111 	/**
112 	 * Switches Glk from the default black on white color scheme
113 	 * to white on black
114 	 */
115 	void switchToWhiteOnBlack();
116 public:
117 	Blorb *_blorb;
118 	Clipboard *_clipboard;
119 	Conf *_conf;
120 	Events *_events;
121 	Pictures *_pictures;
122 	Screen *_screen;
123 	Selection *_selection;
124 	Streams *_streams;
125 	Sounds *_sounds;
126 	Windows *_windows;
127 	bool _copySelect;
128 	bool _terminated;
129 
130 	gidispatch_rock_t(*gli_register_obj)(void *obj, uint objclass);
131 	void(*gli_unregister_obj)(void *obj, uint objclass, gidispatch_rock_t objrock);
132 	gidispatch_rock_t(*gli_register_arr)(void *array, uint len, const char *typecode);
133 	void(*gli_unregister_arr)(void *array, uint len, const char *typecode, gidispatch_rock_t objrock);
134 public:
135 	GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc);
136 	~GlkEngine() override;
137 
138 	/**
139 	 * Returns true if a savegame can be loaded
140 	 */
141 	bool canLoadGameStateCurrently() override;
142 
143 	/**
144 	 * Returns true if the game can be saved
145 	 */
146 	bool canSaveGameStateCurrently() override;
147 
148 	/**
149 	 * Returns the language
150 	 */
getLanguage()151 	Common::Language getLanguage() const { return _gameDescription._language; };
152 
153 	/**
154 	 * Returns the running interpreter type
155 	 */
156 	virtual InterpreterType getInterpreterType() const = 0;
157 
158 	/**
159 	 * Returns the game's Id
160 	 */
getGameID()161 	const Common::String &getGameID() const { return _gameDescription._gameId; }
162 
163 	/**
164 	 * Returns the game's md5
165 	 */
getGameMD5()166 	const Common::String &getGameMD5() const { return _gameDescription._md5; }
167 
168 	/**
169 	 * Returns the primary filename for the game
170 	 */
getFilename()171 	const Common::String &getFilename() const { return _gameDescription._filename; }
172 
173 	/**
174 	 * Returns any options returned with the game's detection entry
175 	 */
getOptions()176 	uint getOptions() const { return _gameDescription._options; }
177 
178 	/**
179 	 * Return the game engine's target name
180 	 */
getTargetName()181 	const Common::String &getTargetName() const {
182 		return _targetName;
183 	}
184 
185 	/**
186 	 * Return the filename for a given save slot
187 	 */
getSaveName(uint slot)188 	Common::String getSaveName(uint slot) const {
189 		return Common::String::format("%s.%.3u", getTargetName().c_str(), slot);
190 	}
191 
192 	/**
193 	 * Prompt the user for a savegame to load, and then load it
194 	 */
195 	Common::Error loadGame();
196 
197 	/**
198 	 * Prompt the user to save their game, and then save it
199 	 */
200 	Common::Error saveGame();
201 
202 	/**
203 	 * Load a savegame from a given slot
204 	 */
205 	Common::Error loadGameState(int slot) override;
206 
207 	/**
208 	 * Save the game to a given slot
209 	 */
210 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
211 
212 	/**
213 	 * Loads Quetzal chunks from the passed savegame
214 	 */
215 	virtual Common::Error loadGameChunks(QuetzalReader &quetzal);
216 
217 	/**
218 	 * Writes out the Quetzal chunks within a savegame
219 	 */
220 	virtual Common::Error saveGameChunks(QuetzalWriter &quetzal);
221 
222 	/**
223 	 * Load a savegame from the passed Quetzal file chunk stream
224 	 */
225 	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) = 0;
226 
227 	/**
228 	 * Save the game. The passed write stream represents access to the UMem chunk
229 	 * in the Quetzal save file that will be created
230 	 */
231 	virtual Common::Error writeGameData(Common::WriteStream *ws) = 0;
232 
233 	/**
234 	 * Updates sound settings
235 	 */
236 	void syncSoundSettings() override;
237 
238 	/**
239 	 * Generate a beep
240 	 */
241 	void beep();
242 
243 	/**
244 	 * Get a random number
245 	 */
getRandomNumber(uint max)246 	uint getRandomNumber(uint max) { return _random.getRandomNumber(max); }
247 
248 	/**
249 	 * Set a random number seed
250 	 */
setRandomNumberSeed(uint seed)251 	void setRandomNumberSeed(uint seed) { _random.setSeed(seed); }
252 
253 	/**
254 	 * Flags to quit the game
255 	 */
quitGame()256 	void quitGame() {
257 		_quitFlag = true;
258 		Engine::quitGame();
259 	}
260 
261 	/**
262 	 * Returns true if the game should be quit
263 	 */
shouldQuit()264 	bool shouldQuit() const {
265 		return _quitFlag || Engine::shouldQuit();
266 	}
267 };
268 
269 extern GlkEngine *g_vm;
270 
271 } // End of namespace Glk
272 
273 #endif
274