ScummVM API documentation
actor.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 
23 #ifndef SCUMM_ACTOR_H
24 #define SCUMM_ACTOR_H
25 
26 #include "common/scummsys.h"
27 #include "common/serializer.h"
28 #include "scumm/scumm.h"
29 
30 namespace Scumm {
31 
32 enum {
33  V12_X_MULTIPLIER = 8,
34  V12_Y_MULTIPLIER = 2,
35 
36  V12_X_SHIFT = 3,
37  V12_Y_SHIFT = 1
38 };
39 
40 enum MoveFlags {
41  MF_NEW_LEG = 1,
42  MF_IN_LEG = 2,
43  MF_TURN = 4,
44  MF_LAST_LEG = 8,
45  MF_FROZEN = 0x80
46 };
47 
48 struct CostumeData {
49  CostumeData() {
50  reset();
51  }
52 
53  byte animType[16];
54  uint16 animCounter;
55  byte soundCounter;
56  byte soundPos;
57  uint16 stopped;
58  uint16 curpos[16];
59  uint16 start[16];
60  uint16 end[16];
61  uint16 frame[16];
62 
63  /* HE specific */
64  uint16 heJumpOffsetTable[16];
65  uint16 heJumpCountTable[16];
66  uint32 heCondMaskTable[16];
67 
68  void reset() {
69  animCounter = 0;
70  soundCounter = 0;
71  soundPos = 0;
72  stopped = 0;
73  memset(animType, 0, sizeof(animType)); // AKAT_Empty
74  memset(curpos, 0xFF, sizeof(curpos));
75  memset(start, 0xFF, sizeof(start));
76  memset(end, 0xFF, sizeof(end));
77  memset(frame, 0xFF, sizeof(frame));
78  }
79 };
80 
81 struct AdjustBoxResult { /* Result type of AdjustBox functions */
82  int16 x, y;
83  byte box;
84 };
85 
86 enum {
87  kOldInvalidBox = 255, // For GF_SMALL_HEADER games
88  kNewInvalidBox = 0
89 };
90 
91 class Actor : public Common::Serializable {
92 public:
93  static byte kInvalidBox;
94 
95 protected:
96  ScummEngine *_vm;
97 
100 
101 public:
102  int _top, _bottom;
103  uint _width;
104  byte _number;
105  uint16 _costume;
106  byte _room;
107 
108 public:
109  byte _talkColor;
110  int _talkFrequency;
111  byte _talkPan;
112  byte _talkVolume;
113  uint16 _boxscale;
114  byte _scalex, _scaley;
115  byte _charset;
116  byte _moving;
117  bool _ignoreBoxes;
118  byte _forceClip;
119  uint16 _lastValidX, _lastValidY;
120 
121  byte _initFrame;
122  byte _walkFrame;
123  byte _standFrame;
124  byte _talkStartFrame;
125  byte _talkStopFrame;
126 
127  bool _needRedraw, _needBgReset, _visible;
128  byte _shadowMode;
129  bool _flip;
130  byte _frame;
131  byte _walkbox;
132  int16 _talkPosX, _talkPosY;
133  uint16 _talkScript, _walkScript;
134  bool _ignoreTurns;
135  bool _drawToBackBuf;
136  int32 _layer;
137  uint16 _sound[32];
138  CostumeData _cost;
139 
140  /* HE specific */
141  int _heOffsX, _heOffsY;
142  bool _heSkipLimbs;
143  uint32 _heCondMask;
144  uint32 _hePaletteNum;
145  uint32 _heShadow;
146 
147 protected:
148  struct ActorWalkData {
149  Common::Point dest; // Final destination point
150  byte destbox; // Final destination box
151  int16 destdir; // Final destination, direction to face at
152 
153  Common::Point cur; // Last position
154  byte curbox; // Last box
155 
156  Common::Point next; // Next position on our way to the destination, i.e. our intermediate destination
157 
158  Common::Point point3;
159  int32 deltaXFactor, deltaYFactor;
160  uint16 xfrac, yfrac;
161  uint16 xAdd, yAdd;
162  int16 facing;
163 
164  void reset() {
165  dest.x = dest.y = 0;
166  destbox = 0;
167  destdir = 0;
168  cur.x = cur.y = 0;
169  curbox = 0;
170  next.x = next.y = 0;
171  point3.x = point3.y = 0;
172  deltaXFactor = 0;
173  deltaYFactor = 0;
174  xfrac = 0;
175  yfrac = 0;
176  xAdd = 0;
177  yAdd = 0;
178  facing = 0;
179  }
180  };
181 
182 
183  uint16 _palette[256];
184  int _elevation;
185  uint16 _facing;
186  uint16 _targetFacing;
187  uint _speedx, _speedy;
188  byte _animProgress, _animSpeed;
189  bool _costumeNeedsInit;
190  ActorWalkData _walkdata;
191  int16 _animVariable[27];
192 
193 public:
194 
195  Actor(ScummEngine *scumm, int id);
196  ~Actor() override {}
197 
198 //protected:
199  virtual void hideActor();
200  void showActor();
201 
202  virtual void initActor(int mode);
203 
204  void putActor() {
205  putActor(_pos.x, _pos.y, _room);
206  }
207 
208  void putActor(int room) {
209  putActor(_pos.x, _pos.y, room);
210  }
211 
212  void putActor(int x, int y) {
213  putActor(x, y, _room);
214  }
215 
216  void putActor(int x, int y, int room);
217  void setActorWalkSpeed(uint newSpeedX, uint newSpeedY);
218 protected:
219  virtual int calcMovementFactor(const Common::Point& next);
220  int actorWalkStep();
221  int remapDirection(int dir, bool is_walking);
222  virtual void setupActorScale();
223 
224  void setBox(int box);
225  int updateActorDirection(bool is_walking);
226 
227 public:
228  void adjustActorPos();
229  virtual AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
230 
231  virtual void setDirection(int direction);
232  void faceToObject(int obj);
233  virtual void turnToDirection(int newdir);
234  virtual void walkActor();
235  void drawActorCostume(bool hitTestMode = false);
236  virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
237  virtual void animateCostume();
238  virtual void setActorCostume(int c);
239 
240  void animateLimb(int limb, int f);
241 
242  bool actorHitTest(int x, int y);
243 
244  const byte *getActorName();
245  void startWalkActor(int x, int y, int dir);
246  void stopActorMoving();
247 protected:
248  void startWalkAnim(int cmd, int angle);
249 public:
250  void runActorTalkScript(int f);
251  virtual void startAnimActor(int frame);
252 
253  void remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold);
254  void remapActorPaletteColor(int slot, int color);
255 
256  void animateActor(int anim);
257 
258  bool isInCurrentRoom() const {
259  return _room == _vm->_currentRoom;
260  }
261 
262  Common::Point getPos() const {
263  Common::Point p(_pos);
264  if (_vm->_game.version <= 2) {
265  p.x *= V12_X_MULTIPLIER;
266  p.y *= V12_Y_MULTIPLIER;
267  }
268  return p;
269  }
270 
271  const Common::Point& getRealPos() const {
272  return _pos;
273  }
274 
275  int getRoom() const {
276  return _room;
277  }
278 
279  int getFacing() const {
280  return _facing;
281  }
282 
283  void setFacing(int newFacing) {
284  _facing = newFacing;
285  }
286 
287  int getAnimVar(byte var) const;
288  void setAnimVar(byte var, int value);
289 
290  void setAnimSpeed(byte newAnimSpeed) {
291  _animSpeed = newAnimSpeed;
292  _animProgress = 0;
293  }
294 
295  int getAnimSpeed() const {
296  return _animSpeed;
297  }
298 
299  int getAnimProgress() const {
300  return _animProgress;
301  }
302 
303  int getElevation() const {
304  return _elevation;
305  }
306 
307  void setElevation(int newElevation) {
308  if (_elevation != newElevation) {
309  _elevation = newElevation;
310  _needRedraw = true;
311  }
312  }
313 
314  void setPalette(int idx, int val) {
315  _palette[idx] = val;
316  _needRedraw = true;
317  }
318 
319  void setScale(int sx, int sy) {
320  if (sx != -1)
321  _scalex = sx;
322  if (sy != -1)
323  _scaley = sy;
324  _needRedraw = true;
325  }
326 
327  void classChanged(int cls, bool value);
328 
329  void saveLoadWithSerializer(Common::Serializer &ser) override;
330 
331 protected:
332  bool isInClass(int cls);
333 
334  virtual bool isPlayer();
335 
336  bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
337 };
338 
339 class Actor_v3 : public Actor {
340 public:
341  Actor_v3(ScummEngine *scumm, int id) : Actor(scumm, id), _stepX(1), _stepThreshold(0), _facingXYratio(scumm->_game.version == 3 ? 3 : 1) {}
342 
343  void initActor(int mode) override;
344  void walkActor() override;
345 
346  void saveLoadWithSerializer(Common::Serializer &ser) override;
347 
348 protected:
349  int calcMovementFactor(const Common::Point& next) override;
350  int actorWalkStep();
351 
352  void setupActorScale() override;
353  void findPathTowardsOld(byte box, byte box2, byte box3, Common::Point &p2, Common::Point &p3);
354 
355 private:
356  uint _stepX, _stepThreshold;
357  const int _facingXYratio;
358 };
359 
360 class Actor_v2 : public Actor_v3 {
361 public:
362  Actor_v2(ScummEngine *scumm, int id) : Actor_v3(scumm, id) {}
363 
364  void initActor(int mode) override;
365  void walkActor() override;
366  AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY) override;
367 
368 protected:
369  bool isPlayer() override;
370  void prepareDrawActorCostume(BaseCostumeRenderer *bcr) override;
371 };
372 
373 class Actor_v7 final : public Actor {
374 public:
375  Actor_v7(ScummEngine *scumm, int id) : Actor(scumm, id) {}
376 
377  void initActor(int mode) override;
378  void walkActor() override;
379  void turnToDirection(int newdir) override;
380  void startAnimActor(int frame) override;
381 
382 private:
383  int updateActorDirection();
384 };
385 
386 enum ActorV0MiscFlags {
387  kActorMiscFlagStrong = 0x01, // Kid is strong (Hunk-O-Matic used)
388  kActorMiscFlagGTFriend = 0x02, // Kid is green tentacle's friend (recording contract)
389  kActorMiscFlagWatchedTV = 0x04, // Kid knows publisher's address (watched TV)
390  kActorMiscFlagEdsEnemy = 0x08, // Kid is not Weird Ed's friend
391  kActorMiscFlag_10 = 0x10, // ???
392  kActorMiscFlag_20 = 0x20, // ???
393  kActorMiscFlagFreeze = 0x40, // Stop moving
394  kActorMiscFlagHide = 0x80 // Kid is invisible (dead or in radiation suit)
395 };
396 
397 class Actor_v0 : public Actor_v2 {
398 public:
399  Common::Point _CurrentWalkTo, _NewWalkTo;
400 
401  Common::Array<byte> _walkboxHistory;
402 
403  byte _walkboxQueue[0x10];
404  byte _walkboxQueueIndex;
405 
406  byte _costCommandNew;
407  byte _costCommand;
408  byte _miscflags;
409  byte _speaking;
410 
411  byte _walkCountModulo;
412  bool _newWalkBoxEntered;
413 
414  byte _walkDirX;
415  byte _walkDirY;
416 
417  byte _walkYCountGreaterThanXCount;
418  byte _walkXCount;
419  byte _walkXCountInc;
420  byte _walkYCount;
421  byte _walkYCountInc;
422 
423  byte _walkMaxXYCountInc;
424 
425  Common::Point _tmp_Pos;
426  Common::Point _tmp_NewPos;
427  byte _tmp_WalkBox;
428  bool _tmp_NewWalkBoxEntered;
429 
430  int8 _animFrameRepeat;
431  int8 _limbFrameRepeatNew[8];
432  int8 _limbFrameRepeat[8];
433 
434  bool _limb_flipped[8];
435 
436 private:
437 
438  bool walkBoxQueueAdd(int box);
439  bool walkBoxQueueFind(int box);
440  void walkboxQueueReverse();
441 
442 public:
443  Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
444 
445  void initActor(int mode) override;
446  void animateActor(int anim);
447  void animateCostume() override;
448 
449  void limbFrameCheck(int limb);
450 
451  void directionUpdate();
452  void speakCheck();
453  void setDirection(int direction) override;
454  void startAnimActor(int f) override;
455 
456  bool calcWalkDistances();
457  void walkActor() override;
458  void actorSetWalkTo();
459  byte actorWalkXCalculate();
460  byte actorWalkYCalculate();
461  byte updateWalkbox();
462 
463  void walkBoxQueueReset();
464  bool walkBoxQueuePrepare();
465 
466  AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY) override;
467  AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box);
468 
469  void setActorToTempPosition();
470  void setActorToOriginalPosition();
471 
472  void saveLoadWithSerializer(Common::Serializer &ser) override;
473 };
474 
475 
476 } // End of namespace Scumm
477 
478 #endif
Common::Point _pos
Definition: actor.h:99
Definition: actor.h:81
Definition: actor.h:373
Definition: serializer.h:79
byte version
Definition: detection.h:225
Definition: scumm.h:518
Definition: actor.h:360
Definition: actor.h:339
Definition: actor.h:148
Definition: rect.h:45
Definition: serializer.h:308
Definition: actor.h:91
int16 x
Definition: rect.h:46
Definition: base-costume.h:68
int16 y
Definition: rect.h:47
Definition: actor.h:48
Definition: actor.h:397
Definition: actor.h:30