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