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 #include "cruise/cruise.h"
24 #include "cruise/cruise_main.h"
25 #include "common/util.h"
26 
27 namespace Cruise {
28 
29 persoStruct *persoTable[NUM_PERSONS];
30 
31 int16 numPoly;
32 
freePerso(int persoIdx)33 void freePerso(int persoIdx) {
34 	if (persoTable[persoIdx]) {
35 		MemFree(persoTable[persoIdx]);
36 		persoTable[persoIdx] = NULL;
37 	}
38 }
39 
freeCTP()40 void freeCTP() {
41 
42 	for (unsigned long int i = 0; i < NUM_PERSONS; i++) {
43 		freePerso(i);
44 	}
45 
46 	if (_vm->_polyStruct) {
47 		_vm->_polyStructNorm.clear();
48 		_vm->_polyStructExp.clear();
49 		_vm->_polyStruct = NULL;
50 	}
51 
52 	ctpVar17 = NULL;
53 	_vm->_polyStruct = NULL;
54 
55 	strcpy((char *)currentCtpName, "");
56 }
57 
58 int pathVar0;
59 
60 unsigned int inc_jo;
61 
direction(int x1,int y1,int x2,int y2,int inc_jo1,int inc_jo2)62 int direction(int x1, int y1, int x2, int y2, int inc_jo1, int inc_jo2) {
63 	int h, v, h1, v1;
64 
65 	h1 = x1 - x2;
66 	h = ABS(h1);
67 	v1 = y1 - y2;
68 	v = ABS(v1);
69 
70 	if (v > h) {
71 		if (h > 30)
72 			inc_jo = inc_jo1 - inc_jo2;
73 		else
74 			inc_jo = inc_jo2;
75 
76 		if (v1 < 0)
77 			return (2);
78 		else
79 			return (0);
80 	} else {
81 		inc_jo = inc_jo1;
82 
83 		if (h1 < 0)
84 			return (1);
85 		else
86 			return (3);
87 	}
88 }
89 
cor_droite(int x1,int y1,int x2,int y2,point * outputTable)90 int cor_droite(int x1, int y1, int x2, int y2, point* outputTable) {
91 	int numOutput = 0;
92 
93 	int dx;
94 	int dy;
95 
96 	int mD0;
97 	int mD1;
98 
99 	int mA0;
100 	int mA1;
101 
102 	int bp;
103 	int cx;
104 	int si;
105 
106 	int ax;
107 	int bx;
108 
109 	outputTable[numOutput].x = x1;
110 	outputTable[numOutput].y = y1;
111 	numOutput++;
112 
113 	dx = x2 - x1;
114 	dy = y2 - y1;
115 
116 	mD0 = mD1 = 1;
117 
118 	if (dx < 0) {
119 		dx = -dx;
120 		mD0 = -1;
121 	}
122 
123 	if (dy < 0) {
124 		dy = -dy;
125 		mD1 = -1;
126 	}
127 
128 	if (dx < dy) {
129 		mA0 = 0;
130 		bp = dx;
131 		cx = dy;
132 
133 		mA1 = mD1;
134 	} else {
135 		mA1 = 0;
136 		bp = dy;
137 		cx = dx;
138 
139 		mA0 = mD0;
140 	}
141 
142 	bp = bp * 2;
143 	dx = bp - cx;
144 	si = dx - cx;
145 
146 	ax = x1;
147 	bx = y1;
148 
149 	while (--cx) {
150 		if (dx > 0) {
151 			ax += mD0;
152 			bx += mD1;
153 			dx += si;
154 		} else {
155 			ax += mA0;
156 			bx += mA1;
157 			dx += bp;
158 		}
159 
160 		outputTable[numOutput].x = ax;
161 		outputTable[numOutput].y = bx;
162 		numOutput++;
163 
164 	}
165 
166 	flag_obstacle = 0;
167 
168 	return numOutput;
169 }
170 
processActorWalk(MovementEntry & resx_y,int16 * inc_droite,int16 * inc_droite0,int16 * inc_chemin,point * cor_joueur,int16 solution0[NUM_NODES+3][2],int16 * inc_jo1,int16 * inc_jo2,int16 * dir_perso,int16 * inc_jo0,int16 num)171 void processActorWalk(MovementEntry &resx_y, int16 *inc_droite, int16 *inc_droite0,
172 					  int16 *inc_chemin, point* cor_joueur,
173 					  int16 solution0[NUM_NODES + 3][2], int16 *inc_jo1, int16 *inc_jo2,
174 					  int16 *dir_perso, int16 *inc_jo0, int16 num) {
175 	int u = 0;
176 	inc_jo = *inc_jo0;
177 
178 	int i = *inc_chemin;
179 
180 	if (!*inc_droite) {
181 		int x1 = solution0[i][0];
182 		int y1 = solution0[i][1];
183 		i++;
184 		if (solution0[i][0] != -1) {
185 			do {
186 				if (solution0[i][0] != -2) {
187 					int x2 = solution0[i][0];
188 					int y2 = solution0[i][1];
189 					if ((x1 == x2) && (y1 == y2)) {
190 						resx_y.x = -1;
191 						resx_y.y = -1;
192 						freePerso(num);
193 
194 						return;
195 					}
196 
197 					*inc_droite0 = cor_droite(x1, y1, x2, y2, cor_joueur);
198 					*dir_perso = resx_y.direction = direction(x1, y1, x2, y2, *inc_jo1, *inc_jo2);
199 					*inc_jo0 = inc_jo;
200 					u = 1;
201 				} else
202 					i++;
203 
204 			} while (solution0[i][0] != -1 && !u);
205 		}
206 		if (!u) {
207 			resx_y.x = -1;
208 			resx_y.y = -1;
209 			freePerso(num);
210 
211 			return;
212 		}
213 		*inc_chemin = i;
214 	}
215 
216 	resx_y.x = cor_joueur[*inc_droite].x;
217 	resx_y.y = cor_joueur[*inc_droite].y;
218 	resx_y.direction = *dir_perso;
219 	resx_y.zoom = computeZoom(resx_y.y);
220 
221 	getPixel(resx_y.x, resx_y.y);
222 	resx_y.poly = numPoly;
223 
224 	u = subOp23(resx_y.zoom, inc_jo);
225 	if (!u)
226 		u = 1;
227 	*inc_droite += u;
228 
229 	if ((*inc_droite) >= (*inc_droite0)) {
230 		*inc_droite = 0;
231 		resx_y.x = solution0[*inc_chemin][0];
232 		resx_y.y = solution0[*inc_chemin][1];
233 	}
234 
235 }
236 
affiche_chemin(int16 persoIdx,MovementEntry & data)237 void affiche_chemin(int16 persoIdx, MovementEntry &data) {
238 	persoStruct *pPerso = persoTable[persoIdx];
239 
240 	assert(pPerso);
241 
242 	processActorWalk(data, &pPerso->inc_droite, &pPerso->inc_droite0,
243 	                 &pPerso->inc_chemin, pPerso->coordinates, pPerso->solution,
244 	                 &pPerso->inc_jo1, &pPerso->inc_jo2, &pPerso->dir_perso,
245 	                 &pPerso->inc_jo0, persoIdx);
246 }
247 
248 } // End of namespace Cruise
249