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