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