ScummVM API documentation
agi.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 AGI_AGI_H
23 #define AGI_AGI_H
24 
25 #include "common/scummsys.h"
26 #include "common/error.h"
27 #include "common/util.h"
28 #include "common/file.h"
29 #include "common/keyboard.h"
30 #include "common/rect.h"
31 #include "common/rendermode.h"
32 #include "common/stack.h"
33 #include "common/str.h"
34 #include "common/system.h"
35 #include "common/text-to-speech.h"
36 
37 #include "engines/engine.h"
38 
39 #include "gui/debugger.h"
40 
41 // AGI resources
42 #include "agi/console.h"
43 #include "agi/view.h"
44 #include "agi/picture.h"
45 #include "agi/logic.h"
46 #include "agi/sound.h"
47 
48 namespace Common {
49 class RandomSource;
50 }
51 
64 namespace Agi {
65 
66 #define TITLE "AGI engine"
67 
68 #define DIR_ "dir"
69 #define LOGDIR "logdir"
70 #define PICDIR "picdir"
71 #define VIEWDIR "viewdir"
72 #define SNDDIR "snddir"
73 #define OBJECTS "object"
74 #define WORDS "words.tok"
75 
76 #define MAX_DIRECTORY_ENTRIES 256
77 #define MAX_CONTROLLERS 256
78 #define MAX_VARS 256
79 #define MAX_FLAGS (256 >> 3)
80 #define SCREENOBJECTS_MAX 255 // KQ3 uses o255!
81 #define SCREENOBJECTS_EGO_ENTRY 0 // first entry is ego
82 #define MAX_WORDS 20
83 #define MAX_STRINGS 24 // MAX_STRINGS + 1 used for get.num
84 #define MAX_STRINGLEN 40
85 #define MAX_CONTROLLER_KEYMAPPINGS 39
86 
87 #define SAVEDGAME_DESCRIPTION_LEN 30
88 
89 #define _EMPTY 0xfffff
90 #define EGO_OWNED 0xff
91 #define EGO_OWNED_V1 0xf9
92 
93 #define CRYPT_KEY_SIERRA "Avis Durgan"
94 #define CRYPT_KEY_AGDS "Alex Simkin"
95 
96 #define ADD_PIC 1
97 #define ADD_VIEW 2
98 
99 #define CMD_BSIZE 12
100 
101 enum AgiGameType {
102  GType_PreAGI = 0,
103  GType_V1 = 1,
104  GType_V2 = 2,
105  GType_V3 = 3,
106  GType_A2 = 4,
107  GType_GAL = 5
108 };
109 
110 enum AgiGameFeatures {
111  GF_AGIMOUSE = (1 << 0), // marks games created with AGIMOUSE, disables "Click-to-walk mouse interface"
112  GF_AGDS = (1 << 1), // marks games created with AGDS - all using AGI version 2.440
113  GF_AGI256 = (1 << 2), // marks fanmade AGI-256 games
114  GF_FANMADE = (1 << 3), // marks fanmade games
115  GF_2GSOLDSOUND = (1 << 5),
116  GF_EXTCHAR = (1 << 6) // use WORDS.TOK.EXTENDED
117 };
118 
119 enum AgiGameID {
120  GID_AGIDEMO,
121  GID_BC,
122  GID_DDP,
123  GID_GOLDRUSH, // V3
124  GID_KQ1,
125  GID_KQ2,
126  GID_KQ3,
127  GID_KQ4,
128  GID_LSL1,
129  GID_MH1, // V3
130  GID_MH2, // V3
131  GID_MIXEDUP,
132  GID_PQ1,
133  GID_SQ1,
134  GID_SQ2,
135  GID_XMASCARD,
136  GID_FANMADE,
137  GID_GETOUTTASQ, // Fanmade
138  GID_MICKEY, // PreAGI
139  GID_WINNIE, // PreAGI
140  GID_TROLL // PreAGI
141 };
142 
143 enum AGIErrors {
144  errOK = 0,
145  errFilesNotFound,
146  errBadFileOpen,
147  errNotEnoughMemory,
148  errBadResource,
149  errIOError,
150 
151  errUnk = 127
152 };
153 
154 enum kDebugLevels {
155  kDebugLevelMain = 1,
156  kDebugLevelResources,
157  kDebugLevelSprites,
158  kDebugLevelPictures,
159  kDebugLevelInventory,
160  kDebugLevelInput,
161  kDebugLevelMenu,
162  kDebugLevelScripts,
163  kDebugLevelSound,
164  kDebugLevelText,
165  kDebugLevelSavegame,
166 };
167 
171 enum {
172  RESOURCETYPE_LOGIC = 1,
173  RESOURCETYPE_SOUND,
174  RESOURCETYPE_VIEW,
175  RESOURCETYPE_PICTURE
176 };
177 
178 enum {
179  RES_LOADED = 0x01,
180  RES_COMPRESSED = 0x40,
181  RES_PICTURE_V3_NIBBLE_PARM = 0x80 // Flag that gets set for picture resources,
182  // which use a nibble instead of a byte as F0+F2 parameters
183 };
184 
185 enum {
186  lCOMMAND_MODE = 1,
187  lTEST_MODE
188 };
189 
190 struct gameIdList {
191  gameIdList *next;
192  uint32 version;
193  uint32 crc;
194  char *gName;
195  char *switches;
196 };
197 
198 struct Mouse {
199  int button;
200  Common::Point pos;
201 
202  Mouse() : button(0) {}
203 };
204 
205 // Used by AGI Mouse protocol 1.0 for v27 (i.e. button pressed -variable).
206 enum AgiMouseButton {
207  kAgiMouseButtonUp, // Mouse button is up (not pressed)
208  kAgiMouseButtonLeft, // Left mouse button
209  kAgiMouseButtonRight, // Right mouse button
210  kAgiMouseButtonMiddle // Middle mouse button
211 };
212 
216 enum {
217  VM_VAR_CURRENT_ROOM = 0, // 0
218  VM_VAR_PREVIOUS_ROOM, // 1
219  VM_VAR_BORDER_TOUCH_EGO, // 2
220  VM_VAR_SCORE, // 3
221  VM_VAR_BORDER_CODE, // 4
222  VM_VAR_BORDER_TOUCH_OBJECT, // 5
223  VM_VAR_EGO_DIRECTION, // 6
224  VM_VAR_MAX_SCORE, // 7
225  VM_VAR_FREE_PAGES, // 8
226  VM_VAR_WORD_NOT_FOUND, // 9
227  VM_VAR_TIME_DELAY, // 10
228  VM_VAR_SECONDS, // 11
229  VM_VAR_MINUTES, // 12
230  VM_VAR_HOURS, // 13
231  VM_VAR_DAYS, // 14
232  VM_VAR_JOYSTICK_SENSITIVITY, // 15
233  VM_VAR_EGO_VIEW_RESOURCE, // 16
234  VM_VAR_AGI_ERROR_CODE, // 17
235  VM_VAR_AGI_ERROR_INFO, // 18
236  VM_VAR_KEY, // 19
237  VM_VAR_COMPUTER, // 20
238  VM_VAR_WINDOW_AUTO_CLOSE_TIMER, // 21
239  VM_VAR_SOUNDGENERATOR, // 22
240  VM_VAR_VOLUME, // 23
241  VM_VAR_MAX_INPUT_CHARACTERS, // 24
242  VM_VAR_SELECTED_INVENTORY_ITEM, // 25
243  VM_VAR_MONITOR = 26, // 26
244  VM_VAR_MOUSE_BUTTONSTATE = 27, // 27
245  VM_VAR_MOUSE_X = 28, // 28
246  VM_VAR_MOUSE_Y = 29 // 29
247 };
248 
254  kAgiMonitorCga = 0,
255  //kAgiMonitorTandy = 1, // Not sure about this
256  kAgiMonitorHercules = 2,
257  kAgiMonitorEga = 3
258  //kAgiMonitorVga = 4 // Not sure about this
259 };
260 
266  kAgiComputerPC = 0,
267  kAgiComputerApple2 = 3,
268  kAgiComputerAtariST = 4,
269  kAgiComputerAmiga = 5,
270  kAgiComputerApple2GS = 7
271 };
272 
273 enum AgiSoundType {
274  kAgiSoundPC = 1,
275  kAgiSoundTandy = 3, // Tandy (This value is also used by the Amiga AGI and Apple IIGS AGI)
276  kAgiSound2GSOld = 8 // Apple IIGS's Gold Rush! (Version 1.0M 1989-02-28 (CE), AGI 3.003) uses value 8
277 };
278 
282 enum {
283  VM_FLAG_EGO_WATER = 0, // 0
284  VM_FLAG_EGO_INVISIBLE,
285  VM_FLAG_ENTERED_CLI,
286  VM_FLAG_EGO_TOUCHED_P2,
287  VM_FLAG_SAID_ACCEPTED_INPUT,
288  VM_FLAG_NEW_ROOM_EXEC, // 5
289  VM_FLAG_RESTART_GAME,
290  VM_FLAG_SCRIPT_BLOCKED,
291  VM_FLAG_JOY_SENSITIVITY,
292  VM_FLAG_SOUND_ON,
293  VM_FLAG_DEBUGGER_ON, // 10
294  VM_FLAG_LOGIC_ZERO_FIRST_TIME,
295  VM_FLAG_RESTORE_JUST_RAN,
296  VM_FLAG_STATUS_SELECTS_ITEMS,
297  VM_FLAG_MENUS_ACCESSIBLE,
298  VM_FLAG_OUTPUT_MODE, // 15
299  VM_FLAG_AUTO_RESTART
300 };
301 
303  uint16 keycode;
304  byte controllerSlot;
305 
306  AgiControllerKeyMapping() : keycode(0), controllerSlot(0) {}
307 };
308 
309 struct AgiObject {
310  int location;
311  Common::String name;
312 };
313 
314 struct AgiDir {
315  uint8 volume;
316  uint32 offset;
317  uint32 len;
318  uint32 clen;
319 
320  // 0 = not in mem, can be freed
321  // 1 = in mem, can be released
322  // 2 = not in mem, can't be released
323  // 3 = in mem, can't be released
324  // 0x40 = was compressed
325  uint8 flags;
326 
327  void reset() {
328  volume = 0xff;
329  offset = _EMPTY;
330  len = 0;
331  clen = 0;
332  flags = 0;
333  }
334 
335  AgiDir() { reset(); }
336 };
337 
338 struct AgiBlock {
339  bool active;
340  int16 x1, y1;
341  int16 x2, y2;
342 
343  AgiBlock() : active(false), x1(0), y1(0), x2(0), y2(0) {}
344 };
345 
346 struct ScriptPos {
347  int script;
348  int curIP;
349 };
350 
351 enum CycleInnerLoopType {
352  CYCLE_INNERLOOP_GETSTRING = 0,
353  CYCLE_INNERLOOP_GETNUMBER,
354  CYCLE_INNERLOOP_INVENTORY,
355  CYCLE_INNERLOOP_MENU_VIA_KEYBOARD,
356  CYCLE_INNERLOOP_MENU_VIA_MOUSE,
357  CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT,
358  CYCLE_INNERLOOP_SYSTEMUI_VERIFICATION,
359  CYCLE_INNERLOOP_MESSAGEBOX,
360  CYCLE_INNERLOOP_HAVEKEY
361 };
362 
364 
366 
372 struct AgiGame {
373  AgiEngine *_vm;
374 
375  // TODO: Check whether adjMouseX and adjMouseY must be saved and loaded when using savegames.
376  // If they must be then loading and saving is partially broken at the moment.
377  int adjMouseX;
378  int adjMouseY;
380  char id[8];
381  uint32 crc;
383  // game flags and variables
384  uint8 flags[MAX_FLAGS];
385  uint8 vars[MAX_VARS];
387  // internal variables
388  int16 horizon;
390  bool cycleInnerLoopActive;
391  int16 cycleInnerLoopType;
392 
393  int16 curLogicNr;
394  Common::Array<ScriptPos> execStack;
395 
396  // internal flags
401  // windows
402  AgiBlock block;
403 
404  // graphics & text
405  bool gfxMode;
406 
407  unsigned int numObjects;
408 
409  bool controllerOccurred[MAX_CONTROLLERS];
410  AgiControllerKeyMapping controllerKeyMapping[MAX_CONTROLLER_KEYMAPPINGS];
411 
412  char strings[MAX_STRINGS + 1][MAX_STRINGLEN];
414  // directory entries for resources
415  AgiDir dirLogic[MAX_DIRECTORY_ENTRIES];
416  AgiDir dirPic[MAX_DIRECTORY_ENTRIES];
417  AgiDir dirView[MAX_DIRECTORY_ENTRIES];
418  AgiDir dirSound[MAX_DIRECTORY_ENTRIES];
419 
420  // resources
421  AgiPicture pictures[MAX_DIRECTORY_ENTRIES];
422  AgiLogic logics[MAX_DIRECTORY_ENTRIES];
423  AgiView views[MAX_DIRECTORY_ENTRIES];
424  AgiSound *sounds[MAX_DIRECTORY_ENTRIES];
426  AgiLogic *_curLogic;
427 
428  // view table
429  ScreenObjEntry screenObjTable[SCREENOBJECTS_MAX];
430 
431  ScreenObjEntry addToPicView;
432 
434  char automaticSaveDescription[SAVEDGAME_DESCRIPTION_LEN + 1];
435 
438  bool mouseHidden;
441  // IF condition handling
442  bool testResult;
443 
444  int max_logics;
445  int logic_list[256];
446 
447  // used to detect situations, where the game shows some text and changes rooms right afterwards
448  // for example Space Quest 2 intro right at the start
449  // or Space Quest 2, when entering the vent also right at the start
450  // The developers assumed that loading the new room would take a bit.
451  // In ScummVM it's basically done in an instant, which means that
452  // the text would only get shown for a split second.
453  // We delay a bit as soon as such situations get detected.
454  bool nonBlockingTextShown;
455  int16 nonBlockingTextCyclesLeft;
456 
457  bool automaticRestoreGame;
458 
459  byte speedLevel;
461  uint16 appleIIgsSpeedControllerSlot;
462 
463  const char *getString(int number);
464  void setString(int number, const char *str);
468  void setSpeedLevel(byte s);
469 
470  AgiGame() {
471  _vm = nullptr;
472 
473  adjMouseX = 0;
474  adjMouseY = 0;
475 
476  memset(id, 0, sizeof(id));
477  crc = 0;
478  memset(flags, 0, sizeof(flags));
479  memset(vars, 0, sizeof(vars));
480 
481  horizon = 0;
482 
483  cycleInnerLoopActive = false;
484  cycleInnerLoopType = 0;
485 
486  curLogicNr = 0;
487 
488  // execStack is defaulted by Common::Array constructor
489 
490  playerControl = false;
491  exitAllLogics = false;
492  pictureShown = false;
493 
494  // block defaulted by AgiBlock constructor
495 
496  gfxMode = false;
497 
498  numObjects = 0;
499 
500  memset(controllerOccurred, 0, sizeof(controllerOccurred));
501 
502  // controllerKeyMapping defaulted by AgiControllerKeyMapping constructor
503 
504  memset(strings, 0, sizeof(strings));
505 
506  // dirLogic cleared by AgiDir constructor
507  // dirPic cleared by AgiDir constructor
508  // dirView cleared by AgiDir constructor
509  // dirSound cleared by AgiDir constructor
510 
511  // pictures cleared by AgiPicture constructor
512  // logics cleared by AgiLogic constructor
513  // views cleared by AgiView constructor
514  memset(sounds, 0, sizeof(sounds));
515 
516  _curLogic = nullptr;
517 
518  // screenObjTable cleared by ScreenObjEntry constructor
519 
520  // addToPicView cleared by ScreenObjEntry constructor
521 
522  automaticSave = false;
523  memset(automaticSaveDescription, 0, sizeof(automaticSaveDescription));
524 
525  // mouseFence cleared by Common::Rect constructor
526  mouseEnabled = false;
527  mouseHidden = false;
528  predictiveDlgOnMouseClick = false;
529 
530  testResult = false;
531 
532  max_logics = 0;
533  memset(logic_list, 0, sizeof(logic_list));
534 
535  nonBlockingTextShown = false;
536  nonBlockingTextCyclesLeft = 0;
537 
538  automaticRestoreGame = false;
539 
540  speedLevel = 2; // normal speed
541 
542  appleIIgsSpeedControllerSlot = 0xffff; // we didn't add yet speed menu
543  }
544 };
545 
546 class AgiLoader;
547 class GfxFont;
548 class GfxMgr;
549 class SpritesMgr;
550 class InventoryMgr;
551 class TextMgr;
552 class GfxMenu;
553 class SystemUI;
554 class Words;
555 struct AGIGameDescription;
556 
557 // Image stack support
559  uint8 type;
560  uint8 pad;
561  int16 parm1;
562  int16 parm2;
563  int16 parm3;
564  int16 parm4;
565  int16 parm5;
566  int16 parm6;
567  int16 parm7;
568 };
569 
570 #define TICK_SECONDS 20
571 
572 #define KEY_QUEUE_SIZE 16
573 
574 class AgiBase : public ::Engine {
575 protected:
576  // Engine API
577  Common::Error init();
578  virtual Common::Error go() = 0;
579  Common::Error run() override {
580  Common::Error err;
581  err = init();
582  if (err.getCode() != Common::kNoError)
583  return err;
584  return go();
585  }
586  bool hasFeature(EngineFeature f) const override;
587 
588  virtual void initialize() = 0;
589 
590  void initRenderMode();
591 
592 public:
593  Words *_words;
594 
595  GfxFont *_font;
596  GfxMgr *_gfx;
597 
598  Common::RenderMode _renderMode;
599  AgiDebug _debug;
600  AgiGame _game;
601  Common::RandomSource *_rnd;
602 
603  SoundMgr *_sound;
604 
605  Mouse _mouse;
606 
607  bool _noSaveLoadAllowed;
608 
609  virtual bool promptIsEnabled() {
610  return false;
611  }
612 
613  virtual int getKeypress() = 0;
614  virtual bool isKeypress() = 0;
615  virtual void clearKeyQueue() = 0;
616 
617  AgiBase(OSystem *syst, const AGIGameDescription *gameDesc);
618  ~AgiBase() override;
619 
620  virtual void clearImageStack() = 0;
621  virtual void recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
622  int16 p4, int16 p5, int16 p6, int16 p7) = 0;
623  virtual void replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
624  int16 p4, int16 p5, int16 p6, int16 p7) = 0;
625  virtual void releaseImageStack() = 0;
626 
627  int _soundemu;
628 
629  bool getFlag(int16 flagNr);
630  void setFlag(int16 flagNr, bool newState);
631  void flipFlag(int16 flagNr);
633  void setFlagOrVar(int16 flagNr, bool newState);
634 
635  const AGIGameDescription *_gameDescription;
636 
637  uint32 _gameFeatures;
638  uint16 _gameVersion;
639 
640  uint32 getGameID() const;
641  uint32 getFeatures() const;
642  uint16 getVersion() const;
643  uint16 getGameType() const;
644  Common::Language getLanguage() const;
645  bool isLanguageRTL() const;
646  Common::Platform getPlatform() const;
647  const char *getGameMD5() const;
648  void initFeatures();
649  void initVersion();
650 
651  const char *getDiskName(uint16 id);
652 
653  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
654  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
655 
656  const byte *getFontData();
657 
658  void cycleInnerLoopActive(int16 loopType) {
659  _game.cycleInnerLoopActive = true;
660  _game.cycleInnerLoopType = loopType;
661  };
662  void cycleInnerLoopInactive() {
663  _game.cycleInnerLoopActive = false;
664  };
665  bool cycleInnerLoopIsActive() {
666  return _game.cycleInnerLoopActive;
667  }
668 };
669 
670 enum AgiArtificialDelayTriggerType {
671  ARTIFICIALDELAYTYPE_NEWROOM = 0,
672  ARTIFICIALDELAYTYPE_NEWPICTURE = 1,
673  ARTIFICIALDELAYTYPE_END = -1
674 };
675 
677  uint32 gameId;
678  Common::Platform platform;
679  AgiArtificialDelayTriggerType triggerType;
680  int16 orgNr;
681  int16 newNr;
682  uint16 millisecondsDelay;
683 };
684 
685 typedef void (*AgiOpCodeFunction)(AgiGame *state, AgiEngine *vm, uint8 *p);
686 
688  const char *name;
689  const char *parameters;
690  AgiOpCodeFunction functionPtr;
691  uint16 parameterSize;
692 };
693 
695  const char *name;
696  const char *parameters;
697  AgiOpCodeFunction functionPtr;
698 };
699 
700 class AgiEngine : public AgiBase {
701 protected:
702  // Engine APIs
703  Common::Error go() override;
704 
705  void initialize() override;
706 
707 public:
708  AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc);
709  ~AgiEngine() override;
710 
711  bool promptIsEnabled() override;
712 
713  Common::Error loadGameState(int slot) override;
714  Common::Error saveGameState(int slot, const Common::String &description, bool isAutosave = false) override;
715 
716 private:
717  int _keyQueue[KEY_QUEUE_SIZE];
718  int _keyQueueStart;
719  int _keyQueueEnd;
720 
721  bool _allowSynthetic;
722 
723  bool checkPriority(ScreenObjEntry *v);
724  bool checkCollision(ScreenObjEntry *v);
725  bool checkPosition(ScreenObjEntry *v);
726 
727  int _firstSlot;
728 
729 public:
730  Common::Array<AgiObject> _objects; // objects in the game
731 
732  SavedGameSlotIdArray getSavegameSlotIds();
733  bool getSavegameInformation(int16 slotId, Common::String &saveDescription, uint32 &saveDate, uint32 &saveTime, bool &saveIsValid);
734 
735  int saveGame(const Common::String &fileName, const Common::String &descriptionString);
736  int loadGame(const Common::String &fileName, bool checkId = true);
737  bool saveGameDialog();
738  bool saveGameAutomatic();
739  bool loadGameDialog();
740  bool loadGameAutomatic();
741  int doSave(int slot, const Common::String &desc);
742  int doLoad(int slot, bool showMessages);
743  int scummVMSaveLoadDialog(bool isSave);
744 
745  uint8 *_intobj;
746  bool _restartGame;
747 
748  SpritesMgr *_sprites;
749  TextMgr *_text;
750  InventoryMgr *_inventory;
751  PictureMgr *_picture;
752  AgiLoader *_loader;
753  GfxMenu *_menu;
754  SystemUI *_systemUI;
755  Common::DumpFile *_logFile; // File used for the log() agi command.
756 
758 
759 #ifdef USE_TTS
760  int16 _previousDisplayRow;
761  Common::String _combinedText;
762  Common::String _previousSaid;
763  bool _queueNextText;
764  bool _voiceClock;
765  bool _replaceDisplayNewlines;
766  Common::CodePage _ttsEncoding;
767 #endif
768 
769  void clearImageStack() override;
770  void recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
771  int16 p4, int16 p5, int16 p6, int16 p7) override;
772  void replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
773  int16 p4, int16 p5, int16 p6, int16 p7) override;
774  void releaseImageStack() override;
775 
776  void wait(uint32 msec, bool busy = false);
777 
778  int agiInit();
779  void agiDeinit();
780  int loadResource(int16 resourceType, int16 resourceNr);
781  void unloadResource(int16 resourceType, int16 resourceNr);
785  void unloadResources();
786 
787  int getKeypress() override;
788  bool isKeypress() override;
789  void clearKeyQueue() override;
790 
791  byte getVar(int16 varNr);
792  void setVar(int16 varNr, byte newValue);
793 
794 private:
795  void applyVolumeToMixer();
796 
797 public:
798  void syncSoundSettings() override;
799 
800 #ifdef USE_TTS
801  void sayText(const Common::String &text, Common::TextToSpeechManager::Action action = Common::TextToSpeechManager::QUEUE,
802  bool checkPreviousSaid = true);
803  void stopTextToSpeech(bool clearPreviousSaid = true);
804 #endif
805 
806 public:
807  void decrypt(uint8 *mem, int len);
808  uint16 processAGIEvents();
809  int runGame();
810 
811  void newRoom(int16 newRoomNr);
812  void resetControllers();
813  void interpretCycle();
814  void playGame();
815 
816  void allowSynthetic(bool);
817  void processScummVMEvents();
818  void checkQuickLoad();
819 
820  const Common::String getTargetName() const { return _targetName; }
821 
822 private:
823  byte getAppleIIgsTimeDelay(const AgiAppleIIgsDelayOverwriteGameEntry *appleIIgsDelayOverwrite, byte &newTimeDelay) const;
824 
825  // Objects
826 public:
827  int loadObjects(const char *fname);
828  int loadObjects(Common::SeekableReadStream &fp, int flen);
829  const char *objectName(uint16 objectNr);
830  int objectGetLocation(uint16 objectNr);
831  void objectSetLocation(uint16 objectNr, int location);
832 private:
833  int decodeObjects(uint8 *mem, uint32 flen);
834 
835  // Logic
836 public:
837  int decodeLogic(int16 logicNr);
838  void unloadLogic(int16 logicNr);
839  int runLogic(int16 logicNr);
840  void debugConsole(int lognum, int mode, const char *str);
841  bool testIfCode(int16 logicNr);
842  void executeAgiCommand(uint8 op, uint8 *p);
843 
844 private:
845  bool _veryFirstInitialCycle;
846  uint32 _instructionCounter;
848  bool _setVolumeBrokenFangame;
849 
850  void resetGetVarSecondsHeuristic();
851  void getVarSecondsHeuristicTrigger();
852  uint32 _getVarSecondsHeuristicLastInstructionCounter;
853  uint16 _getVarSecondsHeuristicCounter;
855  uint32 _playTimeInSecondsAdjust;
857  void setVarSecondsTrigger(byte newSeconds);
858 
859 public:
860  // Some submethods of testIfCode
861  void skipInstruction(byte op);
862  void skipInstructionsUntil(byte v);
863  bool testObjRight(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2);
864  bool testObjCenter(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2);
865  bool testObjInBox(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2);
866  bool testPosn(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2);
867  bool testSaid(uint8 nwords, uint8 *cc);
868  bool testController(uint8 cont);
869  bool testCompareStrings(uint8 s1, uint8 s2);
870 
871  // Picture
872 private:
873  void unloadPicture(int16 picNr);
874 
875  // View
876 private:
877  void updateView(ScreenObjEntry *screenObj);
878 
879 public:
880  void setView(ScreenObjEntry *screenObj, int16 viewNr);
881  void setLoop(ScreenObjEntry *screenObj, int16 loopNr);
882  void setCel(ScreenObjEntry *screenObj, int16 celNr);
883 
884  void clipViewCoordinates(ScreenObjEntry *screenObj);
885 
886  void startUpdate(ScreenObjEntry *viewPtr);
887  void stopUpdate(ScreenObjEntry *viewPtr);
888  void updateScreenObjTable();
889  void unloadView(int16 viewNr);
890  int decodeView(byte *resourceData, uint16 resourceSize, int16 viewNr);
891 
892 private:
893  void unpackViewCelData(AgiViewCel *celData, byte *compressedData, uint16 compressedSize, int16 viewNr);
894  void unpackViewCelDataAGI256(AgiViewCel *celData, byte *compressedData, uint16 compressedSize, int16 viewNr);
895 
896 public:
897  bool isEgoView(const ScreenObjEntry *screenObj);
898 
899  // Motion
900 private:
901  int checkStep(int delta, int step);
902  bool checkBlock(int16 x, int16 y);
903  void changePos(ScreenObjEntry *screenObj);
904  void motionWander(ScreenObjEntry *screenObj);
905  void motionFollowEgo(ScreenObjEntry *screenObj);
906  void motionMoveObj(ScreenObjEntry *screenObj);
907  void motionMoveObjStop(ScreenObjEntry *screenObj);
908  void checkMotion(ScreenObjEntry *screenObj);
909 
910 public:
911  void motionActivated(ScreenObjEntry *screenObj);
912  void cyclerActivated(ScreenObjEntry *screenObj);
913  void checkAllMotions();
914  void moveObj(ScreenObjEntry *screenObj);
915  void inDestination(ScreenObjEntry *screenObj);
916  void fixPosition(int16 screenObjNr);
917  void fixPosition(ScreenObjEntry *screenObj);
918  void updatePosition();
919  int getDirection(int16 objX, int16 objY, int16 destX, int16 destY, int16 stepSize);
920  byte egoNearWater(byte limit);
921  int16 nearWater(ScreenObjEntry &screenObj, byte direction, int16 x, int16 y, byte limit);
922 
923  bool _keyHoldMode;
924  Common::KeyCode _keyHoldModeLastKey;
925 
926  // Keyboard
927  int doPollKeyboard();
928 
929  bool handleMouseClicks(uint16 &key);
930  bool handleController(uint16 key);
931 
932  bool showPredictiveDialog();
933 
934  int waitKey();
935  int waitAnyKey();
936  void waitAnyKeyOrFinishedSound();
937 
938  void nonBlockingText_IsShown();
939  void nonBlockingText_Forget();
940 
941  void artificialDelay_Reset();
942  void artificialDelay_CycleDone();
943 
944  uint16 artificialDelay_SearchTable(AgiArtificialDelayTriggerType triggerType, int16 orgNr, int16 newNr);
945 
946  void artificialDelayTrigger_NewRoom(int16 newRoomNr);
947  void artificialDelayTrigger_DrawPicture(int16 newPictureNr);
948 
949 private:
950  int16 _artificialDelayCurrentRoom;
951  int16 _artificialDelayCurrentPicture;
952 
953 public:
954  void redrawScreen();
955 
956  void inGameTimerReset(uint32 newPlayTime = 0);
957  void inGameTimerResetPassedCycles();
958  uint32 inGameTimerGet();
959  uint32 inGameTimerGetPassedCycles();
960 
961  void inGameTimerUpdate();
962 
963 private:
964  uint32 _lastUsedPlayTimeInCycles; // 40 per second
965  uint32 _lastUsedPlayTimeInSeconds; // actual seconds
966  uint32 _passedPlayTimeCycles; // increased by 1 every time we passed a cycle
967 
968 private:
969  AgiOpCodeEntry _opCodes[256]; // always keep those at 256, so that there is no way for invalid memory access
970  AgiOpCodeEntry _opCodesCond[256];
971 
972  void setupOpCodes(uint16 version);
973 
974 public:
975  const AgiOpCodeEntry *getOpCodesTable() { return _opCodes; }
976 
977 private:
978  void goldRushClockTimeWorkaround_OnReadVar();
979  void goldRushClockTimeWorkaround_OnWriteVar(byte oldValue);
980 };
981 
982 } // End of namespace Agi
983 
984 #endif /* AGI_AGI_H */
bool pictureShown
Definition: agi.h:399
Definition: str.h:59
int adjMouseX
Definition: agi.h:377
Definition: agi.h:574
EngineFeature
Definition: engine.h:260
Definition: error.h:81
ErrorCode getCode() const
Definition: error.h:112
Definition: agi.h:190
bool playerControl
Definition: agi.h:397
Definition: agi.h:314
Definition: random.h:44
RenderMode
Definition: rendermode.h:48
No error occurred.
Definition: error.h:48
Definition: menu.h:55
bool predictiveDlgOnMouseClick
Definition: agi.h:439
Definition: agi.h:558
Definition: rect.h:524
Definition: picture.h:48
Definition: view.h:98
Definition: stream.h:745
Definition: file.h:145
Definition: inv.h:35
Definition: systemui.h:51
Definition: view.h:27
Definition: agi.h:687
AgiMonitorType
Definition: agi.h:253
int adjMouseY
Definition: agi.h:378
Definition: agi.h:309
Definition: agi.h:198
Definition: console.h:32
byte speedLevel
Definition: agi.h:459
Definition: sound.h:76
Definition: logic.h:30
Definition: ustr.h:57
bool mouseEnabled
Definition: agi.h:437
Definition: graphics.h:58
Definition: agi.h:700
int16 curLogicNr
Definition: agi.h:393
uint32 crc
Definition: agi.h:381
Definition: algorithm.h:29
Definition: rect.h:144
bool automaticSave
Definition: agi.h:433
Definition: sprite.h:51
bool mouseHidden
Definition: agi.h:438
Definition: agi.h:302
Definition: agi.h:346
Definition: picture.h:33
bool exitAllLogics
Definition: agi.h:398
Common::Error run() override
Definition: agi.h:579
AgiComputerType
Definition: agi.h:265
Definition: agi.h:676
Definition: words.h:35
Definition: appleIIgs_timedelay_overwrite.h:36
Definition: system.h:163
Definition: agi.h:372
int16 horizon
Definition: agi.h:388
Definition: agi.h:338
Definition: loader.h:27
Definition: sound.h:115
Definition: stack.h:102
Common::Rect mouseFence
Definition: agi.h:436
Definition: agi.h:694
Definition: engine.h:146
Definition: detection.h:29
Definition: agi.h:64
Platform
Definition: platform.h:46
Definition: font.h:27
Definition: text.h:76
Definition: view.h:43
Language
Definition: language.h:45