ScummVM API documentation
game.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 DRACI_GAME_H
23 #define DRACI_GAME_H
24 
25 #include "common/str.h"
26 #include "draci/script.h"
27 #include "draci/walking.h"
28 
29 namespace Common {
30 class Serializer;
31 }
32 
33 namespace Draci {
34 
35 class BArchive;
36 class DraciEngine;
37 
38 enum {
39  kDragonObject = 0
40 };
41 
42 enum {
43  kDialogueLines = 4
44 };
45 
46 enum {
47  kBlackPalette = -1
48 };
49 
50 enum {
51  kMouseEnableSwitching = -1,
52  kMouseDoNotSwitch = -2
53 };
54 
55 // Constants tuned such that with ScummVM's default talkspeed kStandardSpeed, the speed
56 // computed by equation (kBaseSpeechDuration + kSpeechTimeUnit * #characters) /
57 // talkspeed is equal to the original game.
58 enum SpeechConstants {
59  kBaseSpeechDuration = 12000,
60  kSpeechTimeUnit = 2640,
61  kStandardSpeed = 60
62 };
63 
64 enum FadeConstants {
65  // One fading phase called from the game scripts is 50ms.
66  kFadingTimeUnit = 50,
67  // Fading in/out when entering/leaving a location takes 15 iterations of (at least) 7ms each.
68  kBlackFadingIterations = 15,
69  kBlackFadingTimeUnit = 7
70 };
71 
72 enum AnimationConstants {
73  kTimeUnit = 20
74 };
75 
78  kInventoryItemWidth = 25,
79  kInventoryItemHeight = 25,
80  kInventoryColumns = 7,
81  kInventoryLines = 5,
82  kInventoryX = 70,
83  kInventoryY = 30,
84  kInventorySlots = kInventoryLines * kInventoryColumns,
85  kStatusChangeTimeout = 500
86 };
87 
88 class GameObject {
89 public:
90  int _absNum;
91  uint _init, _look, _use, _canUse;
92  bool _imInit, _imLook, _imUse;
93  int _walkDir;
94  byte _z;
95  uint _lookX, _lookY, _useX, _useY;
96  SightDirection _lookDir, _useDir;
97  GPL2Program _program;
98  Common::String _title;
99  int _location;
100  bool _visible;
101 
103  int _playingAnim;
104 
105  int getAnim(int animID) const;
106  int addAnim(Animation *anim);
107  int playingAnim() const { return _playingAnim; }
108  void playAnim(int i);
109  void stopAnim();
110  void deleteAnims();
111  void deleteAnimsFrom(int index);
112  void load(uint objNum, BArchive *archive);
113 };
114 
115 struct GameInfo {
116  int _startRoom;
117  int _mapRoom;
118  uint _numObjects;
119  uint _numItems;
120  byte _numVariables;
121  byte _numPersons;
122  byte _numDialogues;
123  uint _maxItemWidth, _maxItemHeight;
124  uint _musicLength;
125  uint _crc[4];
126  uint _numDialogueBlocks;
127 };
128 
129 class GameItem {
130 public:
131  int _absNum;
132  uint _init, _look, _use, _canUse;
133  bool _imInit, _imLook, _imUse;
134  GPL2Program _program;
135  Common::String _title;
136 
137  Animation *_anim;
138 
139  void load(int itemID, BArchive *archive);
140 };
141 
142 struct Person {
143  uint _x, _y;
144  byte _fontColor;
145 };
146 
147 struct Dialogue {
148  int _canLen;
149  byte *_canBlock;
150  Common::String _title;
151  GPL2Program _program;
152 };
153 
154 class Room {
155 public:
156  int _roomNum;
157  byte _music;
158  int _mapID;
159  int _palette;
160  int _numOverlays;
161  int _init, _look, _use, _canUse;
162  bool _imInit, _imLook, _imUse;
163  bool _mouseOn, _heroOn;
164  double _pers0, _persStep;
165  int _escRoom;
166  byte _numGates;
167  Common::Array<int> _gates;
168  GPL2Program _program;
169 
170  void load(int roomNum, BArchive *archive);
171 };
172 
173 enum LoopStatus {
174  kStatusOrdinary, // normal game-play: everything allowed
175  kStatusGate, // during running init-scripts when entering a room: disable interactivity
176  kStatusInventory, // inventory is open: cannot change the room or go to map
177  kStatusDialogue // during a dialogue: cannot change the room, go to inventory
178 };
179 
180 enum LoopSubstatus {
181  kOuterLoop, // outer loop: everything is allowed
182  kInnerWhileTalk, // playing a voice: inner loop will exit afterwards
183  kInnerWhileFade, // fading a palette: inner loop will exit when done
184  kInnerDuringDialogue, // selecting continuation block: inner block will exit afterwards
185  kInnerUntilExit // other inner loop: either immediately exiting or waiting for an animation to end (whose callback ends the loop)
186 };
187 
188 class Game {
189 public:
190  Game(DraciEngine *vm);
191  ~Game();
192 
193  void init();
194  void start();
195  void loop(LoopSubstatus substatus, bool shouldExit);
196 
197  // HACK: this is only for testing
198  int nextRoomNum() const {
199  int n = _currentRoom._roomNum;
200  n = n < 37 ? n+1 : n;
201  return n;
202  }
203 
204  // HACK: same as above
205  int prevRoomNum() const {
206  int n = _currentRoom._roomNum;
207  n = n > 0 ? n-1 : n;
208  return n;
209  }
210 
211  Common::Point findNearestWalkable(int x, int y) const { return _walkingMap.findNearestWalkable(x, y); }
212  void heroAnimationFinished() { _walkingState.heroAnimationFinished(); }
213  void stopWalking() { _walkingState.stopWalking(); } // and clear callback
214  void walkHero(int x, int y, SightDirection dir); // start walking and leave callback as is
215  void setHeroPosition(const Common::Point &p);
216  const Common::Point &getHeroPosition() const { return _hero; }
217  const Common::Point &getHeroLoadingPosition() const { return _heroLoading; }
218  void positionAnimAsHero(Animation *anim);
219  void positionHeroAsAnim(Animation *anim);
220 
221  // Makes sure animation anim_index plays on the hero. If the hero's
222  // position has changed, it updates the animation position. If the new
223  // animation is different, it stops the old one and starts the new one,
224  // otherwise it just marks dirty rectangles for moving the position.
225  // Returns the current animation phase of the new animation (usually 0
226  // unless the animation hasn't changed).
227  int playHeroAnimation(int anim_index);
228 
229  void loadOverlays();
230  void loadWalkingMap(int mapID); // but leaves _currentRoom._mapID untouched
231  void switchWalkingAnimations(bool enabled);
232 
233  uint getNumObjects() const { return _info._numObjects; }
234  GameObject *getObject(uint objNum) { return _objects + objNum; }
235  const GameObject *getObjectWithAnimation(const Animation *anim) const;
236  void deleteObjectAnimations();
237  void deleteAnimationsAfterIndex(int lastAnimIndex);
238 
239  int getVariable(int varNum) const { return _variables[varNum]; }
240  void setVariable(int varNum, int value) { _variables[varNum] = value; }
241 
242  const Person *getPerson(int personID) const { return &_persons[personID]; }
243 
244  int getRoomNum() const { return _currentRoom._roomNum; }
245  void setRoomNum(int num) { _currentRoom._roomNum = num; }
246  int getPreviousRoomNum() const { return _previousRoom; }
247  void rememberRoomNumAsPrevious() { _previousRoom = getRoomNum(); }
248  void scheduleEnteringRoomUsingGate(int room, int gate) { _newRoom = room; _newGate = gate; }
249  void pushNewRoom();
250  void popNewRoom();
251 
252  double getPers0() const { return _currentRoom._pers0; }
253  double getPersStep() const { return _currentRoom._persStep; }
254  int getMusicTrack() const { return _currentRoom._music; }
255  void setMusicTrack(int num) { _currentRoom._music = num; }
256 
257  int getItemStatus(int itemID) const { return _itemStatus[itemID]; }
258  void setItemStatus(int itemID, int status) { _itemStatus[itemID] = status; }
259  GameItem *getItem(int id) { return id >= 0 && id < (int)_info._numItems ? &_items[id] : NULL; }
260  GameItem *getCurrentItem() const { return _currentItem; }
261  void setCurrentItem(GameItem *item) { _currentItem = item; }
262  int getPreviousItemPosition() const { return _previousItemPosition; }
263  void setPreviousItemPosition(int pos) { _previousItemPosition = pos; }
264  void removeItem(GameItem *item);
265  void loadItemAnimation(GameItem *item);
266  void putItem(GameItem *item, int position);
267  void addItem(int itemID);
268 
269  int getEscRoom() const { return _currentRoom._escRoom; }
270  int getMapRoom() const { return _info._mapRoom; }
271  int getMapID() const { return _currentRoom._mapID; }
272 
279  int getMarkedAnimationIndex() const { return _markedAnimationIndex; }
280  void setMarkedAnimationIndex(int index) { _markedAnimationIndex = index; }
281 
282  void setLoopStatus(LoopStatus status) { _loopStatus = status; }
283  void setLoopSubstatus(LoopSubstatus status) { _loopSubstatus = status; }
284  LoopStatus getLoopStatus() const { return _loopStatus; }
285  LoopSubstatus getLoopSubstatus() const { return _loopSubstatus; }
286 
287  bool gameShouldQuit() const { return _shouldQuit; }
288  void setQuit(bool quit) { _shouldQuit = quit; }
289  bool shouldExitLoop() const { return _shouldExitLoop; }
290  void setExitLoop(bool exit) { _shouldExitLoop = exit; }
291  bool isReloaded() const { return _isReloaded; }
292  void setIsReloaded(bool value) { _isReloaded = value; }
293  bool isPositionLoaded() { return _isPositionLoaded; }
294  void setPositionLoaded(bool value) { _isPositionLoaded = value; }
295 
296  void setSpeechTiming(uint tick, uint duration);
297  void shiftSpeechAndFadeTick(int delta);
298 
299  void inventoryInit();
300  void inventoryDraw();
301  void inventoryDone();
302  void inventoryReload();
303  void inventorySwitch(int action);
304 
305  void dialogueMenu(int dialogueID);
306  int dialogueDraw();
307  void dialogueInit(int dialogID);
308  void dialogueDone();
309 
310  bool isDialogueBegin() const { return _dialogueBegin; }
311  bool shouldExitDialogue() const { return _dialogueExit; }
312  void setDialogueExit(bool exit) { _dialogueExit = exit; }
313  int getDialogueBlockNum() const { return _blockNum; }
314  int getDialogueVar(int dialogueID) const { return _dialogueVars[dialogueID]; }
315  void setDialogueVar(int dialogueID, int value) { _dialogueVars[dialogueID] = value; }
316  int getCurrentDialogue() const { return _currentDialogue; }
317  int getDialogueCurrentBlock() const { return _currentBlock; }
318  int getDialogueLastBlock() const { return _lastBlock; }
319  int getDialogueLinesNum() const { return _dialogueLinesNum; }
320  int getCurrentDialogueOffset() const { return _dialogueOffsets[_currentDialogue]; }
321 
322  void schedulePalette(int paletteID) { _scheduledPalette = paletteID; }
323  int getScheduledPalette() const { return _scheduledPalette; }
324  void initializeFading(int phases);
325  void setEnableQuickHero(bool value) { _enableQuickHero = value; }
326  bool getEnableQuickHero() const { return _enableQuickHero; }
327  void setWantQuickHero(bool value) { _wantQuickHero = value; }
328  bool getWantQuickHero() const { return _wantQuickHero; }
329  void setEnableSpeedText(bool value) { _enableSpeedText = value; }
330  bool getEnableSpeedText() const { return _enableSpeedText; }
331 
332  void synchronize(Common::Serializer &s, uint8 saveVersion);
333 
334 private:
335  void updateOrdinaryCursor();
336  void updateInventoryCursor();
337  int inventoryPositionFromMouse() const;
338  void handleOrdinaryLoop(int x, int y);
339  void handleInventoryLoop();
340  void handleDialogueLoop();
341  void updateTitle(int x, int y);
342  void updateCursor();
343  void fadePalette(bool fading_out);
344  void advanceAnimationsAndTestLoopExit();
345  void handleStatusChangeByMouse();
346 
347  void enterNewRoom();
348  void initWalkingOverlays();
349  void loadRoomObjects();
350  void redrawWalkingPath(Animation *anim, byte color, const WalkingPath &path);
351 
352  DraciEngine *_vm;
353 
354  GameInfo _info;
355 
356  Common::Point _hero;
357  Common::Point _heroLoading;
358  Common::Point _lastTarget;
359 
360  int *_variables;
361  Person *_persons;
362  GameObject *_objects;
363 
364  byte *_itemStatus;
365  GameItem *_items;
366  GameItem *_currentItem;
367  GameItem *_itemUnderCursor;
368 
369  // Last position in the inventory of the item currently in the hands, resp. of the item that
370  // was last in our hands.
371  int _previousItemPosition;
372 
373  GameItem *_inventory[kInventorySlots];
374 
375  Room _currentRoom;
376  int _newRoom;
377  int _newGate;
378  int _previousRoom;
379  int _pushedNewRoom; // used in GPL programs
380  int _pushedNewGate;
381 
382  uint *_dialogueOffsets;
383  int _currentDialogue;
384  int *_dialogueVars;
385  BArchive *_dialogueArchive;
386  Dialogue *_dialogueBlocks;
387  bool _dialogueBegin;
388  bool _dialogueExit;
389  int _currentBlock;
390  int _lastBlock;
391  int _dialogueLinesNum;
392  int _blockNum;
393  int _lines[kDialogueLines];
394  Animation *_dialogueAnims[kDialogueLines];
395 
396  LoopStatus _loopStatus;
397  LoopSubstatus _loopSubstatus;
398 
399  bool _shouldQuit;
400  bool _shouldExitLoop;
401  bool _isReloaded;
402  bool _isPositionLoaded;
403 
404  uint _speechTick;
405  uint _speechDuration;
406 
407  const GameObject *_objUnderCursor;
408  const Animation *_animUnderCursor;
409 
410  int _markedAnimationIndex;
411 
412  int _scheduledPalette;
413  int _fadePhases;
414  int _fadePhase;
415  uint _fadeTick;
416  bool _isFadeOut;
417  int _mouseChangeTick;
418 
419  bool _enableQuickHero;
420  bool _wantQuickHero;
421  bool _enableSpeedText;
422 
423  WalkingMap _walkingMap;
424  WalkingState _walkingState;
425 
426  Animation *_titleAnim;
427  Animation *_inventoryAnim;
428  Animation *_walkingMapOverlay;
429  Animation *_walkingShortestPathOverlay;
430  Animation *_walkingObliquePathOverlay;
431 };
432 
433 } // End of namespace Draci
434 
435 #endif // DRACI_GAME_H
Definition: game.h:129
Definition: walking.h:103
Definition: draci.h:68
Definition: str.h:59
Definition: animation.h:59
Definition: game.h:142
Definition: array.h:52
Definition: walking.h:34
int getMarkedAnimationIndex() const
Definition: game.h:279
InventoryConstants
Definition: game.h:77
Definition: game.h:147
Definition: serializer.h:79
Used for positioning of the inventory sprite on the X axis.
Definition: game.h:82
Definition: game.h:88
Definition: algorithm.h:29
Definition: rect.h:45
Definition: barchive.h:48
Definition: game.h:188
Definition: animation.h:30
Definition: game.h:115
Definition: script.h:83
Used for positioning of the inventory sprite on the Y axis.
Definition: game.h:83
Definition: game.h:154