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