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  * Additional copyright for this file:
8  * Copyright (C) 1994-1998 Revolution Software Ltd.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 #ifndef SWORD2_ROUTER_H
26 #define SWORD2_ROUTER_H
27 
28 // This used to be a variable, but it was never set. Actually, it wasn't even
29 // initialized!
30 //
31 // Define this to force the use of slidy router (so solid path not used when
32 // ending walk in ANY direction)
33 //
34 // #define FORCE_SLIDY
35 
36 #include "sword2/object.h"
37 
38 namespace Sword2 {
39 
40 struct WalkData {
41 	uint16 frame;
42 	int16 x;
43 	int16 y;
44 	uint8 step;
45 	uint8 dir;
46 };
47 
48 struct BarData {
49 	int16 x1;
50 	int16 y1;
51 	int16 x2;
52 	int16 y2;
53 	int16 xmin;
54 	int16 ymin;
55 	int16 xmax;
56 	int16 ymax;
57 	int16 dx;	// x2 - x1
58 	int16 dy;	// y2 - y1
59 	int32 co;	// co = (y1*dx) - (x1*dy) from an equation for a line y*dx = x*dy + co
60 };
61 
62 struct NodeData {
63 	int16 x;
64 	int16 y;
65 	int16 level;
66 	int16 prev;
67 	int16 dist;
68 };
69 
70 // because we only have 2 megas in the game!
71 #define TOTAL_ROUTE_SLOTS	2
72 
73 #define MAX_FRAMES_PER_CYCLE	16
74 #define NO_DIRECTIONS		8
75 #define MAX_FRAMES_PER_CHAR	(MAX_FRAMES_PER_CYCLE * NO_DIRECTIONS)
76 #define ROUTE_END_FLAG		255
77 
78 #define MAX_WALKGRIDS		10
79 
80 #define	O_WALKANIM_SIZE		600	// max number of nodes in router output
81 #define	O_GRID_SIZE		200	// max 200 lines & 200 points
82 #define	O_ROUTE_SIZE		50	// max number of modules in a route
83 
84 struct RouteData {
85 	int32 x;
86 	int32 y;
87 	int32 dirS;
88 	int32 dirD;
89 };
90 
91 struct PathData {
92 	int32 x;
93 	int32 y;
94 	int32 dir;
95 	int32 num;
96 };
97 
98 class Router {
99 private:
100 	Sword2Engine *_vm;
101 
102 	int16 _standbyX;	// see fnSetStandbyCoords()
103 	int16 _standbyY;
104 	int16 _standbyDir;
105 
106 	// stores pointers to mem blocks containing routes created & used by
107 	// megas (NULL if slot not in use)
108 	WalkData *_routeSlots[TOTAL_ROUTE_SLOTS];
109 
110 	BarData _bars[O_GRID_SIZE];
111 	NodeData _node[O_GRID_SIZE];
112 
113 	int32 _walkGridList[MAX_WALKGRIDS];
114 
115 	int32 _nBars;
116 	int32 _nNodes;
117 
118 	int32 _startX, _startY, _startDir;
119 	int32 _targetX, _targetY, _targetDir;
120 	int32 _scaleA, _scaleB;
121 
122 	RouteData _route[O_ROUTE_SIZE];
123 	PathData _smoothPath[O_ROUTE_SIZE];
124 	PathData _modularPath[O_ROUTE_SIZE];
125 	int32 _routeLength;
126 
127 	int32 _framesPerStep;
128 	int32 _framesPerChar;
129 
130 	ObjectWalkdata _walkData;
131 
132 	int8 _modX[NO_DIRECTIONS];
133 	int8 _modY[NO_DIRECTIONS];
134 	int32 _diagonalx;
135 	int32 _diagonaly;
136 
137 	int32 _firstStandFrame;
138 
139 	int32 _firstStandingTurnLeftFrame;
140 	int32 _firstStandingTurnRightFrame;
141 
142 	int32 _firstWalkingTurnLeftFrame;	// left walking turn
143 	int32 _firstWalkingTurnRightFrame;	// right walking turn
144 
145 	uint32 _firstSlowInFrame[NO_DIRECTIONS];
146 
147 	int32 _firstSlowOutFrame;
148 
149 	// number of slow-out frames on for each leading-leg in each direction
150 	// ie. total number of slow-out frames = (numberOfSlowOutFrames * 2 *
151 	// NO_DIRECTIONS)
152 
153 	int32 _numberOfSlowOutFrames;
154 
155 	int32 _stepCount;
156 
157 	int32 _moduleX;
158 	int32 _moduleY;
159 	int32 _currentDir;
160 	int32 _lastCount;
161 	int32 _frame;
162 
163 	uint8 returnSlotNo(uint32 megaId);
164 
165 	int32 getRoute();
166 	void extractRoute();
167 	void loadWalkGrid();
168 	void setUpWalkGrid(byte *ob_mega, int32 x, int32 y, int32 dir);
169 	void loadWalkData(byte *ob_walkdata);
170 	bool scan(int32 level);
171 
172 	int32 newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2);
173 	bool lineCheck(int32 x1, int32 x2, int32 y1, int32 y2);
174 	bool vertCheck(int32 x, int32 y1, int32 y2);
175 	bool horizCheck(int32 x1, int32 y, int32 x2);
176 	bool check(int32 x1, int32 y1, int32 x2, int32 y2);
177 	int32 checkTarget(int32 x, int32 y);
178 
179 	int32 smoothestPath();
180 	void slidyPath();
181 
182 	void smoothCheck(int32 &steps, int32 best, int32 p, int32 dirS, int32 dirD);
183 
184 	bool addSlowInFrames(WalkData *walkAnim);
185 	void addSlowOutFrames(WalkData *walkAnim);
186 	void slidyWalkAnimator(WalkData *walkAnim);
187 
188 #ifndef FORCE_SLIDY
189 	void solidPath();
190 	int32 solidWalkAnimator(WalkData *walkAnim);
191 #endif
192 
193 	void plotCross(int16 x, int16 y, uint8 color);
194 
195 public:
Router(Sword2Engine * vm)196 	Router(Sword2Engine *vm) : _vm(vm), _diagonalx(0), _diagonaly(0) {
197 		memset(_routeSlots, 0, sizeof(_routeSlots));
198 		memset(_bars, 0, sizeof(_bars));
199 		memset(_node, 0, sizeof(_node));
200 		memset(_walkGridList, 0, sizeof(_walkGridList));
201 		memset(_route, 0, sizeof(_route));
202 		memset(_smoothPath, 0, sizeof(_smoothPath));
203 		memset(_modularPath, 0, sizeof(_modularPath));
204 		memset(_modX, 0, sizeof(_modX));
205 		memset(_modY, 0, sizeof(_modY));
206 		memset(_firstSlowInFrame, 0, sizeof(_firstSlowInFrame));
207 	}
208 
209 	void setStandbyCoords(int16 x, int16 y, uint8 dir);
210 	int whatTarget(int startX, int startY, int destX, int destY);
211 
212 	// Sprites
213 	void setSpriteStatus(byte *ob_graph, uint32 type);
214 	void setSpriteShading(byte *ob_graph, uint32 type);
215 
216 	// Animation
217 	int doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse);
218 	int megaTableAnimate(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *animTable, bool reverse);
219 
220 	// Walking
221 	int doWalk(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir);
222 	int walkToAnim(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 animRes);
223 	int walkToTalkToMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId, uint32 separation);
224 
225 	// Turning
226 	int doFace(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint8 target_dir);
227 	int faceXY(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y);
228 	int faceMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId);
229 
230 	// Standing
231 	void standAt(byte *ob_graph, byte *ob_mega, int32 x, int32 y, int32 dir);
232 	void standAfterAnim(byte *ob_graph, byte *ob_mega, uint32 animRes);
233 	void standAtAnim(byte *ob_graph, byte *ob_mega, uint32 animRes);
234 
235 	int32 routeFinder(byte *ob_mega, byte *ob_walkdata, int32 x, int32 y, int32 dir);
236 
237 	void earlySlowOut(byte *ob_mega, byte *ob_walkdata);
238 
239 	void allocateRouteMem();
240 	WalkData *getRouteMem();
241 	void freeRouteMem();
242 	void freeAllRouteMem();
243 	void addWalkGrid(int32 gridResource);
244 	void removeWalkGrid(int32 gridResource);
245 	void clearWalkGridList();
246 
247 	void plotWalkGrid();
248 };
249 
250 } // End of namespace Sword2
251 
252 #endif
253