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 TWINE_TWINE_H
24 #define TWINE_TWINE_H
25 
26 #include "backends/keymapper/keymap.h"
27 #include "common/random.h"
28 #include "common/rect.h"
29 #include "engines/advancedDetector.h"
30 #include "engines/engine.h"
31 
32 #include "engines/metaengine.h"
33 #include "graphics/managed_surface.h"
34 #include "graphics/screen.h"
35 #include "graphics/pixelformat.h"
36 #include "graphics/surface.h"
37 #include "twine/detection.h"
38 #include "twine/input.h"
39 #include "twine/scene/actor.h"
40 
41 namespace TwinE {
42 
43 /** Definition for European version */
44 #define EUROPE_VERSION 0
45 /** Definition for American version */
46 #define USA_VERSION 1
47 /** Definition for Modification version */
48 #define MODIFICATION_VERSION 2
49 
50 /** Default frames per second */
51 #define DEFAULT_FRAMES_PER_SECOND 20
52 
53 #define ORIGINAL_WIDTH 640
54 #define ORIGINAL_HEIGHT 480
55 
56 static const struct TwinELanguage {
57 	const char *name;
58 	const char *id;
59 } LanguageTypes[] = {
60 	{"English", "EN_"},
61 	{"French", "FR_"},
62 	{"German", "DE_"},
63 	{"Spanish", "SP_"},
64 	{"Italian", "IT_"},
65 	{"Portuguese", ""}};
66 
67 enum MidiFileType {
68 	MIDIFILE_NONE,
69 	MIDIFILE_DOS,
70 	MIDIFILE_WIN
71 };
72 
73 /** Config movie types */
74 enum MovieType {
75 	CONF_MOVIE_NONE = 0,
76 	CONF_MOVIE_FLA = 1,
77 	CONF_MOVIE_FLAWIDE = 2,
78 	CONF_MOVIE_FLAGIF = 3
79 };
80 
81 /** Configuration file structure
82 	Used in the engine to load/use certain parts of code according with
83 	this settings. Check \a lba.cfg file for valid values for each settings.\n
84 	All the settings with (*) means they are new and only exist in this engine. */
85 struct ConfigFile {
86 	/** Index into the LanguageTypes array. */
87 	int32 LanguageId = 0;
88 	bool Voice = true;
89 	/** Enable/Disable game dialogues */
90 	bool FlagDisplayText = false;
91 	/** Flag to display game debug */
92 	bool Debug = false;
93 	/** Type of music file to be used */
94 	MidiFileType MidiType = MIDIFILE_NONE;
95 	/** Game version */
96 	int32 Version = EUROPE_VERSION;
97 	/** If you want to use the LBA CD or not */
98 	int32 UseCD = 0;
99 	/** Allow various sound types */
100 	int32 Sound = 0;
101 	/** Allow various movie types */
102 	int32 Movie = CONF_MOVIE_FLA;
103 	/** Flag used to keep the game frames per second */
104 	int32 Fps = 0;
105 
106 	// these settings are not available in the original version
107 	/** Flag to toggle Wall Collision */
108 	bool WallCollision = false;
109 	/** Use original autosaving system or save when you want */
110 	bool UseAutoSaving = false;
111 	bool Mouse = false;
112 
113 	// these settings can be changed in-game - and must be persisted
114 	/** Shadow mode type, value: all, character only, none */
115 	int32 ShadowMode = 0;
116 	int32 PolygonDetails = 2;
117 	/** Scenery Zoom */
118 	bool SceZoom = false;
119 };
120 
121 class Actor;
122 class Animations;
123 class Collision;
124 class Extra;
125 class GameState;
126 class Grid;
127 class Movements;
128 class Interface;
129 class Menu;
130 class Movies;
131 class MenuOptions;
132 class Music;
133 class Redraw;
134 class Renderer;
135 class Resources;
136 class Scene;
137 class Screens;
138 class ScriptLife;
139 class ScriptMove;
140 class Holomap;
141 class Sound;
142 class Text;
143 class DebugGrid;
144 struct Keyboard;
145 class Debug;
146 class DebugScene;
147 
148 enum class EngineState {
149 	Menu,
150 	GameLoop,
151 	LoadedGame,
152 	QuitGame
153 };
154 
155 struct ScopedEngineFreeze {
156 	TwinEEngine *_engine;
157 	ScopedEngineFreeze(TwinEEngine *engine);
158 	~ScopedEngineFreeze();
159 };
160 
161 struct ScopedCursor {
162 	TwinEEngine *_engine;
163 	ScopedCursor(TwinEEngine *engine);
164 	~ScopedCursor();
165 };
166 
167 class FrameMarker {
168 private:
169 	TwinEEngine *_engine;
170 	uint32 _fps;
171 	uint32 _start;
172 public:
173 	FrameMarker(TwinEEngine *engine, uint32 fps = DEFAULT_FRAMES_PER_SECOND);
174 	~FrameMarker();
175 };
176 
177 class TwineScreen : public Graphics::Screen {
178 private:
179 	using Super = Graphics::Screen;
180 	TwinEEngine *_engine;
181 
182 public:
183 	TwineScreen(TwinEEngine *engine);
184 
185 	void update() override;
186 };
187 
188 class TwinEEngine : public Engine {
189 private:
190 	int32 _isTimeFreezed = 0;
191 	int32 _saveFreezedTime = 0;
192 	int32 _mouseCursorState = 0;
193 	ActorMoveStruct _loopMovePtr; // mainLoopVar1
194 	PauseToken _pauseToken;
195 	TwineGameType _gameType;
196 	EngineState _state = EngineState::Menu;
197 	Common::String _queuedFlaMovie;
198 
199 	ScriptLife *_scriptLife;
200 	ScriptMove *_scriptMove;
201 
202 	Common::RandomSource _rnd;
203 	Common::Language _gameLang;
204 
205 	void processBookOfBu();
206 	void processBonusList();
207 	void processInventoryAction();
208 	void processOptionsMenu();
209 
210 	void initConfigurations();
211 	/** Initialize all needed stuffs at first time running engine */
212 	void initAll();
213 	void initEngine();
214 	void processActorSamplePosition(int32 actorIdx);
215 	/** Allocate video memory, both front and back buffers */
216 	void allocVideoMemory(int32 w, int32 h);
217 
218 	/**
219 	 * Game engine main loop
220 	 * @return true if we want to show credit sequence
221 	 */
222 	int32 runGameEngine();
223 public:
224 	TwinEEngine(OSystem *system, Common::Language language, uint32 flagsTwineGameType, TwineGameType gameType);
225 	~TwinEEngine() override;
226 
227 	Common::Error run() override;
228 	bool hasFeature(EngineFeature f) const override;
229 
canLoadGameStateCurrently()230 	bool canLoadGameStateCurrently() override { return true; }
231 	bool canSaveGameStateCurrently() override;
232 
233 	Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
234 	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
235 
236 	void wipeSaveSlot(int slot);
237 	SaveStateList getSaveSlots() const;
238 	void autoSave();
239 
240 	void pushMouseCursorVisible();
241 	void popMouseCursorVisible();
242 
isLBA1()243 	bool isLBA1() const { return _gameType == TwineGameType::GType_LBA; }
isLBA2()244 	bool isLBA2() const { return _gameType == TwineGameType::GType_LBA2; }
isMod()245 	bool isMod() const { return (_gameFlags & TwinE::TF_MOD) != 0; }
isDotEmuEnhanced()246 	bool isDotEmuEnhanced() const { return (_gameFlags & TwinE::TF_DOTEMU_ENHANCED) != 0; }
isDemo()247 	bool isDemo() const { return (_gameFlags & ADGF_DEMO) != 0; };
248 	const char *getGameId() const;
249 
250 	bool unlockAchievement(const Common::String &id);
251 
252 	Actor *_actor;
253 	Animations *_animations;
254 	Collision *_collision;
255 	Extra *_extra;
256 	GameState *_gameState;
257 	Grid *_grid;
258 	Movements *_movements;
259 	Interface *_interface;
260 	Menu *_menu;
261 	Movies *_flaMovies;
262 	MenuOptions *_menuOptions;
263 	Music *_music;
264 	Redraw *_redraw;
265 	Renderer *_renderer;
266 	Resources *_resources;
267 	Scene *_scene;
268 	Screens *_screens;
269 	Holomap *_holomap;
270 	Sound *_sound;
271 	Text *_text;
272 	DebugGrid *_debugGrid;
273 	Input *_input;
274 	Debug *_debug;
275 	DebugScene *_debugScene;
276 
277 	/** Configuration file structure
278 	 * Contains all the data used in the engine to configurated the game in particulary ways. */
279 	ConfigFile _cfgfile;
280 
281 	int32 _frameCounter = 0;
282 	int32 _quitGame = 0;
283 	int32 _lbaTime = 0;
284 
285 	int32 _loopInventoryItem = 0;
286 	int32 _loopActorStep = 0;
287 	uint32 _gameFlags;
288 
289 	/** Disable screen recenter */
290 	bool _disableScreenRecenter = false;
291 
292 	Graphics::ManagedSurface _imageBuffer;
293 	/** Work video buffer */
294 	Graphics::ManagedSurface _workVideoBuffer;
295 	/** Main game video buffer */
296 	TwineScreen _frontVideoBuffer;
297 
298 	int width() const;
299 	int height() const;
300 	Common::Rect rect() const;
301 	Common::Rect centerOnScreen(int32 w, int32 h) const;
302 	Common::Rect centerOnScreenX(int32 w, int32 y, int32 h) const;
303 
304 	void initSceneryView();
305 	void exitSceneryView();
306 
307 	void queueMovie(const char *filename);
308 
309 	/**
310 	 * @return A random value between [0-max)
311 	 */
312 	int getRandomNumber(uint max = 0x7FFF);
313 
314 	void blitWorkToFront(const Common::Rect &rect);
315 	void blitFrontToWork(const Common::Rect &rect);
316 	void restoreFrontBuffer();
317 	void saveFrontBuffer();
318 
319 	void freezeTime();
320 	void unfreezeTime();
321 
322 	/**
323 	 * Game engine main loop
324 	 * @return true if we want to show credit sequence
325 	 */
326 	bool gameEngineLoop();
327 
328 	/**
329 	 * Deplay certain seconds till proceed - Can also Skip this delay
330 	 * @param time time in milliseconds to delay
331 	 */
332 	bool delaySkip(uint32 time);
333 
334 	/**
335 	 * Set a new palette in the SDL screen buffer
336 	 * @param palette palette to set in RGBA
337 	 */
338 	void setPalette(const uint32 *palette);
339 	/**
340 	 * @brief Set the Palette object
341 	 *
342 	 * @param startColor the first palette entry to be updated
343 	 * @param numColors the number of palette entries to be updated
344 	 * @param palette palette to set in RGB
345 	 */
346 	void setPalette(uint startColor, uint numColors, const byte *palette);
347 
348 	/**
349 	 * Blit surface in the screen in a determinate area
350 	 * @param left left position to start copy
351 	 * @param top top position to start copy
352 	 * @param right right position to start copy
353 	 * @param bottom bottom position to start copy
354 	 */
355 	void copyBlockPhys(int32 left, int32 top, int32 right, int32 bottom);
356 	void copyBlockPhys(const Common::Rect &rect);
357 
358 	/** Handle keyboard pressed keys */
359 	void readKeys();
360 
361 	/**
362 	 * Display text in screen
363 	 * @param x X coordinate in screen
364 	 * @param y Y coordinate in screen
365 	 * @param text text to display
366 	 * @param center if the text should be centered accoding with the giving positions
367 	 */
368 	void drawText(int32 x, int32 y, const Common::String &text, bool center = false, bool bigFont = false, int width = 100);
369 };
370 
width()371 inline int TwinEEngine::width() const {
372 	return _frontVideoBuffer.w;
373 }
374 
height()375 inline int TwinEEngine::height() const {
376 	return _frontVideoBuffer.h;
377 }
378 
rect()379 inline Common::Rect TwinEEngine::rect() const {
380 	return Common::Rect(0, 0, _frontVideoBuffer.w - 1, _frontVideoBuffer.h - 1);
381 }
382 
383 } // namespace TwinE
384 
385 #endif
386