ScummVM API documentation
bladerunner.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef BLADERUNNER_BLADERUNNER_H
23 #define BLADERUNNER_BLADERUNNER_H
24 
25 #include "bladerunner/archive.h"
26 
27 #include "common/array.h"
28 #include "common/random.h"
29 #include "common/stream.h"
30 #include "common/keyboard.h"
31 #include "common/events.h"
32 
33 #include "engines/engine.h"
34 
35 #include "graphics/surface.h"
36 
37 #include "math/cosinetables.h"
38 #include "math/sinetables.h"
39 
40 //TODO: change this to debugflag
41 #define BLADERUNNER_DEBUG_CONSOLE 0
42 #define BLADERUNNER_ORIGINAL_SETTINGS 0
43 #define BLADERUNNER_ORIGINAL_BUGS 0
44 
45 namespace Common {
46 class Archive;
47 struct Event;
48 }
49 
50 namespace GUI {
51 class Debugger;
52 }
53 
54 struct ADGameDescription;
55 
56 namespace BladeRunner {
57 
58 enum DebugLevels {
59  kDebugScript = 1 << 0,
60  kDebugSound = 1 << 1,
61  kDebugAnimation = 1 << 2
62 };
63 
64 class Actor;
65 class ActorDialogueQueue;
66 class ScreenEffects;
67 class AIScripts;
68 class AmbientSounds;
69 class AudioCache;
70 class AudioMixer;
71 class AudioPlayer;
72 class AudioSpeech;
73 class Chapters;
74 class CrimesDatabase;
75 class Combat;
76 class Debugger;
77 class DialogueMenu;
78 class Elevator;
79 class EndCredits;
80 class ESPER;
81 class Framelimiter;
82 class Font;
83 class GameFlags;
84 class GameInfo;
85 class ItemPickup;
86 class Items;
87 class KIA;
88 class Lights;
89 class Mouse;
90 class Music;
91 class Obstacles;
92 class Overlays;
93 class PoliceMaze;
94 class Scene;
95 class SceneObjects;
96 class SceneScript;
97 class Scores;
98 class Settings;
99 class Shapes;
100 class SliceAnimations;
101 class SliceRenderer;
102 class Spinner;
103 class Subtitles;
104 class SuspectsDatabase;
105 class TextResource;
106 class Time;
107 class Vector3;
108 class View;
109 class VK;
110 class Waypoints;
111 class ZBuffer;
112 
113 class BladeRunnerEngine : public Engine {
114 public:
115  static const int kArchiveCount = 12; // +2 to original value (10) to accommodate for SUBTITLES.MIX and one extra resource file, to allow for capability of loading all VQAx.MIX and the MODE.MIX file (debug purposes)
116  static const int kActorCount = 100;
117  static const int kActorVoiceOver = kActorCount - 1;
118  static const int kMaxCustomConcurrentRepeatableEvents = 20;
119 
120  static const int16 kOriginalGameWidth = 640;
121  static const int16 kOriginalGameHeight = 480;
122  static const int16 kDemoGameWidth = 320;
123  static const int16 kDemoGameHeight = 200;
124 
125  // Incremental number to keep track of significant revisions of the ScummVM bladerunner engine
126  // that could potentially introduce incompatibilities with old save files or require special actions to restore compatibility
127  // This is stored in game global variable "kVariableGameVersion"
128  // Original (classic) save game files will have version number of 0
129  // Values:
130  // 1: alpha testing (from May 15, 2019 to July 17, 2019)
131  // 2: all time code uses uint32 (since July 17 2019),
132  static const int kBladeRunnerScummVMVersion = 2;
133 
134  static const char *kGameplayKeymapId;
135  static const char *kKiaKeymapId;
136  static const char *kCommonKeymapId;
137 
138  bool _gameIsRunning;
139  bool _windowIsActive;
140  int _playerLosesControlCounter;
141  int _extraCPos;
142  uint8 _extraCNotify;
143 
144  Common::String _languageCode;
145  Common::Language _language;
146  bool _russianCP1251;
147  bool _noMusicDriver; // If "Music Device" is set to "No Music" from Audio tab
148 
149  ActorDialogueQueue *_actorDialogueQueue;
150  ScreenEffects *_screenEffects;
151  AIScripts *_aiScripts;
152  AmbientSounds *_ambientSounds;
153  AudioCache *_audioCache;
154  AudioMixer *_audioMixer;
155  AudioPlayer *_audioPlayer;
156  AudioSpeech *_audioSpeech;
157  Chapters *_chapters;
158  CrimesDatabase *_crimesDatabase;
159  Combat *_combat;
160  DialogueMenu *_dialogueMenu;
161  Elevator *_elevator;
162  EndCredits *_endCredits;
163  ESPER *_esper;
164  GameFlags *_gameFlags;
165  GameInfo *_gameInfo;
166  ItemPickup *_itemPickup;
167  Items *_items;
168  KIA *_kia;
169  Lights *_lights;
170  Font *_mainFont;
171  Subtitles *_subtitles;
172  Mouse *_mouse;
173  Music *_music;
174  Obstacles *_obstacles;
175  Overlays *_overlays;
176  PoliceMaze *_policeMaze;
177  Scene *_scene;
178  SceneObjects *_sceneObjects;
179  SceneScript *_sceneScript;
180  Scores *_scores;
181  Settings *_settings;
182  SliceAnimations *_sliceAnimations;
183  SliceRenderer *_sliceRenderer;
184  Spinner *_spinner;
185  SuspectsDatabase *_suspectsDatabase;
186  Time *_time;
187  View *_view;
188  Framelimiter *_framelimiter;
189  VK *_vk;
190  Waypoints *_waypoints;
191  int *_gameVars;
192 
193  TextResource *_textActorNames;
194  TextResource *_textCrimes;
195  TextResource *_textClueTypes;
196  TextResource *_textKIA;
197  TextResource *_textSpinnerDestinations;
198  TextResource *_textVK;
199  TextResource *_textOptions;
200 
201  Shapes *_shapes;
202 
203  Actor *_actors[kActorCount];
204  Actor *_playerActor;
205 
206  Graphics::PixelFormat _screenPixelFormat;
207 
208  Graphics::Surface _surfaceFront;
209  Graphics::Surface _surfaceBack;
210  bool _surfaceFrontCreated;
211  bool _surfaceBackCreated;
212 
213  ZBuffer *_zbuffer;
214 
216  uint32 _newGameRandomSeed;
217 
218  Debugger *_debugger;
219 
220  Math::CosineTable *_cosTable1024;
221  Math::SineTable *_sinTable1024;
222 
223  bool _isWalkingInterruptible;
224  bool _interruptWalking;
225  bool _playerActorIdle;
226  bool _playerDead;
227  bool _actorIsSpeaking;
228  bool _actorSpeakStopIsRequested;
229  bool _gameOver;
230  bool _gameJustLaunched;
231  int _gameAutoSaveTextId;
232  bool _gameIsAutoSaving;
233  bool _gameIsLoading;
234  bool _sceneIsLoading;
235  bool _vqaIsPlaying;
236  bool _vqaStopIsRequested;
237  bool _subtitlesEnabled; // tracks the state of whether subtitles are enabled or disabled from ScummVM GUI option or KIA checkbox (the states are synched)
238  bool _showSubtitlesForTextCrawl;
239  bool _sitcomMode;
240  bool _shortyMode;
241  bool _noDelayMillisFramelimiter;
242  bool _framesPerSecondMax;
243  bool _disableStaminaDrain;
244  bool _spanishCreditsCorrection;
245  bool _cutContent;
246  bool _enhancedEdition;
247  bool _validBootParam;
248 
249  int _walkSoundId;
250  int _walkSoundVolume;
251  int _walkSoundPan;
252  int _runningActorId;
253 
254  uint32 _mouseClickTimeLast;
255  uint32 _mouseClickTimeDiff;
256 
257  int _walkingToExitId;
258  bool _isInsideScriptExit;
259  int _walkingToRegionId;
260  bool _isInsideScriptRegion;
261  int _walkingToObjectId;
262  bool _isInsideScriptObject;
263  int _walkingToItemId;
264  bool _isInsideScriptItem;
265  bool _walkingToEmpty;
266  int _walkingToEmptyX;
267  int _walkingToEmptyY;
268  bool _isInsideScriptEmpty;
269  int _walkingToActorId;
270  bool _isInsideScriptActor;
271 
272  int _actorUpdateCounter;
273  uint32 _actorUpdateTimeLast;
274 
275  uint32 _timeOfMainGameLoopTickPrevious;
276 
277  bool _isNonInteractiveDemo;
278 
279  // This addon is to emulate keeping a keyboard key pressed (continuous / repeated firing of the event)
280  // -- code is pretty much identical from our common\events.cpp (KeyboardRepeatEventSourceWrapper)
281  // for continuous events (keyDown)
282  enum {
283  kKeyRepeatInitialDelay = 400,
284  kKeyRepeatSustainDelay = 100
285  };
286 
287  Common::KeyState _currentKeyDown;
288  uint32 _keyRepeatTimeLast;
289  uint32 _keyRepeatTimeDelay;
290 
291  uint32 _customEventRepeatTimeLast;
292  uint32 _customEventRepeatTimeDelay;
294 
295  // We do allow keys mapped to the same event,
296  // so eg. a key (Enter) could cause 2 or more events to fire,
297  // However, we should probably restrict the active events
298  // (that can be repeated while holding the mapped keys down)
299  // to a maximum of kMaxCustomConcurrentRepeatableEvents
300  ActiveCustomEventsArray _activeCustomEvents;
301 
302  // NOTE We still need keyboard functionality for naming saved games and also for the KIA Easter eggs.
303  // In KIA keyboard events should be accounted where possible - however some keymaps are still needed
304  // which is why we have the three separate common, gameplay-only and kia-only keymaps.
305  // If a valid keyboard key character eg. ("A") for text input (or Easter egg input)
306  // is also mapped to a common or KIA only custom event, then the custom event will be effected and not the key input.
307  // NOTE We don't use a custom action for left click -- we just use the standard left click action event (kStandardActionLeftClick)
308  // NOTE Dialogue Skip does not work for dialogue replayed when clicking on KIA clues (this is the original's behavior too)
309  // NOTE Toggle KIA options does not work when McCoy is walking towards a character when the player clicks on McCoy
310  // (this is the original's behavior too).
311  // "Esc" (by default) or the mapped key to this action still works though.
312  // NOTE A drawback of using customized keymapper for the game is that we can no longer replicate the original's behavior
313  // whereby holding down <SPACEBAR> would cause McCoy to keep switching quickly between combat mode and normal mode.
314  // This is because the original, when holding down right mouse button, would just toggle McCoy's mode once.
315  // We keep the behavior for "right mouse button".
316  // The continuous fast toggle behavior when holding down <SPACEBAR> feels more like a bug anyway.
317  // NOTE In the original, the KP_PERIOD key with NUMLOCK on, would work as a normal '.' character
318  // in the KIA Save Game screen. With NUMLOCK off, it would work as a delete request for the selected entry.
319  // However, NUMLOCK is currently not working as a modifier key for keymaps,
320  // so maybe we can implement the original behavior more accurately,
321  // when that is fixed in the keymapper or hardware-input code.
322  // For now, KP_PERIOD will work (by default) as a delete request.
323  enum BladeRunnerEngineMappableAction {
324 // kMpActionLeftClick, // default <left click> (select, walk-to, run-to, look-at, talk-to, use, shoot (combat mode), KIA (click on McCoy))
325  kMpActionToggleCombat, // default <right click> or <Spacebar>
326  kMpActionCutsceneSkip, // default <Return> or <KP_Enter> or <Esc> or <Spacebar>
327  kMpActionDialogueSkip, // default <Return> or <KP_Enter>
328  kMpActionToggleKiaOptions, // default <Esc> opens/closes KIA, in Options tab
329  kMpActionOpenKiaDatabase, // default <Tab> - only opens KIA (if closed), in one of the database tabs (the last active one, or else the first)
330  kMpActionOpenKIATabHelp, // default <F1>
331  kMpActionOpenKIATabSaveGame, // default <F2>
332  kMpActionOpenKIATabLoadGame, // default <F3>
333  kMpActionOpenKIATabCrimeSceneDatabase, // default <F4>
334  kMpActionOpenKIATabSuspectDatabase, // default <F5>
335  kMpActionOpenKIATabClueDatabase, // default <F6>
336  kMpActionOpenKIATabQuitGame, // default <F10>
337  kMpActionScrollUp, // ScummVM addition (scroll list up)
338  kMpActionScrollDown, // ScummVM addition (scroll list down)
339  kMpConfirmDlg, // default <Return> or <KP_Enter>
340  kMpDeleteSelectedSvdGame, // default <Delete> or <KP_Period>
341  kMpActionToggleCluePrivacy // default <right click>
342  };
343 
344 private:
345  MIXArchive _archives[kArchiveCount];
346  Common::Archive *_archive;
347 
348 public:
349  BladeRunnerEngine(OSystem *syst, const ADGameDescription *desc);
350  ~BladeRunnerEngine() override;
351 
352  bool hasFeature(EngineFeature f) const override;
353  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
354  Common::Error loadGameState(int slot) override;
355  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
356  Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
369  int getAutosaveSlot() const override { return -1; }
370 
371  void pauseEngineIntern(bool pause) override;
372 
373  Common::Error run() override;
374 
375  bool checkFiles(Common::Array<Common::String> &missingFiles);
376 
377  bool startup(bool hasSavegames = false);
378  void initChapterAndScene();
379  void shutdown();
380 
381  bool loadSplash();
382 
383  Common::Point getMousePos() const;
384  bool isMouseButtonDown() const;
385 
386  void gameLoop();
387  void gameTick();
388 
389  void actorsUpdate();
390 
391  void walkingReset();
392 
393  void handleEvents();
394  void handleKeyUp(Common::Event &event);
395  void handleKeyDown(Common::Event &event);
396  void handleMouseAction(int x, int y, bool mainButton, bool buttonDown, int scrollDirection = 0);
397  void handleMouseClickExit(int exitId, int x, int y, bool buttonDown);
398  void handleMouseClickRegion(int regionId, int x, int y, bool buttonDown);
399  void handleMouseClickItem(int itemId, bool buttonDown);
400  void handleMouseClickActor(int actorId, bool mainButton, bool buttonDown, Vector3 &scenePosition, int x, int y);
401  void handleMouseClick3DObject(int objectId, bool buttonDown, bool isClickable, bool isTarget);
402  void handleMouseClickEmpty(int x, int y, Vector3 &scenePosition, bool buttonDown);
403 
404  bool isAllowedRepeatedKey(const Common::KeyState &currKeyState);
405 
406  void handleCustomEventStart(Common::Event &event);
407  void handleCustomEventStop(Common::Event &event);
408  bool isAllowedRepeatedCustomEvent(const Common::Event &currEvent);
409 
410  bool shouldDropRogueCustomEvent(const Common::Event &evt);
411  void cleanupPendingRepeatingEvents(const Common::String &keymapperId);
412 
413  void gameWaitForActive();
414  void loopActorSpeaking();
415  void loopQueuedDialogueStillPlaying();
416 
417  void outtakePlay(int id, bool no_localization, int container = -1);
418  void outtakePlay(const Common::String &basenameNoExt, bool no_localization, int container = -3);
419 
420  bool openArchive(const Common::String &name);
421  bool closeArchive(const Common::String &name);
422  bool isArchiveOpen(const Common::String &name) const;
423 
424  bool openArchiveEnhancedEdition();
425 
426  void syncSoundSettings() override;
427  bool isSubtitlesEnabled();
428  void setSubtitlesEnabled(bool newVal);
429 
430  Common::SeekableReadStream *getResourceStream(const Common::String &name);
431 
432  bool playerHasControl();
433  void playerLosesControl();
434  void playerGainsControl(bool force = false);
435  void playerDied();
436 
437  bool saveGame(Common::WriteStream &stream, Graphics::Surface *thumb = NULL, bool origformat = false);
438  bool loadGame(Common::SeekableReadStream &stream, int version);
439  void newGame(int difficulty);
440  void autoSaveGame(int textId, bool endgame);
441 
442  void ISez(const Common::String &str);
443 
444  void blitToScreen(const Graphics::Surface &src) const;
445  Graphics::Surface generateThumbnail() const;
446 
447  Common::String getTargetName() const;
448 
449  uint8 getExtraCNotify();
450  void setExtraCNotify(uint8 val);
451 };
452 
453 static inline const Graphics::PixelFormat gameDataPixelFormat() {
454  return Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15);
455 }
456 
457 static inline void getGameDataColor(uint16 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) {
458  // gameDataPixelFormat().colorToARGB(vqaColor, a, r, g, b);
459  // using pixel format functions is too slow on some ports because of runtime checks
460  uint8 r5 = (color >> 10) & 0x1F;
461  uint8 g5 = (color >> 5) & 0x1F;
462  uint8 b5 = (color ) & 0x1F;
463  a = color >> 15;
464  r = (r5 << 3) | (r5 >> 2);
465  g = (g5 << 3) | (g5 >> 2);
466  b = (b5 << 3) | (b5 >> 2);
467 }
468 
469 static inline const Graphics::PixelFormat screenPixelFormat() {
470  return ((BladeRunnerEngine*)g_engine)->_screenPixelFormat;
471 }
472 
473 static inline void drawPixel(Graphics::Surface &surface, void* dst, uint32 value) {
474  switch (surface.format.bytesPerPixel) {
475  case 1:
476  *(uint8*)dst = (uint8)value;
477  break;
478  case 2:
479  *(uint16*)dst = (uint16)value;
480  break;
481  case 4:
482  *(uint32*)dst = (uint32)value;
483  break;
484  default:
485  break;
486  }
487 }
488 
489 static inline void getPixel(Graphics::Surface &surface, void* dst, uint32 &value) {
490  switch (surface.format.bytesPerPixel) {
491  case 1:
492  value = (uint8)(*(uint8*)dst);
493  break;
494  case 2:
495  value = (uint16)(*(uint16*)dst);
496  break;
497  case 4:
498  value = (uint32)(*(uint32*)dst);
499  break;
500  default:
501  break;
502  }
503 }
504 
505 void blit(const Graphics::Surface &src, Graphics::Surface &dst);
506 
507 } // End of namespace BladeRunner
508 
509 #endif
Definition: esper.h:64
Definition: crimes_database.h:34
Definition: police_maze.h:80
Definition: spinner.h:37
Definition: view.h:33
Definition: str.h:59
Definition: items.h:35
Definition: surface.h:67
EngineFeature
Definition: engine.h:253
Definition: obstacles.h:34
Definition: time.h:31
Definition: combat.h:36
Definition: stream.h:77
Definition: waypoints.h:35
Definition: error.h:84
Definition: vk.h:38
Definition: subtitles.h:40
Definition: pixelformat.h:138
Definition: advancedDetector.h:163
Definition: actor.h:31
Definition: random.h:44
Definition: suspects_database.h:101
Definition: ambient_sounds.h:38
Definition: end_credits.h:29
Definition: chapters.h:29
Definition: zbuffer.h:49
Definition: game_info.h:32
Definition: audio_player.h:45
Definition: ai_script.h:533
Definition: stream.h:745
Definition: system.h:46
Definition: framelimiter.h:31
Engine * g_engine
Definition: audio_speech.h:34
Definition: archive.h:141
Definition: scene_objects.h:43
Definition: actor.h:43
Definition: game_flags.h:32
Definition: scores.h:43
Definition: kia.h:68
Definition: ustr.h:57
Definition: audio_mixer.h:43
Definition: mouse.h:35
Definition: events.h:199
Definition: algorithm.h:29
int getAutosaveSlot() const override
Definition: bladerunner.h:369
Definition: rect.h:45
Definition: overlays.h:39
Definition: music.h:37
Definition: scene_script.h:526
Definition: lights.h:33
Definition: elevator.h:34
Definition: scene.h:39
Definition: debugger.h:56
Definition: vector.h:47
Definition: actor_dialogue_queue.h:33
Definition: text_resource.h:32
Definition: keyboard.h:294
Definition: audio_cache.h:33
PixelFormat format
Definition: surface.h:95
Definition: slice_renderer.h:45
Definition: bladerunner.h:113
Definition: system.h:161
Definition: settings.h:31
Definition: item_pickup.h:31
Definition: shape.h:61
Definition: engine.h:144
byte bytesPerPixel
Definition: pixelformat.h:139
Definition: screen_effects.h:39
Definition: font.h:38
Definition: slice_animations.h:39
Definition: dialogue_menu.h:39
Language
Definition: language.h:45
Definition: archive.h:31