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 
217  Debugger *_debugger;
218 
219  Math::CosineTable *_cosTable1024;
220  Math::SineTable *_sinTable1024;
221 
222  bool _isWalkingInterruptible;
223  bool _interruptWalking;
224  bool _playerActorIdle;
225  bool _playerDead;
226  bool _actorIsSpeaking;
227  bool _actorSpeakStopIsRequested;
228  bool _gameOver;
229  bool _gameJustLaunched;
230  int _gameAutoSaveTextId;
231  bool _gameIsAutoSaving;
232  bool _gameIsLoading;
233  bool _sceneIsLoading;
234  bool _vqaIsPlaying;
235  bool _vqaStopIsRequested;
236  bool _subtitlesEnabled; // tracks the state of whether subtitles are enabled or disabled from ScummVM GUI option or KIA checkbox (the states are synched)
237  bool _showSubtitlesForTextCrawl;
238  bool _sitcomMode;
239  bool _shortyMode;
240  bool _noDelayMillisFramelimiter;
241  bool _framesPerSecondMax;
242  bool _disableStaminaDrain;
243  bool _spanishCreditsCorrection;
244  bool _cutContent;
245  bool _enhancedEdition;
246  bool _validBootParam;
247 
248  int _walkSoundId;
249  int _walkSoundVolume;
250  int _walkSoundPan;
251  int _runningActorId;
252 
253  uint32 _mouseClickTimeLast;
254  uint32 _mouseClickTimeDiff;
255 
256  int _walkingToExitId;
257  bool _isInsideScriptExit;
258  int _walkingToRegionId;
259  bool _isInsideScriptRegion;
260  int _walkingToObjectId;
261  bool _isInsideScriptObject;
262  int _walkingToItemId;
263  bool _isInsideScriptItem;
264  bool _walkingToEmpty;
265  int _walkingToEmptyX;
266  int _walkingToEmptyY;
267  bool _isInsideScriptEmpty;
268  int _walkingToActorId;
269  bool _isInsideScriptActor;
270 
271  int _actorUpdateCounter;
272  uint32 _actorUpdateTimeLast;
273 
274  uint32 _timeOfMainGameLoopTickPrevious;
275 
276  bool _isNonInteractiveDemo;
277 
278  // This addon is to emulate keeping a keyboard key pressed (continuous / repeated firing of the event)
279  // -- code is pretty much identical from our common\events.cpp (KeyboardRepeatEventSourceWrapper)
280  // for continuous events (keyDown)
281  enum {
282  kKeyRepeatInitialDelay = 400,
283  kKeyRepeatSustainDelay = 100
284  };
285 
286  Common::KeyState _currentKeyDown;
287  uint32 _keyRepeatTimeLast;
288  uint32 _keyRepeatTimeDelay;
289 
290  uint32 _customEventRepeatTimeLast;
291  uint32 _customEventRepeatTimeDelay;
293 
294  // We do allow keys mapped to the same event,
295  // so eg. a key (Enter) could cause 2 or more events to fire,
296  // However, we should probably restrict the active events
297  // (that can be repeated while holding the mapped keys down)
298  // to a maximum of kMaxCustomConcurrentRepeatableEvents
299  ActiveCustomEventsArray _activeCustomEvents;
300 
301  // NOTE We still need keyboard functionality for naming saved games and also for the KIA Easter eggs.
302  // In KIA keyboard events should be accounted where possible - however some keymaps are still needed
303  // which is why we have the three separate common, gameplay-only and kia-only keymaps.
304  // If a valid keyboard key character eg. ("A") for text input (or Easter egg input)
305  // is also mapped to a common or KIA only custom event, then the custom event will be effected and not the key input.
306  // NOTE We don't use a custom action for left click -- we just use the standard left click action event (kStandardActionLeftClick)
307  // NOTE Dialogue Skip does not work for dialogue replayed when clicking on KIA clues (this is the original's behavior too)
308  // NOTE Toggle KIA options does not work when McCoy is walking towards a character when the player clicks on McCoy
309  // (this is the original's behavior too).
310  // "Esc" (by default) or the mapped key to this action still works though.
311  // NOTE A drawback of using customized keymapper for the game is that we can no longer replicate the original's behavior
312  // whereby holding down <SPACEBAR> would cause McCoy to keep switching quickly between combat mode and normal mode.
313  // This is because the original, when holding down right mouse button, would just toggle McCoy's mode once.
314  // We keep the behavior for "right mouse button".
315  // The continuous fast toggle behavior when holding down <SPACEBAR> feels more like a bug anyway.
316  // NOTE In the original, the KP_PERIOD key with NUMLOCK on, would work as a normal '.' character
317  // in the KIA Save Game screen. With NUMLOCK off, it would work as a delete request for the selected entry.
318  // However, NUMLOCK is currently not working as a modifier key for keymaps,
319  // so maybe we can implement the original behavior more accurately,
320  // when that is fixed in the keymapper or hardware-input code.
321  // For now, KP_PERIOD will work (by default) as a delete request.
322  enum BladeRunnerEngineMappableAction {
323 // kMpActionLeftClick, // default <left click> (select, walk-to, run-to, look-at, talk-to, use, shoot (combat mode), KIA (click on McCoy))
324  kMpActionToggleCombat, // default <right click> or <Spacebar>
325  kMpActionCutsceneSkip, // default <Return> or <KP_Enter> or <Esc> or <Spacebar>
326  kMpActionDialogueSkip, // default <Return> or <KP_Enter>
327  kMpActionToggleKiaOptions, // default <Esc> opens/closes KIA, in Options tab
328  kMpActionOpenKiaDatabase, // default <Tab> - only opens KIA (if closed), in one of the database tabs (the last active one, or else the first)
329  kMpActionOpenKIATabHelp, // default <F1>
330  kMpActionOpenKIATabSaveGame, // default <F2>
331  kMpActionOpenKIATabLoadGame, // default <F3>
332  kMpActionOpenKIATabCrimeSceneDatabase, // default <F4>
333  kMpActionOpenKIATabSuspectDatabase, // default <F5>
334  kMpActionOpenKIATabClueDatabase, // default <F6>
335  kMpActionOpenKIATabQuitGame, // default <F10>
336  kMpActionScrollUp, // ScummVM addition (scroll list up)
337  kMpActionScrollDown, // ScummVM addition (scroll list down)
338  kMpConfirmDlg, // default <Return> or <KP_Enter>
339  kMpDeleteSelectedSvdGame, // default <Delete> or <KP_Period>
340  kMpActionToggleCluePrivacy // default <right click>
341  };
342 
343 private:
344  MIXArchive _archives[kArchiveCount];
345  Common::Archive *_archive;
346 
347 public:
348  BladeRunnerEngine(OSystem *syst, const ADGameDescription *desc);
349  ~BladeRunnerEngine() override;
350 
351  bool hasFeature(EngineFeature f) const override;
352  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
353  Common::Error loadGameState(int slot) override;
354  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
355  Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
368  int getAutosaveSlot() const override { return -1; }
369 
370  void pauseEngineIntern(bool pause) override;
371 
372  Common::Error run() override;
373 
374  bool checkFiles(Common::Array<Common::String> &missingFiles);
375 
376  bool startup(bool hasSavegames = false);
377  void initChapterAndScene();
378  void shutdown();
379 
380  bool loadSplash();
381 
382  Common::Point getMousePos() const;
383  bool isMouseButtonDown() const;
384 
385  void gameLoop();
386  void gameTick();
387 
388  void actorsUpdate();
389 
390  void walkingReset();
391 
392  void handleEvents();
393  void handleKeyUp(Common::Event &event);
394  void handleKeyDown(Common::Event &event);
395  void handleMouseAction(int x, int y, bool mainButton, bool buttonDown, int scrollDirection = 0);
396  void handleMouseClickExit(int exitId, int x, int y, bool buttonDown);
397  void handleMouseClickRegion(int regionId, int x, int y, bool buttonDown);
398  void handleMouseClickItem(int itemId, bool buttonDown);
399  void handleMouseClickActor(int actorId, bool mainButton, bool buttonDown, Vector3 &scenePosition, int x, int y);
400  void handleMouseClick3DObject(int objectId, bool buttonDown, bool isClickable, bool isTarget);
401  void handleMouseClickEmpty(int x, int y, Vector3 &scenePosition, bool buttonDown);
402 
403  bool isAllowedRepeatedKey(const Common::KeyState &currKeyState);
404 
405  void handleCustomEventStart(Common::Event &event);
406  void handleCustomEventStop(Common::Event &event);
407  bool isAllowedRepeatedCustomEvent(const Common::Event &currEvent);
408 
409  bool shouldDropRogueCustomEvent(const Common::Event &evt);
410  void cleanupPendingRepeatingEvents(const Common::String &keymapperId);
411 
412  void gameWaitForActive();
413  void loopActorSpeaking();
414  void loopQueuedDialogueStillPlaying();
415 
416  void outtakePlay(int id, bool no_localization, int container = -1);
417  void outtakePlay(const Common::String &basenameNoExt, bool no_localization, int container = -3);
418 
419  bool openArchive(const Common::String &name);
420  bool closeArchive(const Common::String &name);
421  bool isArchiveOpen(const Common::String &name) const;
422 
423  bool openArchiveEnhancedEdition();
424 
425  void syncSoundSettings() override;
426  bool isSubtitlesEnabled();
427  void setSubtitlesEnabled(bool newVal);
428 
429  Common::SeekableReadStream *getResourceStream(const Common::String &name);
430 
431  bool playerHasControl();
432  void playerLosesControl();
433  void playerGainsControl(bool force = false);
434  void playerDied();
435 
436  bool saveGame(Common::WriteStream &stream, Graphics::Surface *thumb = NULL, bool origformat = false);
437  bool loadGame(Common::SeekableReadStream &stream, int version);
438  void newGame(int difficulty);
439  void autoSaveGame(int textId, bool endgame);
440 
441  void ISez(const Common::String &str);
442 
443  void blitToScreen(const Graphics::Surface &src) const;
444  Graphics::Surface generateThumbnail() const;
445 
446  Common::String getTargetName() const;
447 
448  uint8 getExtraCNotify();
449  void setExtraCNotify(uint8 val);
450 };
451 
452 static inline const Graphics::PixelFormat gameDataPixelFormat() {
453  return Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15);
454 }
455 
456 static inline void getGameDataColor(uint16 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) {
457  // gameDataPixelFormat().colorToARGB(vqaColor, a, r, g, b);
458  // using pixel format functions is too slow on some ports because of runtime checks
459  uint8 r5 = (color >> 10) & 0x1F;
460  uint8 g5 = (color >> 5) & 0x1F;
461  uint8 b5 = (color ) & 0x1F;
462  a = color >> 15;
463  r = (r5 << 3) | (r5 >> 2);
464  g = (g5 << 3) | (g5 >> 2);
465  b = (b5 << 3) | (b5 >> 2);
466 }
467 
468 static inline const Graphics::PixelFormat screenPixelFormat() {
469  return ((BladeRunnerEngine*)g_engine)->_screenPixelFormat;
470 }
471 
472 static inline void drawPixel(Graphics::Surface &surface, void* dst, uint32 value) {
473  switch (surface.format.bytesPerPixel) {
474  case 1:
475  *(uint8*)dst = (uint8)value;
476  break;
477  case 2:
478  *(uint16*)dst = (uint16)value;
479  break;
480  case 4:
481  *(uint32*)dst = (uint32)value;
482  break;
483  default:
484  break;
485  }
486 }
487 
488 static inline void getPixel(Graphics::Surface &surface, void* dst, uint32 &value) {
489  switch (surface.format.bytesPerPixel) {
490  case 1:
491  value = (uint8)(*(uint8*)dst);
492  break;
493  case 2:
494  value = (uint16)(*(uint16*)dst);
495  break;
496  case 4:
497  value = (uint32)(*(uint32*)dst);
498  break;
499  default:
500  break;
501  }
502 }
503 
504 void blit(const Graphics::Surface &src, Graphics::Surface &dst);
505 
506 } // End of namespace BladeRunner
507 
508 #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:66
EngineFeature
Definition: engine.h:250
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:120
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:45
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:198
Definition: algorithm.h:29
int getAutosaveSlot() const override
Definition: bladerunner.h:368
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:94
Definition: slice_renderer.h:45
Definition: bladerunner.h:113
Definition: system.h:167
Definition: settings.h:31
Definition: item_pickup.h:31
Definition: shape.h:61
Definition: engine.h:143
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