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
45namespace Common {
46class Archive;
47struct Event;
48}
49
50namespace GUI {
51class Debugger;
52}
53
55
56namespace BladeRunner {
57
58enum DebugLevels {
59 kDebugScript = 1,
60 kDebugSound,
61 kDebugAnimation,
62};
63
64class Actor;
65class ActorDialogueQueue;
66class ScreenEffects;
67class AIScripts;
68class AmbientSounds;
69class AudioCache;
70class AudioMixer;
71class AudioPlayer;
72class AudioSpeech;
73class Chapters;
74class CrimesDatabase;
75class Combat;
76class Debugger;
77class DialogueMenu;
78class Elevator;
79class EndCredits;
80class ESPER;
81class Framelimiter;
82class Font;
83class GameFlags;
84class GameInfo;
85class ItemPickup;
86class Items;
87class KIA;
88class Lights;
89class Mouse;
90class Music;
91class Obstacles;
92class Overlays;
93class PoliceMaze;
94class Scene;
95class SceneObjects;
96class SceneScript;
97class Scores;
98class Settings;
99class Shapes;
100class SliceAnimations;
101class SliceRenderer;
102class Spinner;
103class Subtitles;
104class SuspectsDatabase;
105class TextResource;
106class Time;
107class Vector3;
108class View;
109class VK;
110class Waypoints;
111class ZBuffer;
112
113class BladeRunnerEngine : public Engine {
114public:
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
344private:
345 MIXArchive _archives[kArchiveCount];
346 Common::Archive *_archive;
347
348public:
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
453static inline constexpr Graphics::PixelFormat gameDataPixelFormat() {
454 return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
455}
456
457static inline bool getGameDataColor(uint16 color, uint8 &r, uint8 &g, uint8 &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 r = (r5 << 3) | (r5 >> 2);
463 g = (g5 << 3) | (g5 >> 2);
464 b = (b5 << 3) | (b5 >> 2);
465 // alpha is inversed for fonts and shapes
466 return !(color & 0x8000);
467}
468
469static inline const Graphics::PixelFormat &screenPixelFormat() {
470 return ((BladeRunnerEngine*)g_engine)->_screenPixelFormat;
471}
472
473static 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
489static 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
505void blit(const Graphics::Surface &src, Graphics::Surface &dst);
506
507} // End of namespace BladeRunner
508
509#endif
Definition: ai_script.h:533
Definition: actor_dialogue_queue.h:33
Definition: actor.h:43
Definition: ambient_sounds.h:38
Definition: audio_cache.h:33
Definition: audio_mixer.h:43
Definition: audio_player.h:45
Definition: audio_speech.h:34
Definition: bladerunner.h:113
bool hasFeature(EngineFeature f) const override
Common::Error loadGameState(int slot) override
bool canLoadGameStateCurrently(Common::U32String *msg=nullptr) override
void syncSoundSettings() override
Common::Error run() override
void pauseEngineIntern(bool pause) override
int getAutosaveSlot() const override
Definition: bladerunner.h:369
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave=false) override
bool canSaveGameStateCurrently(Common::U32String *msg=nullptr) override
Definition: chapters.h:29
Definition: combat.h:36
Definition: crimes_database.h:34
Definition: debugger.h:56
Definition: dialogue_menu.h:39
Definition: esper.h:64
Definition: elevator.h:34
Definition: end_credits.h:29
Definition: font.h:38
Definition: framelimiter.h:31
Definition: game_flags.h:32
Definition: game_info.h:32
Definition: item_pickup.h:31
Definition: items.h:35
Definition: kia.h:68
Definition: lights.h:33
Definition: archive.h:31
Definition: mouse.h:35
Definition: music.h:37
Definition: obstacles.h:34
Definition: overlays.h:39
Definition: police_maze.h:80
Definition: scene.h:39
Definition: scene_objects.h:43
Definition: scene_script.h:526
Definition: scores.h:43
Definition: screen_effects.h:39
Definition: settings.h:31
Definition: shape.h:61
Definition: slice_animations.h:39
Definition: slice_renderer.h:45
Definition: spinner.h:37
Definition: subtitles.h:40
Definition: suspects_database.h:101
Definition: text_resource.h:32
Definition: time.h:31
Definition: vk.h:38
Definition: vector.h:47
Definition: view.h:33
Definition: waypoints.h:35
Definition: zbuffer.h:49
Definition: archive.h:141
Definition: error.h:81
Definition: random.h:44
Definition: stream.h:745
Definition: str.h:59
Definition: ustr.h:57
Definition: stream.h:77
Definition: engine.h:149
EngineFeature
Definition: engine.h:282
Definition: system.h:166
Language
Definition: language.h:45
Engine * g_engine
Definition: algorithm.h:29
Definition: advancedDetector.h:164
Definition: events.h:218
Definition: keyboard.h:294
Definition: rect.h:144
Definition: pixelformat.h:138
byte bytesPerPixel
Definition: pixelformat.h:139
Definition: surface.h:67
PixelFormat format
Definition: surface.h:95