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