ScummVM API documentation
scumm.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 SCUMM_SCUMM_H
23 #define SCUMM_SCUMM_H
24 
25 #include "engines/engine.h"
26 
27 #include "common/endian.h"
28 #include "common/events.h"
29 #include "common/file.h"
30 #include "common/savefile.h"
31 #include "common/keyboard.h"
32 #include "common/mutex.h"
33 #include "common/random.h"
34 #include "common/rect.h"
35 #include "common/rendermode.h"
36 #include "common/str.h"
37 #include "common/textconsole.h"
38 #include "common/text-to-speech.h"
39 #include "graphics/surface.h"
40 #include "graphics/sjis.h"
41 #include "graphics/palette.h"
42 
43 #include "scumm/file.h"
44 #include "scumm/gfx.h"
45 #include "scumm/detection.h"
46 #include "scumm/script.h"
47 #include "scumm/serializer.h"
48 
49 #ifdef __DS__
50 /* This disables the dual layer mode which is used in FM-Towns versions
51  * of SCUMM games and which emulates the behavior of the original code.
52  * The only purpose is code size reduction for certain backends.
53  * SCUMM 3 (FM-Towns) games will run in English in normal (DOS VGA) mode,
54  * which should work just fine in most situations. Some glitches might
55  * occur. Japanese mode and SCUMM 5 FM-Towns games will not work without
56  * dual layer (and 16 bit color) support.
57  */
58 #define DISABLE_TOWNS_DUAL_LAYER_MODE
59 #endif
60 
61 namespace GUI {
62 class Dialog;
63 }
64 using GUI::Dialog;
65 namespace Common {
66 class SeekableReadStream;
67 class WriteStream;
68 class SeekableWriteStream;
69 }
70 namespace Graphics {
71 class FontSJIS;
72 }
73 
86 namespace Scumm {
87 
88 class Actor;
89 class BaseCostumeLoader;
90 class BaseCostumeRenderer;
91 class BaseScummFile;
92 class CharsetRenderer;
93 class IMuse;
94 class IMuseDigital;
95 class MacGui;
96 class MusicEngine;
97 class Player_Towns;
98 class ScummEngine;
99 class ScummDebugger;
100 class Sound;
101 class Localizer;
102 class GlyphRenderer_v7;
103 
104 struct Box;
105 struct BoxCoords;
106 struct FindObjectInRoom;
107 
108 // Use g_scumm from error() ONLY
109 extern ScummEngine *g_scumm;
110 
111 /* System Wide Constants */
112 enum {
113  NUM_SENTENCE = 6,
114  NUM_SHADOW_PALETTE = 8
115 };
116 
117 /* SCUMM Debug Channels */
118 void debugC(int level, MSVC_PRINTF const char *s, ...) GCC_PRINTF(2, 3);
119 
120 struct VerbSlot;
121 struct ObjectData;
122 
123 enum {
131 
137 
144 
153  //
154 };
155 
156 enum {
157  MBS_LEFT_CLICK = 0x8000,
158  MBS_RIGHT_CLICK = 0x4000,
159  MBS_MOUSE_MASK = (MBS_LEFT_CLICK | MBS_RIGHT_CLICK),
160  MBS_MAX_KEY = 0x0200
161 };
162 
163 struct SentenceTab {
164  byte verb;
165  byte preposition;
166  uint16 objectA;
167  uint16 objectB;
168  uint8 freezeCount;
169 };
170 
171 struct StringSlot {
172  int16 xpos;
173  int16 ypos;
174  int16 right;
175  int16 height;
176  byte color;
177  byte charset;
178  bool center;
179  bool overhead;
180  bool no_talk_anim;
181  bool wrapping;
182 };
183 
185  // The 'default' values for this string slot. This is used so that the
186  // string slot can temporarily be set to different values, and then be
187  // easily reset to a previously set default.
188  StringSlot _default;
189 
190  void saveDefault() {
191  StringSlot &s = *this;
192  _default = s;
193  }
194 
195  void loadDefault() {
196  StringSlot &s = *this;
197  s = _default;
198  }
199 };
200 
202  bool _screenScroll;
203  uint _objectRedrawCount;
204  uint _objectStripRedrawCount;
205  uint _actorRedrawCount;
206  uint _actorLimbRedrawDrawCount;
207 
208 };
209 
210 enum WhereIsObject {
211  WIO_NOT_FOUND = -1,
212  WIO_INVENTORY = 0,
213  WIO_ROOM = 1,
214  WIO_GLOBAL = 2,
215  WIO_LOCAL = 3,
216  WIO_FLOBJECT = 4
217 };
218 
220  uint32 date;
221  uint16 time;
222  uint32 playtime;
223 };
224 
225 enum UserStates {
226  USERSTATE_SET_FREEZE = 0x01, // freeze scripts if USERSTATE_FREEZE_ON is set, unfreeze otherwise
227  USERSTATE_SET_CURSOR = 0x02, // shows cursor if USERSTATE_CURSOR_ON is set, hides it otherwise
228  USERSTATE_SET_IFACE = 0x04, // change user-interface (sentence-line, inventory, verb-area)
229  USERSTATE_FREEZE_ON = 0x08, // only interpreted if USERSTATE_SET_FREEZE is set
230  USERSTATE_CURSOR_ON = 0x10, // only interpreted if USERSTATE_SET_CURSOR is set
231  USERSTATE_IFACE_SENTENCE = 0x20, // only interpreted if USERSTATE_SET_IFACE is set
232  USERSTATE_IFACE_INVENTORY = 0x40, // only interpreted if USERSTATE_SET_IFACE is set
233  USERSTATE_IFACE_VERBS = 0x80 // only interpreted if USERSTATE_SET_IFACE is set
234 };
235 
236 #define USERSTATE_IFACE_ALL (USERSTATE_IFACE_SENTENCE | USERSTATE_IFACE_INVENTORY | USERSTATE_IFACE_VERBS)
237 
243 enum ResType {
244  rtInvalid = 0,
245  rtFirst = 1,
246  rtRoom = 1,
247  rtScript = 2,
248  rtCostume = 3,
249  rtSound = 4,
250  rtInventory = 5,
251  rtCharset = 6,
252  rtString = 7,
253  rtVerb = 8,
254  rtActorName = 9,
255  rtBuffer = 10,
256  rtScaleTable = 11,
257  rtTemp = 12,
258  rtFlObject = 13,
259  rtMatrix = 14,
260  rtBox = 15,
261  rtObjectName = 16,
262  rtRoomScripts = 17,
263  rtRoomImage = 18,
264  rtImage = 19,
265  rtTalkie = 20,
266  rtSpoolBuffer = 21,
267  rtLast = 21
268 };
269 
270 typedef uint16 ResId;
271 
272 class ResourceManager;
273 
314 #define PIT_BASE_FREQUENCY 1193182.0 // In Hz
315 #define PIT_V1_DIVISOR 65536.0
316 #define PIT_V2_4_DIVISOR 5041.0
317 #define PIT_V5_6_ORCHESTRATOR_DIVISOR 4096.0
318 #define PIT_V5_6_SUBTIMER_INC 3433.0
319 #define PIT_V5_SUBTIMER_THRESH 4167.0
320 #define PIT_V6_SAMNMAX_SUBTIMER_THRESH 4167.0
321 #define PIT_V6_DOTT_SUBTIMER_THRESH 4237.0
322 #define PIT_V7_ORCHESTRATOR_DIVISOR 3977.0
323 #define PIT_V7_SUBTIMER_INC 3977.0
324 #define PIT_V7_SUBTIMER_THRESH 4971.0
325 
326 #define PIT_HE_PUTT_PUTT_DIVISOR 9362.0
327 #define PIT_HE_FATTY_BEAR_DIVISOR 21845.0
328 
329 #define LOOM_STEAM_CDDA_RATE 240.0
330 
344 #define AMIGA_NTSC_VBLANK_RATE 240.0
345 #define AMIGA_PAL_VBLANK_RATE 200.0
346 
351 #define GAME_PROPER_SAVE 201
352 #define GAME_FAILED_SAVE 202
353 #define GAME_PROPER_LOAD 203
354 #define GAME_FAILED_LOAD 204
355 
360 #define GUI_PAGE_MAIN 0
361 #define GUI_PAGE_SAVE 1
362 #define GUI_PAGE_LOAD 2
363 #define GUI_PAGE_RESTART 3 // Sega CD
364 #define GUI_PAGE_CODE_CONFIRM 4 // Sega CD
365 #define GUI_PAGE_INVALID_CODE 5 // Sega CD
366 
367 #define GUI_CTRL_FIRST_SG 1
368 #define GUI_CTRL_LAST_SG 9
369 #define GUI_CTRL_SAVE_BUTTON 10
370 #define GUI_CTRL_LOAD_BUTTON 11
371 #define GUI_CTRL_PLAY_BUTTON 12
372 #define GUI_CTRL_QUIT_BUTTON 13
373 #define GUI_CTRL_OK_BUTTON 14
374 #define GUI_CTRL_CANCEL_BUTTON 15
375 #define GUI_CTRL_ARROW_UP_BUTTON 16
376 #define GUI_CTRL_ARROW_DOWN_BUTTON 17
377 #define GUI_CTRL_PATH_BUTTON 18
378 #define GUI_CTRL_MUSIC_SLIDER 19
379 #define GUI_CTRL_SPEECH_SLIDER 20
380 #define GUI_CTRL_SFX_SLIDER 21
381 #define GUI_CTRL_TEXT_SPEED_SLIDER 22
382 #define GUI_CTRL_DISPLAY_TEXT_CHECKBOX 23
383 #define GUI_CTRL_SPOOLED_MUSIC_CHECKBOX 24
384 #define GUI_CTRL_OUTER_BOX 26
385 #define GUI_CTRL_INNER_BOX 27
386 
387 // Sega CD
388 #define GUI_CTRL_NUMPAD_1 1
389 #define GUI_CTRL_NUMPAD_2 2
390 #define GUI_CTRL_NUMPAD_3 3
391 #define GUI_CTRL_NUMPAD_4 4
392 #define GUI_CTRL_NUMPAD_5 5
393 #define GUI_CTRL_NUMPAD_6 6
394 #define GUI_CTRL_NUMPAD_7 7
395 #define GUI_CTRL_NUMPAD_8 8
396 #define GUI_CTRL_NUMPAD_9 9
397 #define GUI_CTRL_NUMPAD_0 10
398 #define GUI_CTRL_RESTART_BUTTON 13
399 #define GUI_CTRL_ARROW_LEFT_BUTTON 16
400 #define GUI_CTRL_ARROW_RIGHT_BUTTON 17
401 #define GUI_CTRL_NUMPAD_BACK 23
402 
403 enum GUIString {
404  gsPause = 0,
405  gsVersion = 1,
406  gsTextSpeedSlider = 2,
407  gsRestart = 3,
408  gsQuitPrompt = 4,
409  gsSave = 5,
410  gsLoad = 6,
411  gsPlay = 7,
412  gsCancel = 8,
413  gsQuit = 9,
414  gsOK = 10,
415  gsMustName = 11,
416  gsGameNotSaved = 12,
417  gsGameNotLoaded = 13,
418  gsSaving = 14,
419  gsLoading = 15,
420  gsNamePrompt = 16,
421  gsSelectLoadPrompt = 17,
422  gsReplacePrompt = 18,
423  gsYes = 20,
424  gsNo = 21,
425  gsIMuseBuffer = 22,
426  gsVoiceAndText = 23,
427  gsTextDisplayOnly = 24,
428  gsVoiceOnly = 25,
429  gsYesKey = 26,
430  gsMusicVolumeSlider = 27,
431  gsVoiceVolumeSlider = 28,
432  gsSfxVolumeSlider = 29,
433  gsHeap = 30,
434  gsSavePath = 31,
435  gsTitle = 32,
436  gsDisabled = 33,
437  gsMusic = 34,
438  gsVoice = 35,
439  gsSfx = 36,
440  gsTextSpeed = 37,
441  gsDisplayText = 38,
442  gsSpooledMusic = 39,
443  gsInsertSaveDisk = 40,
444  gsSnapOn = 41,
445  gsSnapOff = 42,
446  gsRecalJoystick = 43,
447  gsMouseMode = 44,
448  gsMouseOn = 45,
449  gsMouseOff = 46,
450  gsJoystickOn = 47,
451  gsJoystickOff = 48,
452  gsSoundsOn = 49,
453  gsSoundsOff = 50,
454  gsVGAMode = 51,
455  gsEGAMode = 52,
456  gsCGAMode = 53,
457  gsHerculesMode = 54,
458  gsTandyMode = 55,
459  gsCurrentPasscode = 56,
460  gsEnterPasscode = 57,
461  gsConfirmPasscode = 58,
462  gsInvalidPasscode = 59,
463  gsSlowFast = 60,
464  gsRestartGame = 61,
465  gsHeapExt = 62,
466 };
467 
469  int relativeCenterX;
470  int relativeCenterY;
471  int xPos;
472  int yPos;
473  int normalFillColor;
474  int topLineColor;
475  int bottomLineColor;
476  int leftLineColor;
477  int rightLineColor;
478  int normalTextColor;
479  int highlightedTextColor;
480  int highlightedFillColor;
481  bool centerText;
482  Common::String label;
483 #ifdef USE_TTS
484  Common::String alternateTTSLabel;
485 #endif
486  bool doubleLinesFlag;
487 };
488 
489 enum ScummAction {
490  kScummActionNone,
491  kScummActionInsaneDownLeft,
492  kScummActionInsaneDown,
493  kScummActionInsaneDownRight,
494  kScummActionInsaneLeft,
495  kScummActionInsaneRight,
496  kScummActionInsaneUpLeft,
497  kScummActionInsaneUp,
498  kScummActionInsaneUpRight,
499  kScummActionInsaneAttack,
500  kScummActionInsaneSwitch,
501  kScummActionInsaneCheat,
502  kScummActionInsaneBack,
503  kScummActionInsaneSkip,
504 
505  kScummActionCount
506 };
507 
508 enum ScummBackendAction {
509  kScummBackendActionRebel1AxisUp = 11000,
510  kScummBackendActionRebel1AxisDown,
511  kScummBackendActionRebel1AxisLeft,
512  kScummBackendActionRebel1AxisRight,
513  kScummBackendActionRebel2AxisUp,
514  kScummBackendActionRebel2AxisDown,
515  kScummBackendActionRebel2AxisLeft,
516  kScummBackendActionRebel2AxisRight
517 };
518 
519 extern const char *const insaneKeymapId;
520 
524 class ScummEngine : public Engine, public Common::Serializable {
525  friend class ScummDebugger;
526  friend class CharsetRenderer;
527  friend class CharsetRendererClassic;
528  friend class CharsetRendererTownsClassic;
529  friend class ResourceManager;
530  friend class MacGuiImpl;
531  friend class MacIndy3Gui;
532  friend class MacLoomGui;
533  friend class MacV5Gui;
534  friend class MacV6Gui;
535  friend class LogicHEBasketball;
536  friend class ScummEditor;
537 
538 public:
539  /* Put often used variables at the top.
540  * That results in a shorter form of the opcode
541  * on some architectures. */
542  IMuse *_imuse = nullptr;
543  IMuseDigital *_imuseDigital = nullptr;
544  MusicEngine *_musicEngine = nullptr;
545  Player_Towns *_townsPlayer = nullptr;
546  Sound *_sound = nullptr;
547 
548  VerbSlot *_verbs = nullptr;
549  ObjectData *_objs = nullptr;
550 
551  // Core variables
552  GameSettings _game;
553  uint8 _gameMD5[16];
554 
557 
559  Gdi *_gdi = nullptr;
560 
562  ResourceManager *_res = nullptr;
563  int _insideCreateResource = 0; // Counter for HE sound
564 
565  bool _useOriginalGUI = true;
566  bool _enableAudioOverride = false;
567  bool _enableCOMISong = false;
568  bool _isAmigaPALSystem = false;
569  bool _quitFromScriptCmd = false;
570  bool _isHE995 = false;
571  bool _enableHECompetitiveOnlineMods = false;
572 
573  Common::Keymap *_insaneKeymap;
574 
575 protected:
577 
578  bool _needsSoundUnpause = false;
579 
580 public:
581  // Constructor / Destructor
582  ScummEngine(OSystem *syst, const DetectorResult &dr);
583  ~ScummEngine() override;
584 
585  // Engine APIs
586  Common::Error init();
587  Common::Error go();
588  Common::Error run() override {
589  Common::Error err;
590  err = init();
591  if (err.getCode() != Common::kNoError)
592  return err;
593  return go();
594  }
595 
596  void errorString(const char *buf_input, char *buf_output, int buf_output_size) override;
597  bool hasFeature(EngineFeature f) const override;
598  bool gameSupportsQuitDialogOverride() const;
599  void syncSoundSettings() override;
600 
601  Common::Error loadGameState(int slot) override;
602  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
603  Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
604  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
605 
606  void pauseEngineIntern(bool pause) override;
607 
608 protected:
609  virtual void setupScumm(const Common::Path &macResourceFile);
610  virtual void resetScumm();
611 
612  virtual void setupScummVars();
613  virtual void resetScummVars();
614  void setVideoModeVarToCurrentConfig();
615  void setSoundCardVarToCurrentConfig();
616 
617  void setupCharsetRenderer(const Common::Path &macFontFile);
618  void setupCostumeRenderer();
619 
620  virtual void loadLanguageBundle();
621  void loadCJKFont();
622  void loadKorFont();
623  void setupMusic(int midi);
624  void setTalkSpeed(int talkspeed);
625  int getTalkSpeed();
626 
627  // Scumm main loop & helper functions.
628  virtual void scummLoop(int delta);
629  virtual void scummLoop_updateScummVars();
630  virtual void scummLoop_handleSaveLoad();
631  virtual void scummLoop_handleDrawing();
632  virtual void scummLoop_handleActors() = 0;
633  virtual void scummLoop_handleEffects();
634  virtual void scummLoop_handleSound();
635 
636  virtual void runBootscript();
637 
638  virtual void terminateSaveMenuScript() {};
639 
640  // Event handling
641 public:
642  void beginTextInput();
643  void endTextInput();
644 
645  void parseEvents(); // Used by IMuseDigital::startSound
646 protected:
647  virtual void parseEvent(Common::Event event);
648 
649  void waitForTimer(int quarterFrames, bool freezeMacGui = false);
650  uint32 _lastWaitTime;
651 
652  void setTimerAndShakeFrequency();
653 
659  uint32 getIntegralTime(double fMsecs);
660  double _msecFractParts = 0.0;
661 
662  virtual void processInput();
663  virtual void processKeyboard(Common::KeyState lastKeyHit);
664  virtual void clearClickedStatus();
665 
666  // Cursor/palette
667  virtual void updateCursor();
668  virtual void animateCursor() {}
669  virtual void updatePalette();
670  virtual void setDefaultCursor() {};
671  virtual void setCursorTransparency(int a) {};
672  virtual void resetCursors() {}
673  virtual void setCursorHotspot(int x, int y) {}
674  virtual void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch, bool preventScale = false) {}
675 
676 public:
677  void pauseGame();
678  void restart();
679  bool isUsingOriginalGUI() const;
680  bool isMessageBannerActive(); // For Indy4 Jap character shadows
681 
682  bool _isIndy4Jap = false;
683 
684 protected:
685  Dialog *_pauseDialog = nullptr;
686  Dialog *_messageDialog = nullptr;
687  Dialog *_versionDialog = nullptr;
688 
689  void confirmExitDialog();
690  void confirmRestartDialog();
691  void pauseDialog();
692  void messageDialog(const Common::U32String &message);
693  void versionDialog();
694 
695  // Original GUI
696  int32 _bannerColors[50]; // Colors for the original GUI
697  byte *_bannerMem = nullptr;
698  uint32 _bannerMemSize = 0;
699  int _bannerSaveYStart = 0;
700 
701  bool _messageBannerActive = false;
702  bool _comiQuitMenuIsOpen = false;
703  bool _closeBannerAndQueryQuitFlag = false;
704 
705  // The followings are needed for MI1 FM-Towns
706  byte *_textSurfBannerMem = nullptr;
707  uint32 _textSurfBannerMemSize = 0;
708 
709  InternalGUIControl _internalGUIControls[30];
710 
711  // Special GUI strings
712  const char _emptyMsg[1] = {'\0'};
713  const char _uncheckedBox[2] = {' ', '\0'};
714  const char _checkedBox[2] = {'x', '\0'};
715  const char _arrowUp[2] = {'\x18', '\0'};
716  const char _arrowDown[2] = {'\x19', '\0'};
717  const char _arrowLeft[2] = {'\x3c', '\0'};
718  const char _arrowRight[2] = {'\x3d', '\0'};
719 
720  Common::StringArray _savegameNames;
721  int _menuPage = 0;
722  int _mainMenuSavegameLabel = 1;
723  int _curDisplayedSaveSlotPage = 0;
724  int _firstSaveStateOfList = 0; // For LOOM VGA
725  bool _mainMenuIsActive = false;
726  bool _quitByGUIPrompt = false;
727  char _mainMenuMusicSlider[17];
728  char _mainMenuSpeechSlider[17];
729  char _mainMenuSfxSlider[17];
730  char _mainMenuTextSpeedSlider[17];
731  char _mainMenuSegaCDPasscode[5];
732  int _spooledMusicIsToBeEnabled = 1;
733  int _saveScriptParam = 0;
734  int _guiCursorAnimCounter = 0;
735  int _v5VoiceMode = 0;
736 
737  // Fake flags just for sub v5 GUIs
738  int _internalSpeakerSoundsAreOn = 1;
739  int _guiMouseFlag = 1;
740  int _guiJoystickFlag = 1;
741 
742  bool _mixerMutedByGUI = false;
743 
744  Graphics::Surface _savegameThumbnail;
745  byte *_tempTextSurface = nullptr;
746  byte *_tempMainSurface = nullptr;
747  byte *_tempVerbSurface = nullptr;
748  bool _postGUICharMask = false;
749 
750  // Saved cursor pre and post GUI
751  byte *_curGrabbedCursor = nullptr;
752  int8 _oldCursorState = 0;
753  int _curCursorState = 0;
754  int _curCursorWidth = 0;
755  int _curCursorHeight = 0;
756  int _curCursorHotspotX = 0;
757  int _curCursorHotspotY = 0;
758 
759  virtual void setSnailCursor() {}
760 
761  void initBanners();
762  Common::KeyState showBannerAndPause(int bannerId, int32 waitTime, const char *msg, ...);
763  bool showBannerAndPauseForTextInput(int bannerId, const char *prompt, Common::String &input, uint maxLength = 255);
764  Common::KeyState showOldStyleBannerAndPause(const char *msg, int color, int32 waitTime);
765  Common::KeyState printMessageAndPause(const char *msg, int color, int32 waitTime, bool drawOnSentenceLine);
766 
767  void clearBanner();
768  void setBannerColors(int bannerId, byte r, byte g, byte b);
769  virtual int getBannerColor(int bannerId);
770  void setUpInternalGUIControl(int id, int normalFillColor, int normalTextColor,
771  int topLineColor, int bottomLineColor, int leftLineColor, int rightLineColor,
772  int highlightedTextColor, int highlightedFillColor,
773  int anchorPointX, int anchorPointY, int x, int y, const char *label, bool centerFlag, bool unknownFlag);
774  void drawInternalGUIControl(int id, bool highlightColor);
775  int getInternalGUIControlFromCoordinates(int x, int y);
776  virtual bool isSmushActive() { return false; }
777  virtual bool isInsaneActive() { return false; }
778 
779  virtual void queryQuit(bool returnToLauncher);
780  virtual void queryRestart();
781  virtual const char *getGUIString(int stringId);
782  void waitForBannerInput(int32 waitTime, Common::KeyState &ks, bool &leftBtnClicked, bool &rightBtnClicked, bool handleMouseWheel = false);
783  virtual int getGUIStringHeight(const char *str);
784  virtual int getGUIStringWidth(const char *str);
785  virtual void drawGUIText(const char *buttonString, Common::Rect *clipRect, int textXPos, int textYPos, int textColor, bool centerFlag);
786  void getSliderString(int stringId, int value, char *sliderString, int size);
787  virtual int getMusicVolume();
788  virtual int getSpeechVolume();
789  virtual int getSFXVolume();
790  virtual void setMusicVolume(int volume);
791  virtual void setSpeechVolume(int volume);
792  virtual void setSFXVolume(int volume);
793  virtual void toggleVoiceMode();
794  virtual void handleLoadDuringSmush() {}
795  virtual void setSkipVideo(int value) {}
796 
797  void showMainMenu();
798  virtual void setUpMainMenuControls();
799  void setUpMainMenuControlsSegaCD();
800  void setUpMainMenuControlsIndy4Jap();
801  void drawMainMenuControls();
802  void drawMainMenuControlsSegaCD();
803  void updateMainMenuControls();
804  void updateMainMenuControlsSegaCD();
805  void drawMainMenuTitle(const char *title);
806  bool executeMainMenuOperation(int op, int mouseX, int mouseY, bool &hasLoadedState);
807  bool executeMainMenuOperationSegaCD(int op, int mouseX, int mouseY, bool &hasLoadedState);
808  bool shouldHighlightLabelAndWait(int clickedControl);
809  void fillSavegameLabels();
810  bool canWriteGame(int slotId);
811  bool userWriteLabelRoutine(Common::KeyState &ks, bool &leftMsClicked, bool &rightMsClicked);
812  void saveCursorPreMenu();
813  void restoreCursorPostMenu();
814  void saveSurfacesPreGUI();
815  void restoreSurfacesPostGUI();
816  void showDraftsInventory();
817  void setUpDraftsInventory();
818  void drawDraftsInventory();
819 
820 public:
821  char displayMessage(MSVC_PRINTF const char *message, ...) GCC_PRINTF(2, 3);
822  bool displayMessageYesNo(MSVC_PRINTF const char *message, ...) GCC_PRINTF(2, 3);
823  bool displayMessageOKQuit(MSVC_PRINTF const char *message, ...) GCC_PRINTF(2, 3);
824 
825 protected:
826  byte _fastMode = 0;
827 
828  byte _numActors = 0;
829  Actor **_actors = nullptr; // Has _numActors elements
830  Actor **_sortedActors = nullptr;
831 
832  byte *_arraySlot = nullptr;
833  uint16 *_inventory = nullptr;
834  uint16 *_newNames = nullptr;
835 public:
836  // VAR is a wrapper around scummVar, which attempts to include additional
837  // useful information should an illegal var access be detected.
838  #define VAR(x) scummVar(x, #x, __FILE__, __LINE__)
839  int32& scummVar(byte var, const char *varName, const char *file, int line) {
840  if (var == 0xFF) {
841  error("Illegal access to variable %s in file %s, line %d", varName, file, line);
842  }
843  return _scummVars[var];
844  }
845  int32 scummVar(byte var, const char *varName, const char *file, int line) const {
846  if (var == 0xFF) {
847  error("Illegal access to variable %s in file %s, line %d", varName, file, line);
848  }
849  return _scummVars[var];
850  }
851 
852  bool applyMi2NiDemoOverride();
853  struct Playback {
854  struct FrameEvent {
855  bool hasPos = false;
856  uint16 x = 0;
857  uint16 y = 0;
858 
859  uint16 mbs = 0;
860  uint16 key = 0;
861  };
862 
863  static void parseStream(const Common::Array<byte> &stream, Common::Array<FrameEvent> &outEvents);
864 
865  bool _loaded = false;
866  bool _attempted = false;
867  bool _active = false;
868 
869  bool _mi2DemoVarsApplied = false;
870 
872 
873  uint32 _streamOff = 0;
874  uint32 _streamBytes = 0;
875 
876  uint32 _nextIndex = 0;
877  int _lastRoom = -1;
878 
879  bool _hasPrevMbs = false;
880  uint16 _prevMbs = 0;
881  uint32 _firstInteractIndex = 0;
882  bool _firstInteractValid = false;
883 
884  int16 _curX = 0;
885  int16 _curY = 0;
886  bool _pendingLUp = false;
887  bool _pendingRUp = false;
888 
889  bool _sputmCmdActive = false;
890  byte _sputmCmdEnterCount = 0;
891  Common::String _sputmCmdBuf;
892  Common::String _name;
893 
894  void reset();
895  bool tryLoadPlayback(ScummEngine *engine, const Common::Path &path = Common::Path("demo.rec"));
896  bool startPlayback(ScummEngine *engine);
897  void playbackPump(ScummEngine *engine);
898 
899  //MI2 DOS NI Demo specific playback helpers
900  void mi2DemoArmPlaybackByRoom(ScummEngine *engine);
901  void mi2DemoPlaybackJumpRoom(ScummEngine *engine, int room);
902  bool handleMi2NIDemoSputmDebugKey(ScummEngine *engine, uint16 rawKey);
903  };
904 
905  Playback _playback;
906 
907 protected:
908  int16 _varwatch = 0;
909  int32 *_roomVars = nullptr;
910  int32 *_scummVars = nullptr;
911  byte *_bitVars = nullptr;
912 
913  /* Global resource tables */
914  int _numVariables = 0;
915  int _numBitVariables = 0;
916  int _numLocalObjects = 0;
917  int _numGlobalObjects = 0;
918  int _numArray = 0;
919  int _numVerbs = 0;
920  int _numFlObject = 0;
921  int _numInventory = 0;
922  int _numNewNames = 0;
923  int _numGlobalScripts = 0;
924  int _numRoomVariables = 0;
925  int _numPalettes = 0;
926  int _numSprites = 0;
927  int _numTalkies = 0;
928  int _numWindows = 0;
929  int _HEHeapSize = 0;
930 
931 public:
932  int _numLocalScripts = 60, _numImages = 0, _numRooms = 0, _numScripts = 0, _numSounds = 0; // Used by HE games
933  int _numCostumes = 0; // FIXME - should be protected, used by Actor::remapActorPalette
934  int32 _numCharsets = 0; // FIXME - should be protected, used by CharsetRenderer
935 
936  BaseCostumeLoader *_costumeLoader = nullptr;
937  BaseCostumeRenderer *_costumeRenderer = nullptr;
938 
939  int _NESCostumeSet = 0;
940  void NES_loadCostumeSet(int n);
941  byte *_NEScostdesc = nullptr, *_NEScostlens = nullptr, *_NEScostoffs = nullptr, *_NEScostdata = nullptr;
942  byte _NESPatTable[2][4096];
943  byte _NESPalette[2][16];
944  byte _NESBaseTiles = 0;
945 
946  int _NESStartStrip = 0;
947 
948 protected:
949  int _curPalIndex = 0;
950 
951 public:
952  byte _currentRoom = 0; // FIXME - should be protected but Actor::isInCurrentRoom uses it
953  int _roomResource = 0; // FIXME - should be protected but Sound::pauseSounds uses it
954  bool _egoPositioned = false; // Used by Actor::putActor, hence public
955 
956  FilenamePattern _filenamePattern;
957 
958  virtual Common::Path generateFilename(const int room) const;
959 
960 protected:
961  Common::KeyState _keyPressed;
962  bool _keyDownMap[512]; // FIXME - 512 is a guess. it's max(kbd.ascii)
963  bool _actionMap[kScummActionCount];
964 
965  Common::Point _mouse;
966  Common::Point _virtualMouse;
967 
968  uint16 _mouseAndKeyboardStat = 0;
969  byte _leftBtnPressed = 0, _rightBtnPressed = 0;
970 
971  int _mouseWheelFlag = 0; // For original save/load dialog only
972 
973  bool _setupIsComplete = false;
974 
979  uint32 _lastInputScriptTime = 0;
980 
982  int _bootParam = 0;
983 
984  // Various options useful for debugging
985  bool _dumpScripts = false;
986  bool _hexdumpScripts = false;
987  bool _showStack = false;
988  bool _debugMode = false;
989 
990  // Save/Load class - some of this may be GUI
991  byte _saveLoadFlag = 0, _saveLoadSlot = 0;
992  uint32 _lastSaveTime = 0;
993  bool _saveTemporaryState = false;
994  bool _pauseSoundsDuringSave = true;
995  bool _loadFromLauncher = false;
996  bool _videoModeChanged = false;
997  Common::String _saveLoadFileName;
998  Common::String _saveLoadDescription;
999 
1000  bool saveState(Common::SeekableWriteStream *out, bool writeHeader = true);
1001  bool saveState(int slot, bool compat, Common::String &fileName);
1002  bool loadState(int slot, bool compat);
1003  bool loadState(int slot, bool compat, Common::String &fileName);
1004  void saveLoadWithSerializer(Common::Serializer &s) override;
1005  void saveResource(Common::Serializer &ser, ResType type, ResId idx);
1006  void loadResource(Common::Serializer &ser, ResType type, ResId idx);
1007  void loadResourceOLD(Common::Serializer &ser, ResType type, ResId idx); // "Obsolete"
1008 
1009  virtual int checkSoundEngineSaveDataSize(Serializer &s);
1010 
1011  void copyHeapSaveGameToFile(int slot, const char *saveName);
1012  bool changeSavegameName(int slot, char *newName);
1013  virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName);
1014  virtual Common::SeekableWriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName);
1015 
1016  Common::String makeSavegameName(int slot, bool temporary) const {
1017  return makeSavegameName(_targetName, slot, temporary);
1018  }
1019 
1020  int getKeyState(int key);
1021  int getActionState(ScummAction action);
1022 
1023 public:
1024  static Common::String makeSavegameName(const Common::String &target, int slot, bool temporary);
1025 
1026  bool getSavegameName(int slot, Common::String &desc);
1027  void listSavegames(bool *marks, int num);
1028 
1029  void requestSave(int slot, const Common::String &name);
1030  void requestLoad(int slot);
1031 
1032  Common::String getTargetName() const { return _targetName; }
1033  bool canPauseSoundsDuringSave() const { return _pauseSoundsDuringSave; }
1034 
1035 // thumbnail + info stuff
1036 public:
1037  static bool querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos);
1038 
1039 protected:
1040  void saveInfos(Common::WriteStream *file);
1041  static bool loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff);
1042 
1043  /* Script VM - should be in Script class */
1044  uint32 _localScriptOffsets[1024];
1045  Common::HashMap<int, byte *> _scriptOverrides;
1046  const byte *_scriptPointer = nullptr;
1047  const byte *_scriptOrgPointer = nullptr;
1048  const byte * const *_lastCodePtr = nullptr;
1049  byte _opcode = 0;
1050  bool _debug = false;
1051  byte _currentScript = 0xFF; // Let debug() work on init stage
1052  int _scummStackPos = 0;
1053  int _vmStack[256];
1054 
1055  char _engineVersionString[50];
1056  char _dataFileVersionString[50];
1057 
1058  OpcodeEntry _opcodes[256];
1059 
1064  bool currentScriptSlotIs(uint16 script) const {
1065  return _currentScript != 0xFF && vm.slot[_currentScript].number == script;
1066  }
1067 
1068  virtual void setupOpcodes() = 0;
1069  void executeOpcode(byte i);
1070  const char *getOpcodeDesc(byte i);
1071 
1072  void initializeLocals(int slot, int *vars);
1073  int getScriptSlot();
1074 
1075  void startScene(int room, Actor *a, int b);
1076  bool startManiac();
1077 
1078 public:
1079  void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle = 0);
1080  void stopScript(int script);
1081  void nukeArrays(byte scriptSlot);
1082 
1083 protected:
1084  void runObjectScript(int script, int entry, bool freezeResistant, bool recursive, int *vars, int slot = -1, int cycle = 0);
1085  void runScriptNested(int script);
1086  void executeScript();
1087  void updateScriptPtr();
1088  virtual void runInventoryScript(int i);
1089  virtual void runInventoryScriptEx(int i);
1090  virtual void checkAndRunSentenceScript();
1091  bool monkey1HermanNoteWorkaround(const SentenceTab &st);
1092  void runExitScript();
1093  void runEntryScript();
1094  void runQuitScript();
1095  void runAllScripts();
1096  void freezeScripts(int scr);
1097  void unfreezeScripts();
1098 
1099  bool isScriptInUse(int script) const;
1100  bool isRoomScriptRunning(int script) const;
1101  bool isScriptRunning(int script) const;
1102 
1103  void killAllScriptsExceptCurrent();
1104  void killScriptsAndResources();
1105  void decreaseScriptDelay(int amount);
1106 
1107  void stopObjectCode();
1108  void stopObjectScript(int script);
1109 
1110  void getScriptBaseAddress();
1111  void resetScriptPointer();
1112  int getVerbEntrypoint(int obj, int entry);
1113 
1114  void refreshScriptPointer();
1115  byte fetchScriptByte();
1116  virtual uint fetchScriptWord();
1117  virtual int fetchScriptWordSigned();
1118  uint fetchScriptDWord();
1119  int fetchScriptDWordSigned();
1120  void ignoreScriptWord() { fetchScriptWord(); }
1121  void ignoreScriptByte() { fetchScriptByte(); }
1122  void push(int a);
1123  int pop();
1124  virtual int readVar(uint var);
1125  virtual void writeVar(uint var, int value);
1126  // SCUMM 1/2
1127  virtual void resetSentence() {}
1128 
1129 protected:
1130  virtual void beginCutscene(int *args);
1131  virtual void endCutscene();
1132  void abortCutscene();
1133  void beginOverride();
1134  void endOverride();
1135 
1136  void copyScriptString(byte *dst);
1137  int resStrLen(const byte *src);
1138  void doSentence(int c, int b, int a);
1139 
1140  /* Should be in Resource class */
1141  BaseScummFile *_fileHandle = nullptr;
1142  uint32 _fileOffset = 0;
1143 public:
1146  Common::Path _macCursorFile;
1147 
1148  bool openFile(BaseScummFile &file, const Common::Path &filename, bool resourceFile = false);
1149  ScummFile *instantiateScummFile(bool indexPAKFiles = true);
1150 
1151 protected:
1152  int _resourceHeaderSize = 8;
1153  byte _resourceMapper[128];
1154  const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile?
1155  uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile?
1156 
1157  virtual void allocateArrays();
1158  void openRoom(int room);
1159  void closeRoom();
1160  void deleteRoomOffsets();
1161  virtual void readRoomsOffsets();
1162  void askForDisk(const Common::Path &filename, int disknum);
1163  byte getEncByte(int room);
1164  bool openResourceFile(const Common::Path &filename, byte encByte);
1165 
1166  void loadPtrToResource(ResType type, ResId idx, const byte *ptr);
1167  virtual int readResTypeList(ResType type);
1168 // void allocResTypeData(ResType type, uint32 tag, int num, int mode);
1169 // byte *createResource(int type, int index, uint32 size);
1170  int loadResource(ResType type, ResId idx);
1171 // void nukeResource(ResType type, ResId idx);
1172  int getResourceRoomNr(ResType type, ResId idx);
1173  virtual uint32 getResourceRoomOffset(ResType type, ResId idx);
1174 
1175  void scriptOverride(ResId room, int script);
1176 
1177 public:
1178  int getResourceSize(ResType type, ResId idx);
1179  byte *getResourceAddress(ResType type, ResId idx);
1180  virtual byte *getStringAddress(ResId idx);
1181  byte *getStringAddressVar(int i);
1182  void ensureResourceLoaded(ResType type, ResId idx);
1183 
1184 protected:
1185  Common::Mutex _resourceAccessMutex; // Used in getResourceSize(), getResourceAddress() and findResource()
1186  // to avoid race conditions between the audio thread of Digital iMUSE
1187  // and the main SCUMM thread
1188 
1189  int readSoundResource(ResId idx);
1190  int readSoundResourceSmallHeader(ResId idx);
1191  bool isResourceInUse(ResType type, ResId idx) const;
1192 
1193  virtual void setupRoomSubBlocks();
1194  virtual void resetRoomSubBlocks();
1195 
1196  virtual void clearRoomObjects();
1197  virtual void resetRoomObjects();
1198  virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
1199 
1200  virtual void readArrayFromIndexFile();
1201  virtual void readMAXS(int blockSize) = 0;
1202  virtual void readGlobalObjects();
1203  virtual void readIndexFile();
1204  virtual void readIndexBlock(uint32 block, uint32 itemsize);
1205  virtual void loadCharset(int i);
1206  void nukeCharset(int i);
1207 
1208  int _lastLoadedRoom = 0;
1209 public:
1210  const byte *findResourceData(uint32 tag, const byte *ptr);
1211  const byte *findResource(uint32 tag, const byte *ptr);
1212  void applyWorkaroundIfNeeded(ResType type, int idx);
1213  bool verifyMI2MacBootScript();
1214  bool verifyMI2MacBootScript(byte *buf, int size);
1215  bool tryPatchMI1CannibalScript(byte *buf, int size);
1216 
1217  int getResourceDataSize(const byte *ptr) const;
1218  void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
1219 
1220 public:
1221  /* Should be in Object class */
1222  byte OF_OWNER_ROOM = 0;
1223  int getInventorySlot();
1224  int findInventory(int owner, int index);
1225  int getInventoryCount(int owner);
1226 
1227 protected:
1228  byte *_objectOwnerTable = nullptr, *_objectRoomTable = nullptr, *_objectStateTable = nullptr;
1229  int _numObjectsInRoom = 0;
1230 
1231 public:
1232  uint32 *_classData = nullptr;
1233 
1234 protected:
1235  void markObjectRectAsDirty(int obj);
1236  virtual void loadFlObject(uint object, uint room);
1237  void nukeFlObjects(int min, int max);
1238  int findFlObjectSlot();
1239  int findLocalObjectSlot();
1240  void addObjectToInventory(uint obj, uint room);
1241  void updateObjectStates();
1242 public:
1243  bool getClass(int obj, int cls) const; // Used in actor.cpp, hence public
1244 protected:
1245  void putClass(int obj, int cls, bool set);
1246  int getState(int obj);
1247  void putState(int obj, int state);
1248  void setObjectState(int obj, int state, int x, int y);
1249  int getOwner(int obj) const;
1250  void putOwner(int obj, int owner);
1251  void setOwnerOf(int obj, int owner);
1252  void clearOwnerOf(int obj);
1253  int getObjectRoom(int obj) const;
1254  virtual bool objIsActor(int obj);
1255  virtual int objToActor(int obj);
1256  virtual int actorToObj(int actor);
1257  int getObjX(int obj);
1258  int getObjY(int obj);
1259  void getObjectWidth(int object, int &width) { int x, y, dir; getObjectXYPos(object, x, y, dir, width); }
1260  void getObjectXYPos(int object, int &x, int &y) { int dir, width; getObjectXYPos(object, x, y, dir, width); }
1261  void getObjectXYPos(int object, int &x, int &y, int &dir) { int width; getObjectXYPos(object, x, y, dir, width); }
1262  void getObjectXYPos(int object, int &x, int &y, int &dir, int &width);
1263  int getObjOldDir(int obj);
1264  int getObjNewDir(int obj);
1265  int getObjectIndex(int object) const;
1266  int getObjectImageCount(int object);
1267  int whereIsObject(int object) const;
1268  int findObject(int x, int y);
1269  void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
1270 public:
1271  int getObjectOrActorWidth(int object, int &width); // Used in v4 and below
1272  int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
1273  int getDist(int x, int y, int x2, int y2); // Also used in actor.cpp
1274 protected:
1275 
1276  int getObjActToObjActDist(int a, int b); // Not sure how to handle
1277  const byte *getObjOrActorName(int obj); // these three..
1278  void setObjectName(int obj);
1279 
1280  void addObjectToDrawQue(int object);
1281  void removeObjectFromDrawQue(int object);
1282  void clearDrawObjectQueue();
1283  void processDrawQue();
1284 
1285  virtual void clearDrawQueues();
1286 
1287  uint32 getOBCDOffs(int object) const;
1288  byte *getOBCDFromObject(int obj, bool v0CheckInventory = true);
1289  const byte *getOBIMFromObjectData(const ObjectData &od);
1290  const byte *getObjectImage(const byte *ptr, int state);
1291  virtual int getObjectIdFromOBIM(const byte *obim);
1292 
1293 protected:
1294  /* Should be in Verb class */
1295  uint16 _verbMouseOver = 0;
1296  int8 _userPut = 0;
1297  uint16 _userState = 0;
1298 
1299  virtual void handleMouseOver(bool updateInventory);
1300  virtual void redrawVerbs();
1301  virtual void checkExecVerbs();
1302 
1303  void verbMouseOver(int verb);
1304  int findVerbAtPos(int x, int y) const;
1305  virtual void drawVerb(int verb, int mode, Common::TextToSpeechManager::Action ttsAction = Common::TextToSpeechManager::INTERRUPT);
1306  virtual void runInputScript(int clickArea, int val, int mode);
1307  void restoreVerbBG(int verb);
1308  void drawVerbBitmap(int verb, int x, int y);
1309  int getVerbSlot(int id, int mode) const;
1310  void killVerb(int slot);
1311  void setVerbObject(uint room, uint object, uint verb);
1312 
1313 public:
1314  bool isValidActor(int id) const;
1315 
1316  /* Should be in Actor class */
1317  Actor *derefActor(int id, const char *errmsg = 0) const;
1318  Actor *derefActorSafe(int id, const char *errmsg) const;
1319 
1320 protected:
1321  void walkActors();
1322  void playActorSounds();
1323  void redrawAllActors();
1324  virtual void setActorRedrawFlags();
1325  void putActors();
1326  void showActors();
1327  void resetV1ActorTalkColor();
1328  virtual void resetActorBgs();
1329  virtual void processActors();
1330  void processUpperActors();
1331  virtual int getActorFromPos(int x, int y);
1332 
1333 public:
1334  /* Actor talking stuff */
1335  byte _actorToPrintStrFor = 0, _V1TalkingActor = 0;
1336  int _sentenceNum = 0;
1337  SentenceTab _sentence[NUM_SENTENCE];
1338  StringTab _string[6];
1339  byte _haveMsg = 0;
1340  int16 _talkDelay = 0;
1341  int _NES_lastTalkingActor = 0;
1342  int _NES_talkColor = 0;
1343 
1344  virtual void actorTalk(const byte *msg);
1345  void stopTalk();
1346  int getTalkingActor(); // Wrapper around VAR_TALK_ACTOR for V1 Maniac
1347  void setTalkingActor(int variable);
1348 
1349  // Generic costume code
1350  bool isCostumeInUse(int i) const;
1351 
1352 protected:
1353  /* Should be in Graphics class? */
1354  uint16 _screenB = 0, _screenH = 0;
1355 public:
1356  int _roomHeight = 0, _roomWidth = 0;
1357  int _screenHeight = 0, _screenWidth = 0;
1358  VirtScreen _virtscr[4]; // Virtual screen areas
1359  CameraData camera; // 'Camera' - viewport
1360  bool _cameraIsFrozen = false;
1361 
1362  int _screenStartStrip = 0, _screenEndStrip = 0;
1363  int _screenTop = 0;
1364  bool _forceBannerVirtScreen = false;
1365 
1366  // For Mac versions of 320x200 games:
1367  // these versions rendered at 640x480 without any aspect ratio correction;
1368  // in order to correctly display the games as they should be, we perform some
1369  // offset corrections within the various rendering pipelines.
1370  //
1371  // The only reason I've made _useMacScreenCorrectHeight toggleable is because
1372  // maybe someday the screen correction can be activated or deactivated from the
1373  // ScummVM GUI; but currently I'm not taking that responsibility, after all the
1374  // work done on ensuring that old savegames translate correctly to the new setting... :-P
1375  bool _useMacScreenCorrectHeight = true;
1376  int _macScreenDrawOffset = 20;
1377 
1378  Common::RenderMode _renderMode;
1379  uint8 _bytesPerPixel = 1;
1380  Graphics::PixelFormat _outputPixelFormat;
1381 
1382 protected:
1383  ColorCycle _colorCycle[16]; // Palette cycles
1384  uint8 _colorUsedByCycle[256];
1385  Graphics::PaletteLookup _pl; // Used by the internal GUI
1386 
1387  uint32 _ENCD_offs = 0, _EXCD_offs = 0;
1388  uint32 _CLUT_offs = 0, _EPAL_offs = 0;
1389  uint32 _IM00_offs = 0, _PALS_offs = 0;
1390 
1391  //ender: fullscreen
1392  bool _fullRedraw = false, _bgNeedsRedraw = false;
1393  bool _screenEffectFlag = false, _completeScreenRedraw = false;
1394  bool _disableFadeInEffect = false;
1395 
1396  struct {
1397  int hotspotX, hotspotY, width, height;
1398  byte animate, animateIndex;
1399  int8 state;
1400  } _cursor;
1401 
1402  // HACK Double the array size to handle 16-bit images.
1403  // this should be dynamically allocated based on game depth instead.
1404  byte _grabbedCursor[16384];
1405  byte _macGrabbedCursor[16384 * 4]; // Double resolution cursor
1406  byte _currentCursor = 0;
1407 
1408  byte _newEffect = 0, _switchRoomEffect2 = 0, _switchRoomEffect = 0;
1409  bool _doEffect = false;
1410 
1411  bool _snapScroll = false;
1412 
1413  virtual void setBuiltinCursor(int index) {}
1414 public:
1415  bool isLightOn() const;
1416 
1417  virtual int getCurrentLights() const;
1418 
1419 protected:
1420  void initScreens(int b, int h);
1421  void initVirtScreen(VirtScreenNumber slot, int top, int width, int height, bool twobufs, bool scrollable);
1422  void initBGBuffers(int height);
1423  void initCycl(const byte *ptr); // Color cycle
1424 
1425  void decodeNESBaseTiles();
1426  void playNESTitleScreens();
1427 
1428  void drawObject(int obj, int scrollType);
1429  void drawRoomObjects(int arg);
1430  void drawRoomObject(int i, int arg);
1431  void drawBox(int x, int y, int x2, int y2, int color);
1432  void drawLine(int x1, int y1, int x2, int y2, int color);
1433  void drawPixel(VirtScreen *vs, int x, int y, int16 color, bool useBackbuffer = false);
1434 
1435  void moveScreen(int dx, int dy, int height);
1436 
1437  void restoreBackground(Common::Rect rect, byte backcolor = 0);
1438  void redrawBGStrip(int start, int num);
1439  virtual void redrawBGAreas();
1440 
1441  void cameraMoved();
1442  void setCameraAtEx(int at);
1443  virtual void setCameraAt(int pos_x, int pos_y);
1444  virtual void setCameraFollows(Actor *a, bool setCamera = false);
1445  virtual void moveCamera();
1446  virtual void panCameraTo(int x, int y);
1447  void clampCameraPos(Common::Point *pt);
1448  void actorFollowCamera(int act);
1449 
1450  const byte *getPalettePtr(int palindex, int room);
1451 
1452  void setPaletteFromTable(const byte *ptr, int numcolor, int firstIndex = 0);
1453  void resetPalette(bool isBootUp = false);
1454 
1455  void setCurrentPalette(int pal);
1456  void setRoomPalette(int pal, int room);
1457  void setPCEPaletteFromPtr(const byte *ptr);
1458  void setAmigaPaletteFromPtr(const byte *ptr);
1459  virtual void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
1460  void setV1ColorTable(int renderMode);
1461 
1462  virtual void setPalColor(int index, int r, int g, int b);
1463  void setDirtyColors(int min, int max);
1464  const byte *findPalInPals(const byte *pal, int index);
1465  void swapPalColors(int a, int b);
1466  virtual void copyPalColor(int dst, int src);
1467  void cyclePalette();
1468  void stopCycle(int i);
1469  virtual void palManipulateInit(int resID, int start, int end, int time);
1470  void palManipulate();
1471  uint32 findClosestPaletteColor(byte *palette, int paletteLength, byte r, byte g, byte b);
1472  void applyGrayscaleToPaletteRange(int min, int max); // For Sam&Max original noir mode
1473  bool haveToApplyMonkey1PaletteFix();
1474 
1475 public:
1476  uint8 *getHEPaletteSlot(uint16 palSlot);
1477  uint16 get16BitColor(uint8 r, uint8 g, uint8 b);
1478  uint32 getPaletteColorFromRGB(byte *palette, byte r, byte g, byte b);
1479  uint32 getPackedRGBColorFromPalette(byte *palette, uint32 color);
1480  void fetchBlackAndWhite(uint32 &black, uint32 &white, byte *palette, int paletteEntries);
1481  int remapPaletteColor(int r, int g, int b, int threshold); // Used by Actor::remapActorPalette
1482  void readPCEPalette(const byte **ptr, byte **dest, int numEntries);
1483  void colorPCEToRGB(uint16 color, byte *r, byte *g, byte *b);
1484  void setPCETextPalette(uint8 color);
1485 protected:
1486  void moveMemInPalRes(int start, int end, byte direction);
1487  void setShadowPalette(int slot, int redScale, int greenScale, int blueScale, int startColor, int endColor);
1488  void setShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end);
1489  virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
1490 
1491 public:
1492  void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);
1493  void markRectAsDirty(VirtScreenNumber virt, const Common::Rect& rect, int dirtybit = 0) {
1494  markRectAsDirty(virt, rect.left, rect.right, rect.top, rect.bottom, dirtybit);
1495  }
1496 protected:
1497  // Screen rendering
1498  byte *_compositeBuf;
1499  byte *_hercCGAScaleBuf = nullptr;
1500  bool _enableEGADithering = false;
1501  bool _supportsEGADithering = false;
1502  bool _enableSegaShadowMode = false;
1503 
1504  virtual void drawDirtyScreenParts();
1505  void updateDirtyScreen(VirtScreenNumber slot);
1506  void drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom);
1507 
1508  void mac_markScreenAsDirty(int x, int y, int w, int h);
1509  void mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height);
1510  void mac_drawIndy3TextBox();
1511  void mac_undrawIndy3TextBox();
1512  void mac_undrawIndy3CreditsText();
1513  void mac_drawBufferToScreen(const byte *buffer, int pitch, int x, int y, int width, int height, bool epxRectangleExpansion = true);
1514  void mac_updateCompositeBuffer(const byte *buffer, int pitch, int x, int y, int width, int height);
1515  void mac_blitDoubleResImage(const byte *buffer, int pitch, int x, int y, int width, int height);
1516  void mac_applyDoubleResToBuffer(const byte *inputBuffer, byte *outputBuffer, int width, int height, int inputPitch, int outputPitch);
1517  void mac_blitEPXImage(const byte *buffer, int pitch, int x, int y, int width, int height, bool epxRectangleExpansion = true);
1518  void mac_applyEPXToBuffer(const byte *inputBuffer, byte *outputBuffer, int width, int height, int inputPitch, int outputPitch, int xOffset, int yOffset, int bufferWidth, int bufferHeight);
1519  void mac_scaleCursor(byte *&outCursor, int &outHotspotX, int &outHotspotY, int &outWidth, int &outHeight);
1520  void mac_toggleSmoothing();
1521 
1522  Common::KeyState mac_showOldStyleBannerAndPause(const char *msg, int32 waitTime);
1523 
1524  const byte *postProcessDOSGraphics(VirtScreen *vs, int &pitch, int &x, int &y, int &width, int &height) const;
1525  const byte *ditherVGAtoEGA(int &pitch, int &x, int &y, int &width, int &height) const;
1526 
1527 public:
1528  VirtScreen *findVirtScreen(int y);
1529  byte *getMaskBuffer(int x, int y, int z);
1530 
1531 protected:
1532  void fadeIn(int effect);
1533  void fadeOut(int effect);
1534 
1535  void dissolveEffectSelector();
1536  void transitionEffect(int a);
1537  void dissolveEffect(int width, int height);
1538  void scrollEffect(int dir);
1539 
1540  void updateScreenShakeEffect();
1541 
1542 public:
1543  double getTimerFrequency();
1544  double getAmigaMusicTimerFrequency(); // For setting up Players v2 and v3
1545 
1546 protected:
1547  bool _shakeEnabled = false;
1548  bool _shakeTempSavedState = false; // For saving and restoring before and after GUI calls
1549  uint _shakeFrame = 0;
1550  uint32 _shakeNextTick = 0;
1551  uint32 _shakeTickCounter = 0;
1552  double _shakeTimerRate;
1553  double _timerFrequency;
1554 
1555  void setShake(int mode);
1556 
1557  int _drawObjectQueNr = 0;
1558  byte _drawObjectQue[200];
1559 
1560  /* For each of the 410 screen strips, gfxUsageBits contains a
1561  * bitmask. The lower 80 bits each correspond to one actor and
1562  * signify if any part of that actor is currently contained in
1563  * that strip.
1564  *
1565  * If the leftmost bit is set, the strip (background) is dirty
1566  * needs to be redrawn.
1567  *
1568  * The second leftmost bit is set by restoreBlastObjectsRect() and
1569  * restoreBackground(), but I'm not yet sure why.
1570  */
1571  uint32 gfxUsageBits[410 * 3];
1572 
1573  void upgradeGfxUsageBits();
1574  void setGfxUsageBit(int strip, int bit);
1575  void clearGfxUsageBit(int strip, int bit);
1576 
1577  // speed optimization: inline due to frequent calling
1578  bool testGfxUsageBit(int strip, int bit) {
1579  assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
1580  assert(1 <= bit && bit <= 96);
1581  bit--;
1582  return (gfxUsageBits[3 * strip + bit / 32] & (1 << (bit % 32))) != 0;
1583  }
1584 
1585  bool testGfxAnyUsageBits(int strip);
1586  bool testGfxObjectUsageBits(int strip); // Used for HE actors overlap calculations
1587  bool testGfxOtherUsageBits(int strip, int bit);
1588 
1589 public:
1590  byte _roomPalette[256];
1591  byte *_shadowPalette = nullptr;
1592  bool _skipDrawObject = 0;
1593  int _voiceMode = 0;
1594  int _soundEnabled = 0;
1595 
1596  // HE specific
1597  byte _HEV7ActorPalette[256];
1598  uint8 *_hePalettes = nullptr;
1599  uint16 _hePaletteSlot = 0;
1600  uint16 *_16BitPalette = nullptr;
1601 
1602  // Indy4 Amiga specific
1603  byte *_verbPalette = nullptr;
1604 
1605  ScummEngine_v0_Delays _V0Delay;
1606 
1607 protected:
1608  int _shadowPaletteSize = 0;
1609  byte _currentPalette[3 * 256];
1610  byte _darkenPalette[3 * 256];
1611  int _paletteChangedCounter = 1;
1612 
1613  int _palDirtyMin = 0, _palDirtyMax = 0;
1614 
1615  byte _palManipStart = 0, _palManipEnd = 0;
1616  uint16 _palManipCounter = 0;
1617  byte *_palManipPalette = nullptr;
1618  byte *_palManipIntermediatePal = nullptr;
1619 
1620  bool _haveActorSpeechMsg = false;
1621  bool _useTalkAnims = false;
1622  uint16 _defaultTextSpeed = 0;
1623  int _saveSound = 0;
1624  bool _native_mt32 = false;
1625  bool _copyProtection = false;
1626  bool _shadowPalRemap = false;
1627 
1628  // Indy4 Amiga specific
1629  uint16 _amigaFirstUsedColor = 0;
1630  byte _amigaPalette[3 * 64];
1631  void amigaPaletteFindFirstUsedColor();
1632  void mapRoomPalette(int idx);
1633  int remapRoomPaletteColor(int r, int g, int b);
1634  void mapVerbPalette(int idx);
1635  int remapVerbPaletteColor(int r, int g, int b);
1636 
1637  // EGA dithering mode color tables for certain VGA games like MI2, LOOM Talkie...
1638  byte *_egaColorMap[2];
1639 
1640 public:
1641  uint16 _extraBoxFlags[65];
1642 
1643  byte getNumBoxes();
1644  byte *getBoxMatrixBaseAddr();
1645  byte *getBoxConnectionBase(int box);
1646 
1647  int getNextBox(byte from, byte to);
1648 
1649  void setBoxFlags(int box, int val);
1650  void setBoxScale(int box, int b);
1651 
1652  bool checkXYInBoxBounds(int box, int x, int y);
1653 
1654  BoxCoords getBoxCoordinates(int boxnum);
1655 
1656  byte getMaskFromBox(int box);
1657  Box *getBoxBaseAddr(int box);
1658  byte getBoxFlags(int box);
1659  int getBoxScale(int box);
1660 
1661  int getScale(int box, int x, int y);
1662  int getScaleFromSlot(int slot, int x, int y);
1663 
1664 protected:
1665  // Scaling slots/items
1666  struct ScaleSlot {
1667  int x1, y1, scale1;
1668  int x2, y2, scale2;
1669  };
1670  friend void syncWithSerializer(Common::Serializer &, ScaleSlot &);
1671  ScaleSlot _scaleSlots[20];
1672  void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
1673  void setBoxScaleSlot(int box, int slot);
1674  void convertScaleTableToScaleSlot(int slot);
1675 
1676  void calcItineraryMatrix(byte *itineraryMatrix, int num);
1677  void createBoxMatrix();
1678  virtual bool areBoxesNeighbors(int i, int j);
1679 
1680  /* String class */
1681 public:
1682  CharsetRenderer *_charset = nullptr;
1683  byte _charsetColorMap[16];
1684 
1690  int _textSurfaceMultiplier = 0;
1691 
1692  bool _isModernMacVersion = false;
1693  bool _useGammaCorrection = true;
1694 
1695  Graphics::Surface *_macScreen = nullptr;
1696  MacGui *_macGui = nullptr;
1697  bool _useMacGraphicsSmoothing = true;
1698  byte _completeScreenBuffer[320 * 200];
1699 
1700 protected:
1701  byte _charsetColor = 0;
1702  byte _charsetData[23][16];
1703 
1704  int _charsetBufPos = 0;
1705  byte _charsetBuffer[512];
1706 
1707  bool _keepText = false;
1708  byte _msgCount = 0;
1709 
1710  int _nextLeft = 0, _nextTop = 0;
1711 
1712  Localizer *_localizer = nullptr;
1713 
1714 #ifdef USE_TTS
1715  bool _voiceNextString = false;
1716  bool _checkPreviousSaid = false;
1717  bool _voicePassHelpButtons = false;
1718  int _previousVerb = -1;
1719  int _previousControl = -1;
1720  Common::String _previousSaid;
1721  Common::String _passHelpButtons[6];
1722 #endif
1723 
1724  void restoreCharsetBg();
1725  void clearCharsetMask();
1726  void clearTextSurface();
1727 
1728  virtual void initCharset(int charset);
1729 
1730  virtual void printString(int m, const byte *msg);
1731 
1732  virtual bool handleNextCharsetCode(Actor *a, int *c);
1733  virtual void drawSentence() {}
1734  virtual void displayDialog();
1735  int countNumberOfWaits(); // For SE speech support, from disasm
1736  bool newLine();
1737  void drawString(int a, const byte *msg, Common::TextToSpeechManager::Action ttsAction = Common::TextToSpeechManager::QUEUE);
1738  virtual void fakeBidiString(byte *ltext, bool ignoreVerb, int ltextSize) const;
1739  void wrapSegaCDText();
1740  void debugMessage(const byte *msg);
1741  virtual void showMessageDialog(const byte *msg);
1742 
1743 #ifdef USE_TTS
1744  void sayText(const Common::String &text, Common::TextToSpeechManager::Action action = Common::TextToSpeechManager::QUEUE) const;
1745  void stopTextToSpeech() const;
1746  void sayButtonText();
1747 #endif
1748 
1749  virtual int convertMessageToString(const byte *msg, byte *dst, int dstSize);
1750  int convertIntMessage(byte *dst, int dstSize, int var);
1751  int convertVerbMessage(byte *dst, int dstSize, int var);
1752  int convertNameMessage(byte *dst, int dstSize, int var);
1753  int convertStringMessage(byte *dst, int dstSize, int var);
1754 
1755 public:
1756  Common::Language _language; // Accessed by a hack in NutRenderer::loadFont
1757 
1758  // Used by class ScummDialog:
1759  virtual void translateText(const byte *text, byte *trans_buff, int transBufferSize);
1760  // Old Hebrew games require reversing the dialog text.
1761  bool reverseIfNeeded(const byte *text, byte *reverseBuf, int reverseBufSize) const;
1762  // Returns codepage that matches the game for languages that require it.
1763  Common::CodePage getDialogCodePage() const;
1764 
1765  // Somewhat hackish stuff for 2 byte support (Chinese/Japanese/Korean)
1766  bool _useCJKMode = false;
1767  bool _useMultiFont = false;
1768  int _numLoadedFont = 0;
1769  int _2byteShadow = 0;
1770  bool _force2ByteCharHeight = false;
1771 
1772  int _2byteHeight = 0;
1773  int _2byteWidth = 0;
1774  int _krStrPost = 0;
1775  byte _newLineCharacter = 0;
1776  byte *get2byteCharPtr(int idx);
1777 
1778  bool isScummvmKorTarget();
1779  bool hasLocalizer();
1780 
1781 //protected:
1782  byte *_2byteFontPtr = nullptr;
1783  byte *_2byteMultiFontPtr[20];
1784  int _2byteMultiHeight[20];
1785  int _2byteMultiWidth[20];
1786  int _2byteMultiShadow[20];
1787 
1788 private:
1789  struct TranslatedLine {
1790  uint32 originalTextOffset;
1791  uint32 translatedTextOffset;
1792  };
1793 
1794  struct TranslationRange {
1795  uint32 left;
1796  uint32 right;
1797 
1798  TranslationRange(uint32 left_, uint32 right_) : left(left_), right(right_) {}
1799  TranslationRange() : left(0), right(0) {}
1800  };
1801 
1802  struct TranslationRoom {
1804  };
1805 
1806  bool _existLanguageFile = false;
1807  bool _isRTL = false;
1808  byte *_languageBuffer = nullptr;
1809  int _numTranslatedLines = 0;
1810  TranslatedLine *_translatedLines = nullptr;
1811  uint16 *_languageLineIndex = nullptr;
1813 
1814  const byte *searchTranslatedLine(const byte *text, const TranslationRange &range, bool useIndex);
1815 
1816  virtual void createTextRenderer(GlyphRenderer_v7 *gr) {}
1817 
1818 public:
1819 
1820  /* Scumm Vars */
1821  byte VAR_KEYPRESS = 0xFF;
1822  byte VAR_SYNC = 0xFF;
1823  byte VAR_EGO = 0xFF;
1824  byte VAR_CAMERA_POS_X = 0xFF;
1825  byte VAR_HAVE_MSG = 0xFF;
1826  byte VAR_ROOM = 0xFF;
1827  byte VAR_OVERRIDE = 0xFF;
1828  byte VAR_MACHINE_SPEED = 0xFF;
1829  byte VAR_ME = 0xFF;
1830  byte VAR_NUM_ACTOR = 0xFF;
1831  byte VAR_CURRENT_LIGHTS = 0xFF;
1832  byte VAR_CURRENTDRIVE = 0xFF; // How about merging this with VAR_CURRENTDISK?
1833  byte VAR_CURRENTDISK = 0xFF;
1834  byte VAR_TMR_1 = 0xFF;
1835  byte VAR_TMR_2 = 0xFF;
1836  byte VAR_TMR_3 = 0xFF;
1837  byte VAR_MUSIC_TIMER = 0xFF;
1838  byte VAR_ACTOR_RANGE_MIN = 0xFF;
1839  byte VAR_ACTOR_RANGE_MAX = 0xFF;
1840  byte VAR_CAMERA_MIN_X = 0xFF;
1841  byte VAR_CAMERA_MAX_X = 0xFF;
1842  byte VAR_TIMER_NEXT = 0xFF;
1843  byte VAR_VIRT_MOUSE_X = 0xFF;
1844  byte VAR_VIRT_MOUSE_Y = 0xFF;
1845  byte VAR_ROOM_RESOURCE = 0xFF;
1846  byte VAR_LAST_SOUND = 0xFF;
1847  byte VAR_CUTSCENEEXIT_KEY = 0xFF;
1848  byte VAR_OPTIONS_KEY = 0xFF;
1849  byte VAR_TALK_ACTOR = 0xFF;
1850  byte VAR_CAMERA_FAST_X = 0xFF;
1851  byte VAR_SCROLL_SCRIPT = 0xFF;
1852  byte VAR_ENTRY_SCRIPT = 0xFF;
1853  byte VAR_ENTRY_SCRIPT2 = 0xFF;
1854  byte VAR_EXIT_SCRIPT = 0xFF;
1855  byte VAR_EXIT_SCRIPT2 = 0xFF;
1856  byte VAR_VERB_SCRIPT = 0xFF;
1857  byte VAR_SENTENCE_SCRIPT = 0xFF;
1858  byte VAR_INVENTORY_SCRIPT = 0xFF;
1859  byte VAR_CUTSCENE_START_SCRIPT = 0xFF;
1860  byte VAR_CUTSCENE_END_SCRIPT = 0xFF;
1861  byte VAR_CHARINC = 0xFF;
1862  byte VAR_WALKTO_OBJ = 0xFF;
1863  byte VAR_DEBUGMODE = 0xFF;
1864  byte VAR_HEAPSPACE = 0xFF;
1865  byte VAR_RESTART_KEY = 0xFF;
1866  byte VAR_PAUSE_KEY = 0xFF;
1867  byte VAR_MOUSE_X = 0xFF;
1868  byte VAR_MOUSE_Y = 0xFF;
1869  byte VAR_TIMER = 0xFF;
1870  byte VAR_TIMER_TOTAL = 0xFF;
1871  byte VAR_SOUNDCARD = 0xFF;
1872  byte VAR_VIDEOMODE = 0xFF;
1873  byte VAR_MAINMENU_KEY = 0xFF;
1874  byte VAR_FIXEDDISK = 0xFF;
1875  byte VAR_CURSORSTATE = 0xFF;
1876  byte VAR_USERPUT = 0xFF;
1877  byte VAR_SOUNDRESULT = 0xFF;
1878  byte VAR_TALKSTOP_KEY = 0xFF;
1879  byte VAR_FADE_DELAY = 0xFF;
1880  byte VAR_NOSUBTITLES = 0xFF;
1881 
1882  // V5+
1883  byte VAR_SOUNDPARAM = 0xFF;
1884  byte VAR_SOUNDPARAM2 = 0xFF;
1885  byte VAR_SOUNDPARAM3 = 0xFF;
1886  byte VAR_INPUTMODE = 0xFF;
1887  byte VAR_MEMORY_PERFORMANCE = 0xFF;
1888  byte VAR_VIDEO_PERFORMANCE = 0xFF;
1889  byte VAR_ROOM_FLAG = 0xFF;
1890  byte VAR_GAME_LOADED = 0xFF;
1891  byte VAR_NEW_ROOM = 0xFF;
1892 
1893  // V4/V5
1894  byte VAR_V5_TALK_STRING_Y = 0xFF;
1895 
1896  // V6+
1897  byte VAR_ROOM_WIDTH = 0xFF;
1898  byte VAR_ROOM_HEIGHT = 0xFF;
1899  byte VAR_SUBTITLES = 0xFF;
1900  byte VAR_V6_EMSSPACE = 0xFF;
1901 
1902  // V7/V8 specific variables
1903  byte VAR_CAMERA_POS_Y = 0xFF;
1904  byte VAR_CAMERA_MIN_Y = 0xFF;
1905  byte VAR_CAMERA_MAX_Y = 0xFF;
1906  byte VAR_CAMERA_THRESHOLD_X = 0xFF;
1907  byte VAR_CAMERA_THRESHOLD_Y = 0xFF;
1908  byte VAR_CAMERA_SPEED_X = 0xFF;
1909  byte VAR_CAMERA_SPEED_Y = 0xFF;
1910  byte VAR_CAMERA_ACCEL_X = 0xFF;
1911  byte VAR_CAMERA_ACCEL_Y = 0xFF;
1912  byte VAR_CAMERA_DEST_X = 0xFF;
1913  byte VAR_CAMERA_DEST_Y = 0xFF;
1914  byte VAR_CAMERA_FOLLOWED_ACTOR = 0xFF;
1915 
1916  // V7/V8 specific variables
1917  byte VAR_VERSION_KEY = 0xFF;
1918  byte VAR_DEFAULT_TALK_DELAY = 0xFF;
1919  byte VAR_CUSTOMSCALETABLE = 0xFF;
1920  byte VAR_BLAST_ABOVE_TEXT = 0xFF;
1921  byte VAR_VOICE_MODE = 0xFF;
1922  byte VAR_MUSIC_BUNDLE_LOADED = 0xFF;
1923  byte VAR_VOICE_BUNDLE_LOADED = 0xFF;
1924 
1925  byte VAR_LEFTBTN_DOWN = 0xFF; // V7/V8
1926  byte VAR_RIGHTBTN_DOWN = 0xFF; // V7/V8
1927  byte VAR_LEFTBTN_HOLD = 0xFF; // V6/V72HE/V7/V8
1928  byte VAR_RIGHTBTN_HOLD = 0xFF; // V6/V72HE/V7/V8
1929  byte VAR_PRE_SAVELOAD_SCRIPT = 0xFF; // V6/V7 (not HE)
1930  byte VAR_POST_SAVELOAD_SCRIPT = 0xFF; // V6/V7 (not HE)
1931  byte VAR_SAVELOAD_PAGE = 0xFF; // V8
1932  byte VAR_OBJECT_LABEL_FLAG = 0xFF; // V8
1933 
1934  // V6/V7 specific variables (FT & Sam & Max specific)
1935  byte VAR_CHARSET_MASK = 0xFF;
1936 
1937  // V6 specific variables
1938  byte VAR_V6_SOUNDMODE = 0xFF;
1939 
1940  // V1/V2 specific variables
1941  byte VAR_CHARCOUNT = 0xFF;
1942  byte VAR_VERB_ALLOWED = 0xFF;
1943  byte VAR_ACTIVE_VERB = 0xFF;
1944  byte VAR_ACTIVE_OBJECT1 = 0xFF;
1945  byte VAR_ACTIVE_OBJECT2 = 0xFF;
1946 
1947  // HE specific variables
1948  byte VAR_ALWAYS_REDRAW_ACTORS = 0xFF; // Used in setActorRedrawFlags()
1949  byte VAR_SKIP_RESET_TALK_ACTOR = 0xFF; // Used in setActorCostume()
1950 
1951  byte VAR_SOUND_CHANNEL = 0xFF; // Used in o_startSound()
1952  byte VAR_TALK_CHANNEL = 0xFF; // Used in playVoice()
1953  byte VAR_SOUND_TOKEN_OFFSET = 0xFF; // Used in handleSoundFrame()
1954  byte VAR_START_DYN_SOUND_CHANNELS = 0xFF; // Used in getNextDynamicChannel()
1955  byte VAR_SOUND_CALLBACK_SCRIPT = 0xFF;
1956 
1957  byte VAR_EARLY_TALKIE_CALLBACK = 0xFF;
1958  byte VAR_EARLY_CHAN_0_CALLBACK = 0xFF;
1959  byte VAR_EARLY_CHAN_1_CALLBACK = 0xFF;
1960  byte VAR_EARLY_CHAN_2_CALLBACK = 0xFF;
1961  byte VAR_EARLY_CHAN_3_CALLBACK = 0xFF;
1962 
1963  byte VAR_MAIN_SCRIPT = 0xFF; // Used in scummLoop()
1964 
1965  byte VAR_DEFAULT_SCRIPT_PRIORITY = 0xFF; // Used in runScript()/runObjectScript()
1966  byte VAR_LAST_SCRIPT_PRIORITY = 0xFF; // Used in runAllScripts()
1967 
1968  byte VAR_QUIT_SCRIPT = 0xFF; // Used in confirmExitDialog()
1969  byte VAR_ERROR_FLAG = 0xFF; // HE70-90
1970  byte VAR_OPERATION_FAILURE = 0xFF; // HE99+
1971 
1972  byte VAR_COLOR_BLACK = 0xFF;
1973 
1974  // Exists both in V7 and in V72HE:
1975  byte VAR_NUM_GLOBAL_OBJS = 0xFF;
1976 
1977  byte VAR_LAST_FRAME_BURN_TIME = 0xFF; // HE90+
1978  byte VAR_LAST_FRAME_SCUMM_TIME = 0xFF; // HE90+
1979 
1980  byte VAR_WINDEX_RUNNING = 0xFF;
1981 
1982 #ifdef USE_RGB_COLOR
1983  // FM-Towns / PC-Engine specific
1984  Graphics::FontSJIS *_cjkFont = nullptr;
1985 #endif
1986 
1987  // FM-Towns specific
1988 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
1989 public:
1990  bool towns_isRectInStringBox(int x1, int y1, int x2, int y2);
1991  byte _townsPaletteFlags = 0;
1992  byte _townsCharsetColorMap[16];
1993 
1994 protected:
1995  void towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, int srcX, int srcY, int w, int h);
1996  void towns_fillTopLayerRect(int x1, int y1, int x2, int y2, int col);
1997  void towns_swapVirtScreenArea(VirtScreen *vs, int x, int y, int w, int h);
1998  void towns_clearStrip(int strip);
1999 #ifdef USE_RGB_COLOR
2000  void towns_setPaletteFromPtr(const byte *ptr, int numcolor = -1);
2001  void towns_setTextPaletteFromPtr(const byte *ptr);
2002 #endif
2003  void towns_setupPalCycleField(int x1, int y1, int x2, int y2);
2004  void towns_processPalCycleField();
2005  void towns_resetPalCycleFields();
2006  void towns_restoreCharsetBg();
2007  void towns_scriptScrollEffect(int dir);
2008 
2009  void requestScroll(int dir);
2010  void scrollLeft() { requestScroll(-1); }
2011  void scrollRight() { requestScroll(1); }
2012  void towns_waitForScroll(int waitForDirection, int threshold = 0);
2013  void towns_updateGfx();
2014 
2015  Common::Rect _cyclRects[10];
2016  int _numCyclRects = 0;
2017  int _scrollRequest = 0;
2018  int _scrollDeltaAdjust = 0;
2019  bool _scrollNeedDeltaAdjust = 0;
2020  int _refreshDuration[20];
2021  int _refreshArrayPos = 0;
2022  bool _refreshNeedCatchUp = false;
2023  bool _enableSmoothScrolling = false;
2024  bool _forceFMTownsHiResMode = false;
2025  uint32 _scrollTimer = 0;
2026  uint32 _scrollDestOffset = 0;
2027  uint16 _scrollFeedStrips[3];
2028 
2029  Common::Rect _curStringRect;
2030 
2031  byte _townsOverrideShadowColor = 0;
2032  byte _textPalette[48];
2033  byte _townsClearLayerFlag = 1;
2034  byte _townsActiveLayerFlags = 3;
2035  static const uint8 _townsLayer2Mask[];
2036 
2037  TownsScreen *_townsScreen = nullptr;
2038 #else
2039  void scrollLeft() { redrawBGStrip(_gdi->_numStrips - 1, 1); }
2040  void scrollRight() { redrawBGStrip(0, 1); }
2041  void towns_updateGfx() {}
2042  void towns_waitForScroll(int waitForDirection, int threshold = 0) {}
2043  void towns_fillTopLayerRect(int x1, int y1, int x2, int y2, int col) {}
2044  void towns_swapVirtScreenArea(VirtScreen *vs, int x, int y, int w, int h) {}
2045 #endif // DISABLE_TOWNS_DUAL_LAYER_MODE
2046 };
2047 
2048 } // End of namespace Scumm
2049 
2050 #endif
#define ARRAYSIZE(x)
Definition: util.h:114
Definition: editor.h:49
Definition: charset.h:70
Definition: macgui_impl.h:52
Definition: keymap.h:66
VirtScreenNumber
Definition: gfx.h:161
Definition: gfx.h:563
Definition: str.h:59
Definition: boxes.h:44
Definition: surface.h:67
EngineFeature
Definition: engine.h:282
Definition: stream.h:77
Definition: error.h:81
T left
Definition: rect.h:170
ErrorCode getCode() const
Definition: error.h:112
Definition: detection.h:125
Definition: script.h:31
Definition: gfx.h:138
Definition: pixelformat.h:138
Definition: macgui_v6.h:33
Definition: script.h:128
Definition: scumm.h:152
Definition: random.h:44
Definition: palette.h:195
RenderMode
Definition: rendermode.h:48
No error occurred.
Definition: error.h:48
Definition: rect.h:536
Definition: scumm.h:143
Common::Path _containerFile
Definition: scumm.h:1145
Definition: path.h:52
Definition: scumm.h:171
Definition: resource.h:80
Definition: music.h:40
ResType
Definition: scumm.h:243
Definition: stream.h:745
Definition: macgui_indy3.h:39
Definition: sound.h:59
Definition: printman.h:30
void void void void void debugC(int level, uint32 debugChannel, MSVC_PRINTF const char *s,...) GCC_PRINTF(3
Definition: serializer.h:80
Definition: scumm.h:163
Definition: scumm.h:524
Definition: gfx.h:185
Graphics::Surface _textSurface
Definition: scumm.h:1689
Definition: scumm.h:184
int FORCEINLINE GCC_PRINTF(2, 0) int vsprintf_s(T(&dst)[N]
Definition: detection.h:52
T right
Definition: rect.h:171
Definition: scumm.h:136
Definition: hashmap.h:85
Definition: ustr.h:57
bool currentScriptSlotIs(uint16 script) const
Definition: scumm.h:1064
Definition: scumm.h:219
Definition: player_towns.h:32
Definition: scumm.h:201
Definition: debugger.h:33
Definition: object.h:189
Definition: object.h:64
Definition: imuse.h:50
Definition: events.h:218
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: mutex.h:67
Definition: rect.h:144
Definition: macgui_v5.h:33
Definition: serializer.h:352
Definition: charset.h:159
Definition: scumm.h:468
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: actor.h:100
Definition: localizer.h:31
Definition: dialog.h:49
Definition: gfx.h:292
Definition: stream.h:351
Definition: base-costume.h:68
Definition: scumm.h:1666
Definition: macgui.h:39
Definition: keyboard.h:294
Definition: serializer.h:33
Common::Error run() override
Definition: scumm.h:588
Common::RandomSource _rnd
Definition: scumm.h:556
Definition: macgui_loom.h:33
Definition: system.h:166
Definition: base-costume.h:49
Definition: scumm.h:853
Definition: engine.h:149
Definition: actor.h:30
Definition: gfx.h:279
Definition: verbs.h:47
Definition: detection.h:139
Definition: file.h:36
Language
Definition: language.h:45