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
30namespace 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
41enum {
42 V12_X_MULTIPLIER = 8,
43 V12_Y_MULTIPLIER = 2,
44
45 V12_X_SHIFT = 3,
46 V12_Y_SHIFT = 1
47};
48
49enum 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
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
90struct AdjustBoxResult { /* Result type of AdjustBox functions */
91 int16 x, y;
92 byte box;
93};
94
95enum {
96 kOldInvalidBox = 255, // For GF_SMALL_HEADER games
97 kNewInvalidBox = 0
98};
99
101public:
102 static byte kInvalidBox;
103
104protected:
105 ScummEngine *_vm;
106
109
110public:
111 int _top = 0, _bottom = 0;
112 uint _width = 0;
113 byte _number = 0;
114 uint16 _costume = 0;
115 byte _room = 0;
116
117public:
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
156protected:
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
202public:
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);
227protected:
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
236public:
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();
256protected:
257 void startWalkAnim(int cmd, int angle);
258public:
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 {
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
349protected:
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
357class Actor_v3 : public Actor {
358public:
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
366protected:
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;
371private:
372 virtual int actorWalkStep() override;
373 uint _stepX;
374 const int _facingXYratio;
375};
376
377class Actor_v2 : public Actor_v3 {
378public:
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
385protected:
386 bool isPlayer() override;
387 void prepareDrawActorCostume(BaseCostumeRenderer *bcr) override;
388private:
389 int actorWalkStep() override;
390 int remapDirection(int dir, bool is_walking) override;
391};
392
393class Actor_v7 final : public Actor {
394public:
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
402private:
403 int updateActorDirection();
404};
405
406enum 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
417class Actor_v0 : public Actor_v2 {
418public:
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
456private:
457
458 bool walkBoxQueueAdd(int box);
459 bool walkBoxQueueFind(int box);
460 void walkboxQueueReverse();
461
462public:
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
Definition: serializer.h:352
Definition: serializer.h:80
Definition: actor.h:417
Definition: actor.h:377
Definition: actor.h:357
Definition: actor.h:393
Definition: actor.h:100
Common::Point _pos
Definition: actor.h:108
Definition: base-costume.h:68
Definition: scumm.h:536
Definition: actor.h:30
T y
Definition: rect.h:49
T x
Definition: rect.h:48
Definition: rect.h:144
Definition: actor.h:157
Definition: actor.h:90
Definition: actor.h:57
byte version
Definition: detection.h:91