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
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef ILLUSIONS_ACTOR_H
24 #define ILLUSIONS_ACTOR_H
25 
26 #include "illusions/resources/actorresource.h"
27 #include "illusions/resources/backgroundresource.h"
28 #include "illusions/graphics.h"
29 #include "illusions/pathfinder.h"
30 #include "common/algorithm.h"
31 #include "common/func.h"
32 #include "common/list.h"
33 #include "graphics/surface.h"
34 
35 namespace Illusions {
36 
37 class Control;
38 class IllusionsEngine;
39 class SequenceOpcodes;
40 struct OpCall;
41 
42 enum ActorFlags {
43 	ACTOR_FLAG_IS_VISIBLE = 1,
44 	ACTOR_FLAG_HAS_WALK_POINTS = 2,
45 	ACTOR_FLAG_SCALED = 4,
46 	ACTOR_FLAG_PRIORITY = 8,
47 	ACTOR_FLAG_HAS_WALK_RECTS = 0x10,
48 	ACTOR_FLAG_REGION = 0x20,
49 	ACTOR_FLAG_40 = 0x40,
50 	ACTOR_FLAG_80 = 0x80,
51 	ACTOR_FLAG_100 = 0x100,
52 	ACTOR_FLAG_200 = 0x200,
53 	ACTOR_FLAG_400 = 0x400,
54 	ACTOR_FLAG_800 = 0x800,
55 	ACTOR_FLAG_1000 = 0x1000,
56 	ACTOR_FLAG_2000 = 0x2000,
57 	ACTOR_FLAG_4000 = 0x4000,
58 	ACTOR_FLAG_8000 = 0x8000
59 };
60 
61 enum ControlObjectID {
62 	CURSOR_OBJECT_ID = 0x40004
63 };
64 
65 const uint kSubObjectsCount = 15;
66 
67 struct DefaultSequence {
68 	uint32 _sequenceId;
69 	uint32 _newSequenceId;
DefaultSequenceDefaultSequence70 	DefaultSequence()
71 		: _sequenceId(0), _newSequenceId(0) {}
DefaultSequenceDefaultSequence72 	DefaultSequence(uint32 sequenceId, uint32 newSequenceId)
73 		: _sequenceId(sequenceId), _newSequenceId(newSequenceId) {}
74 };
75 
76 class DefaultSequences {
77 public:
78 	uint32 use(uint32 sequenceId);
79 	void set(uint32 sequenceId, uint32 newSequenceId);
80 protected:
81 	typedef Common::Array<DefaultSequence> Items;
82 	typedef Items::iterator ItemsIterator;
83 	struct DefaultSequenceEqual : public Common::UnaryFunction<const DefaultSequence&, bool> {
84 		uint32 _sequenceId;
DefaultSequenceEqualDefaultSequenceEqual85 		DefaultSequenceEqual(uint32 sequenceId) : _sequenceId(sequenceId) {}
operatorDefaultSequenceEqual86 		bool operator()(const DefaultSequence &defaultSequence) const {
87 			return defaultSequence._sequenceId == _sequenceId;
88 		}
89 	};
90 	Common::Array<DefaultSequence> _items;
91 };
92 
93 typedef Common::Functor2<Control*, uint32, void> ActorControlRoutine;
94 
95 class Actor {
96 public:
97 	Actor(IllusionsEngine *vm);
98 	~Actor();
99 	void pause();
100 	void unpause();
101 	void createSurface(SurfInfo &surfInfo);
102 	void destroySurface();
103 	void initSequenceStack();
104 	void pushSequenceStack(int16 value);
105 	int16 popSequenceStack();
106 	void setControlRoutine(ActorControlRoutine *controlRoutine);
107 	void runControlRoutine(Control *control, uint32 deltaTime);
108 	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
109 public:
110 	IllusionsEngine *_vm;
111 	byte _drawFlags;
112 	uint _spriteFlags;
113 
114 	int _pauseCtr;
115 	uint _flags;
116 
117 	int _scale;
118 	int16 _frameIndex;
119 	int16 _newFrameIndex;
120 	SurfInfo _surfInfo;
121 	Graphics::Surface *_surface;
122 
123 	FramesList *_frames;
124 	NamedPoints *_namedPoints;
125 
126 	ScaleLayer *_scaleLayer;
127 	PriorityLayer *_priorityLayer;
128 	RegionLayer *_regionLayer;
129 	PathWalkPoints *_pathWalkPoints;
130 	PathWalkRects *_pathWalkRects;
131 
132 	uint _seqStackCount;
133 	int16 _seqStack[5];
134 
135 	Common::Point _position;
136 	Common::Point _position2;
137 	uint _facing;
138 	int _regionIndex;
139 
140 	uint32 _fontId;
141 	int16 _actorIndex;
142 
143 	DefaultSequences _defaultSequences;
144 
145 	uint32 _parentObjectId;
146 	int _linkIndex;
147 	int _linkIndex2;
148 	uint32 _subobjects[kSubObjectsCount];
149 
150 	uint32 _notifyThreadId1;
151 	uint32 _notifyId3C;
152 
153 	uint32 _notifyThreadId2;
154 	byte *_entryTblPtr;
155 
156 	ActorControlRoutine *_controlRoutine;
157 
158 	uint32 _sequenceId;
159 	int _seqCodeValue2;
160 	byte *_seqCodeIp;
161 	int _seqCodeValue1;
162 	int _seqCodeValue3;
163 
164 	int _pathCtrX, _pathCtrY;
165 	int _pathAngle;
166 	int32 _posXShl, _posYShl;
167 	uint _pathPointIndex;
168 	uint _pathPointsCount;
169 	Common::Point _pathInitialPos;
170 	bool _pathInitialPosFlag;
171 	bool _pathFlag50;
172 	PointArray *_pathNode;
173 	uint _pathPoints;
174 	uint32 _walkCallerThreadId1;
175 
176 	RGB _color;
177 	int16 _choiceJumpOffs;
178 
179 };
180 
181 class Control {
182 public:
183 	Control(IllusionsEngine *vm);
184 	~Control();
185 	void pause();
186 	void unpause();
187 	void appearActor();
188 	void disappearActor();
189 	bool isActorVisible();
190 	void activateObject();
191 	void deactivateObject();
192 	void readPointsConfig(byte *pointsConfig);
193 	void setActorPosition(Common::Point position);
194 	Common::Point getActorPosition();
195 	void setActorScale(int scale);
196 	void faceActor(uint facing);
197 	void linkToObject(uint32 parentObjectId, uint32 linkedObjectValue);
198 	void unlinkObject();
199 	void clearNotifyThreadId1();
200 	void clearNotifyThreadId2();
201 	void setPriority(int16 priority);
202 	uint32 getOverlapPriority();
203 	uint32 getDrawPriority();
204 	uint32 getPriority();
205 	Common::Point calcPosition(Common::Point posDelta);
206 	uint32 getSubActorParent();
207 	void getCollisionRectAccurate(Common::Rect &collisionRect);
208 	void getCollisionRect(Common::Rect &collisionRect);
209 	void setActorUsePan(int usePan);
210 	void setActorFrameIndex(int16 frameIndex);
211 	void stopActor();
212 	void startSequenceActor(uint32 sequenceId, int value, uint32 notifyThreadId);
213 	void stopSequenceActor();
214 	void startTalkActor(uint32 sequenceId, byte *entryTblPtr, uint32 threadId);
215 	void sequenceActor();
216 	void setActorIndex(int actorIndex);
217 	void setActorIndexTo1();
218 	void setActorIndexTo2();
219 	void startSubSequence(int linkIndex, uint32 sequenceId);
220 	void stopSubSequence(int linkIndex);
221 	void startMoveActor(uint32 sequenceId, Common::Point destPt, uint32 callerThreadId1, uint32 callerThreadId2);
222 	PointArray *createPath(Common::Point destPt);
223 	void updateActorMovement(uint32 deltaTime);
224 	void refreshSequenceCode();
225 	void getActorFrameDimensions(WidthHeight &dimensions);
226 	void drawActorRect(const Common::Rect r, byte color);
227 	void fillActor(byte color);
228 	bool isPixelCollision(Common::Point &pt);
229 public:
230 	IllusionsEngine *_vm;
231 	uint _flags;
232 	int _pauseCtr;
233 	int16 _priority;
234 	Actor *_actor;
235 	uint32 _sceneId;
236 	uint32 _objectId;
237 	uint32 _actorTypeId;
238 	WRect _bounds;
239 	Common::Point _feetPt;
240 	Common::Point _position;
241 	Common::Point _subobjectsPos[kSubObjectsCount];
242 	void startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId);
243 	void execSequenceOpcode(OpCall &opCall);
244 };
245 
246 class Controls {
247 public:
248 	Controls(IllusionsEngine *vm);
249 	~Controls();
250 	void placeBackgroundObject(BackgroundObject *backgroundObject);
251 	void placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequenceId, uint32 objectId, uint32 notifyThreadId);
252 	void placeSequenceLessActor(uint32 objectId, Common::Point placePt, WidthHeight dimensions, int16 priority);
253 	void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags);
254 	void placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId, uint32 sequenceId);
255 	void placeDialogItem(uint16 objectNum, uint32 actorTypeId, uint32 sequenceId, Common::Point placePt, int16 choiceJumpOffs);
256 	void destroyControls();
257 	void destroyActiveControls();
258 	void destroyControlsBySceneId(uint32 sceneId);
259 	void destroyDialogItems();
260 	void threadIsDead(uint32 threadId);
261 	void pauseControls();
262 	void unpauseControls();
263 	void pauseControlsBySceneId(uint32 sceneId);
264 	void unpauseControlsBySceneId(uint32 sceneId);
265 	bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority);
266 	bool getOverlappedObjectAccurate(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority);
267 	bool getDialogItemAtPos(Control *control, Common::Point pt, Control **outOverlappedControl);
268 	bool getOverlappedWalkObject(Control *control, Common::Point pt, Control **outOverlappedControl);
269 	void destroyControl(Control *control);
270 	bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
271 	void actorControlRoutine(Control *control, uint32 deltaTime);
272 	void dialogItemControlRoutine(Control *control, uint32 deltaTime);
273 	void disappearActors();
274 	void appearActors();
275 	void pauseActors(uint32 objectId);
276 	void unpauseActors(uint32 objectId);
277 public:
278 	typedef Common::List<Control*> Items;
279 	typedef Items::iterator ItemsIterator;
280 	IllusionsEngine *_vm;
281 	Items _controls;
282 	SequenceOpcodes *_sequenceOpcodes;
283 	uint32 _nextTempObjectId;
284 	Actor *newActor();
285 	Control *newControl();
286 	uint32 newTempObjectId();
287 	void destroyControlInternal(Control *control);
288 };
289 
290 } // End of namespace Illusions
291 
292 #endif // ILLUSIONS_ACTOR_H
293