ScummVM API documentation
character.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 CHARACTER_H
23#define CHARACTER_H
24
25#include "common/hashmap.h"
26#include "common/ptr.h"
27#include "common/rect.h"
28#include "common/scummsys.h"
29
30namespace Common {
31class SeekableReadStream;
32class ReadStream;
33class WriteStream;
34} // namespace Common
35namespace Graphics {
36struct Surface;
37class ManagedSurface;
38} // namespace Graphics
39
40namespace AGDS {
41
42class AGDSEngine;
43class Object;
44using ObjectPtr = Common::SharedPtr<Object>;
45class Animation;
46using AnimationPtr = Common::SharedPtr<Animation>;
47
48class Character {
50 AGDSEngine *_engine;
51 ObjectPtr _object;
52 AnimationPtr _animation;
53 FogPtr _fog;
54 bool _jokes;
55 Common::String _name;
56 Common::String _processName;
57 Common::Point _pos;
58 Common::Point _animationPos;
59 bool _enabled;
60 bool _visible;
61 bool _stopped;
62 bool _shown;
63 int _phase;
64 int _frames;
65 int _direction;
66 int _jokesDirection;
67 int _movementDirections;
68 int _fogMinZ, _fogMaxZ;
69
70 struct AnimationDescription {
71 struct Frame {
72 int x, y; // cumulative walk displacement from animation start
73 uint w, h; // cropped bitmap size of this frame
74 uint canvasW, canvasH; // logical canvas size (anchor and scale reference)
75 int offX, offY; // anchor tweak of the crop inside the logical canvas
76 int cropX, cropY; // position of the crop inside the full FLIC frame
77 };
78
79 Common::String filename;
81 };
83 const AnimationDescription *_description;
84 bool _standing;
85
86 // Phased characters (Black Mirror main cast) store 5 animations per
87 // facing direction: start(0), cycle A(1), cycle B(2), stop from A(3),
88 // stop from B(4). Their animation index is dir * 5 + phase.
89 static const int kAnimsPerDirection = 5;
90
91 bool phased() const {
92 return _movementDirections != 0 &&
93 _animations.size() >= (uint)(_movementDirections * kAnimsPerDirection);
94 }
95
96 int animIndexFor(int dir, int phase) const {
97 return phased() ? dir * kAnimsPerDirection + phase : dir;
98 }
99
100 const AnimationDescription::Frame *frameAt(int dir, int phase, int frame) const {
101 const AnimationDescription *desc = animationDescription(animIndexFor(dir, phase));
102 if (!desc || desc->frames.empty())
103 return nullptr;
104 if (frame < 0)
105 frame = 0;
106 if (frame >= (int)desc->frames.size())
107 frame = desc->frames.size() - 1;
108 return &desc->frames[frame];
109 }
110
111 bool animate(int animIndex, int speed, bool jokes);
112 float perspectiveScale() const;
113 Common::Point animationPosition() const;
114
115 // --- Walk state machine (mirrors the original engine) ---
116 enum WalkState {
117 kWalkIdle = 0,
118 kWalkWalking = 1, // normal walk along the path
119 kWalkLeaving = 2, // walking off-screen
120 kWalkTurning = 3, // turning in place only
121 kWalkRemovePending = 5, // finish current cycle, then re-issue moveTo
122 kWalkLeavePending = 6, // finish current cycle, then leave
123 kWalkStopPending = 9 // finish current cycle, play stop anim, idle
124 };
125
126 int _walkState;
127 int _targetDir;
129 uint _pathIndex;
130 Common::Point _segStart, _segTarget, _finalTarget;
131 int _finalDir;
132 bool _exactMove;
133 int _walkPhase; // 0..4 walk phase, -1 = finished
134 int _cyclesA, _cyclesB;
135 bool _playStopAnim;
136 Common::Array<int> _cycleScales; // permyriad scale per planned cycle
137 int _scaleIdx;
138 int _errX, _errY, _errStepX, _errStepY;
139 int _errPeriodX, _errPeriodY, _errPhaseX, _errPhaseY;
140 int _walkTickCnt;
141 int _cycleErrX, _cycleErrY, _corrX, _corrY;
142 int _decodedFrame; // FLIC frame currently decoded into _animation
143
144 void walkUpdateTick();
145 void turnOneStep();
146 void startNextSegment();
147 void setCycleScale(uint idx, int scale);
148 void setupSegmentPhased(int dx, int dy);
149 int advanceWalkPhase(bool cont);
150 void advanceWalkFrame();
151 bool walkTickAdvance();
152 void stepErrorCorrection();
153 void walkingTick();
154 void arrive(int prevState);
155 void stopMoving(bool force);
156 bool loadWalkAnim();
157 Common::Point totalDisp(int dir, int phase) const;
158 int perspectiveScalePermyriad(int y) const;
159 int scaleForSegmentY(int simY, int targetY) const;
160 static double scalePermyriad(int v, int scale);
161 void checkTrapRegions();
162
163public:
164 Character(AGDSEngine *engine, const Common::String &name);
165 ~Character();
166
167 void associate(const Common::String &name);
168
169 const AnimationDescription *animationDescription(uint index) const {
170 auto it = _animations.find(index);
171 return it != _animations.end() ? &it->_value : nullptr;
172 }
173
174 const Common::String &name() const {
175 return _name;
176 }
177
178 const ObjectPtr &object() const {
179 return _object;
180 }
181
182 void load(Common::SeekableReadStream &stream);
183 void loadState(Common::ReadStream &stream);
184 void saveState(Common::WriteStream &stream) const;
185
186 void enable(bool enabled = true) {
187 _enabled = enabled;
188 }
189
190 void visible(bool visible);
191 bool visible() const {
192 return _visible && _shown;
193 }
194
195 bool active() const {
196 return _enabled && _visible;
197 }
198
199 bool animate(Common::Point pos, int direction, int speed);
200
201 void stop();
202 void leave(const Common::String &processName);
203
204 int phase() const {
205 return _jokes ? _phase : -1;
206 }
207 void phase(int phase) {
208 _phase = phase;
209 }
210
211 void position(Common::Point pos) {
212 // placing the character cancels any walk in progress
213 cancelWalk();
214 _pos = pos;
215 }
216
217 void cancelWalk() {
218 _walkState = kWalkIdle;
219 _path.clear();
220 _pathIndex = 0;
221 _targetDir = _direction;
222 }
223
224 Common::Point position() const {
225 return _pos;
226 }
227 bool pointIn(Common::Point pos) const;
228
229 void notifyProcess(const Common::String &processName);
230 // leave: walk off-screen instead of stopping at the destination
231 bool moveTo(const Common::String &processName, Common::Point dst, int direction,
232 bool userMove = false, bool leave = false);
233 void pointTo(const Common::String &processName, Common::Point dst);
234 // Graceful stop: finish the current walk cycle, play the stop
235 // animation, then face dir (-1 keeps the current facing).
236 void requestStop(int dir);
237
238 bool walking() const {
239 return _walkState != kWalkIdle;
240 }
241
242 bool direction(int dir);
243
244 int direction() const {
245 return _jokes ? _jokesDirection : _direction;
246 }
247
248 // base facing direction (0-15), ignoring any jokes gesture in progress
249 int baseDirection() const {
250 return _direction;
251 }
252
253 void tick(bool reactivate);
254 void paint(Graphics::Surface &backbuffer, Common::Point pos) const;
255
256 int getDirectionForMovement(Common::Point delta);
257
258 int z() const;
259
260 void reset();
261 void setFog(Graphics::ManagedSurface *surface, int minZ, int maxZ);
262};
263
264} // End of namespace AGDS
265
266#endif /* AGDS_CHARACTER_H */
Definition: agds.h:82
Definition: character.h:48
void clear()
Definition: array.h:321
Definition: stream.h:385
Definition: stream.h:745
Definition: str.h:59
Definition: stream.h:77
Definition: managed_surface.h:51
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: rect.h:144
Definition: surface.h:67