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