28 end; |
28 end; |
29 |
29 |
30 function SweepDirty: boolean; |
30 function SweepDirty: boolean; |
31 function Despeckle(X, Y: LongInt): boolean; |
31 function Despeckle(X, Y: LongInt): boolean; |
32 function CheckLandValue(X, Y: LongInt; Color: Word): boolean; |
32 function CheckLandValue(X, Y: LongInt; Color: Word): boolean; |
33 procedure Despeckle2(X, Y, Threesold: LongInt); |
|
34 procedure DrawExplosion(X, Y, Radius: LongInt); |
33 procedure DrawExplosion(X, Y, Radius: LongInt); |
35 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
34 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
36 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); |
35 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); |
37 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); |
36 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); |
38 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean); |
37 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean); |
39 |
38 |
40 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean; |
39 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean; |
41 |
40 |
42 implementation |
41 implementation |
43 uses SDLh, uMisc, uLand, uLandTexture; |
42 uses SDLh, uMisc, uLand, uLandTexture; |
44 |
|
45 procedure Despeckle2(X, Y, Threesold: LongInt); |
|
46 var |
|
47 i, j: LongInt; |
|
48 x0, x1, y0, y1: LongInt; |
|
49 c: byte; |
|
50 begin |
|
51 // If the pixel has less than Threesold neightbours, it gets erased |
|
52 // Erasing is outwards recursive |
|
53 c := 0; |
|
54 |
|
55 x0 := max(X-1, 0); |
|
56 x1 := min(X+1, LAND_WIDTH - 1); |
|
57 y0 := max(Y-1, 0); |
|
58 y1 := min(Y+1, LAND_HEIGHT - 1); |
|
59 |
|
60 for i:=x0 to x1 do begin |
|
61 for j:=y0 to y1 do begin |
|
62 if Land[j, i]<>0 then begin |
|
63 c := c+1; |
|
64 end; |
|
65 end; |
|
66 end; |
|
67 |
|
68 if c<Threesold then begin |
|
69 Land[Y, X] := 0; |
|
70 LandPixels[Y, X] := 0; |
|
71 for i:=x0 to x1 do begin |
|
72 for j:=y0 to y1 do begin |
|
73 if Land[j, i]<>0 then begin |
|
74 LandPixels[j, i] := cExplosionBorderColor; |
|
75 Despeckle2(i, j, 5); |
|
76 end; |
|
77 end; |
|
78 end; |
|
79 end; |
|
80 UpdateLandTexture(x0, x1-x0, y0, y1-y0); |
|
81 end; |
|
82 |
43 |
83 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); |
44 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); |
84 var i: LongInt; |
45 var i: LongInt; |
85 begin |
46 begin |
86 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
47 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
182 procedure FillLandCircleLines0(x, y, dx, dy: LongInt); |
143 procedure FillLandCircleLines0(x, y, dx, dy: LongInt); |
183 var i: LongInt; |
144 var i: LongInt; |
184 begin |
145 begin |
185 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
146 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
186 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
147 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
187 if Land[y + dy, i] = COLOR_LAND then |
148 if (Land[y + dy, i] <> COLOR_INDESTRUCTIBLE) then |
188 LandPixels[y + dy, i]:= 0; |
149 LandPixels[y + dy, i]:= 0; |
189 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
150 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
190 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
151 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
191 if Land[y - dy, i] = COLOR_LAND then |
152 if (Land[y - dy, i] <> COLOR_INDESTRUCTIBLE) then |
192 LandPixels[y - dy, i]:= 0; |
153 LandPixels[y - dy, i]:= 0; |
193 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
154 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
194 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
155 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
195 if Land[y + dx, i] = COLOR_LAND then |
156 if (Land[y + dx, i] <> COLOR_INDESTRUCTIBLE) then |
196 LandPixels[y + dx, i]:= 0; |
157 LandPixels[y + dx, i]:= 0; |
197 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
158 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
198 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
159 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
199 if Land[y - dx, i] = COLOR_LAND then |
160 if (Land[y - dx, i] <> COLOR_INDESTRUCTIBLE) then |
200 LandPixels[y - dx, i]:= 0; |
161 LandPixels[y - dx, i]:= 0; |
|
162 end; |
|
163 |
|
164 procedure FillLandCircleLinesBG(x, y, dx, dy: LongInt); |
|
165 var i: LongInt; |
|
166 begin |
|
167 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
|
168 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
|
169 if (Land[y + dy, i] = COLOR_LAND) then |
|
170 LandPixels[y + dy, i]:= LandBackPixel(i, y + dy) |
|
171 else |
|
172 if (Land[y + dy, i] = COLOR_OBJECT) then LandPixels[y + dy, i]:= 0; |
|
173 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
|
174 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
|
175 if (Land[y - dy, i] = COLOR_LAND) then |
|
176 LandPixels[y - dy, i]:= LandBackPixel(i, y - dy) |
|
177 else |
|
178 if (Land[y - dy, i] = COLOR_OBJECT) then LandPixels[y - dy, i]:= 0; |
|
179 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
|
180 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
|
181 if (Land[y + dx, i] = COLOR_LAND) then |
|
182 LandPixels[y + dx, i]:= LandBackPixel(i, y + dx) |
|
183 else |
|
184 if (Land[y + dx, i] = COLOR_OBJECT) then LandPixels[y + dx, i]:= 0; |
|
185 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
|
186 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
|
187 if (Land[y - dx, i] = COLOR_LAND) then |
|
188 LandPixels[y - dx, i]:= LandBackPixel(i, y - dx) |
|
189 else |
|
190 if (Land[y - dx, i] = COLOR_OBJECT) then LandPixels[y - dx, i]:= 0; |
201 end; |
191 end; |
202 |
192 |
203 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt); |
193 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt); |
204 var i: LongInt; |
194 var i: LongInt; |
205 begin |
195 begin |
206 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
196 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
207 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
197 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
208 if Land[y + dy, i] = COLOR_LAND then |
198 if (Land[y + dy, i] = COLOR_LAND) or (Land[y + dy, i] = COLOR_OBJECT) then |
209 begin |
199 begin |
210 LandPixels[y + dy, i]:= cExplosionBorderColor; |
200 LandPixels[y + dy, i]:= cExplosionBorderColor; |
211 Despeckle2(i, y + dy, 6); |
201 Despeckle(i, y + dy); |
212 LandDirty[(y + dy) div 32, i div 32]:= 1; |
202 LandDirty[(y + dy) div 32, i div 32]:= 1; |
213 end; |
203 end; |
214 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
204 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
215 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
205 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
216 if Land[y - dy, i] = COLOR_LAND then |
206 if (Land[y - dy, i] = COLOR_LAND) or (Land[y - dy, i] = COLOR_OBJECT) then |
217 begin |
207 begin |
218 LandPixels[y - dy, i]:= cExplosionBorderColor; |
208 LandPixels[y - dy, i]:= cExplosionBorderColor; |
219 Despeckle2(i, y - dy, 6); |
209 Despeckle(i, y - dy); |
220 LandDirty[(y - dy) div 32, i div 32]:= 1; |
210 LandDirty[(y - dy) div 32, i div 32]:= 1; |
221 end; |
211 end; |
222 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
212 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
223 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
213 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
224 if Land[y + dx, i] = COLOR_LAND then |
214 if (Land[y + dx, i] = COLOR_LAND) or (Land[y + dx, i] = COLOR_OBJECT) then |
225 begin |
215 begin |
226 LandPixels[y + dx, i]:= cExplosionBorderColor; |
216 LandPixels[y + dx, i]:= cExplosionBorderColor; |
227 Despeckle2(i, y + dx, 6); |
217 Despeckle(i, y + dx); |
228 LandDirty[(y + dx) div 32, i div 32]:= 1; |
218 LandDirty[(y + dx) div 32, i div 32]:= 1; |
229 end; |
219 end; |
230 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
220 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
231 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
221 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
232 if Land[y - dx, i] = COLOR_LAND then |
222 if (Land[y - dx, i] = COLOR_LAND) or (Land[y - dx, i] = COLOR_OBJECT) then |
233 begin |
223 begin |
234 LandPixels[y - dx, i]:= cExplosionBorderColor; |
224 LandPixels[y - dx, i]:= cExplosionBorderColor; |
235 Despeckle2(i, y - dy, 6); |
225 Despeckle(i, y - dy); |
236 LandDirty[(y - dx) div 32, i div 32]:= 1; |
226 LandDirty[(y - dx) div 32, i div 32]:= 1; |
237 end; |
227 end; |
238 end; |
228 end; |
239 |
229 |
240 procedure DrawExplosion(X, Y, Radius: LongInt); |
230 procedure DrawExplosion(X, Y, Radius: LongInt); |
241 var dx, dy, ty, tx, d: LongInt; |
231 var dx, dy, ty, tx, d: LongInt; |
242 begin |
232 begin |
243 dx:= 0; |
233 |
244 dy:= Radius; |
234 // draw background land texture |
245 d:= 3 - 2 * Radius; |
235 begin |
246 while (dx < dy) do |
236 dx:= 0; |
247 begin |
237 dy:= Radius; |
248 FillLandCircleLines0(x, y, dx, dy); |
238 d:= 3 - 2 * Radius; |
249 if (d < 0) |
239 |
250 then d:= d + 4 * dx + 6 |
240 while (dx < dy) do |
251 else begin |
241 begin |
252 d:= d + 4 * (dx - dy) + 10; |
242 FillLandCircleLinesBG(x, y, dx, dy); |
253 dec(dy) |
243 if (d < 0) |
254 end; |
244 then d:= d + 4 * dx + 6 |
255 inc(dx) |
245 else begin |
256 end; |
246 d:= d + 4 * (dx - dy) + 10; |
257 if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); |
247 dec(dy) |
|
248 end; |
|
249 inc(dx) |
|
250 end; |
|
251 if (dx = dy) then FillLandCircleLinesBG(x, y, dx, dy); |
|
252 end; |
|
253 |
|
254 // draw a hole in land |
|
255 if Radius > 25 then |
|
256 begin |
|
257 dx:= 0; |
|
258 dy:= Radius - 25; |
|
259 d:= 3 - 2 * dy; |
|
260 |
|
261 while (dx < dy) do |
|
262 begin |
|
263 FillLandCircleLines0(x, y, dx, dy); |
|
264 if (d < 0) |
|
265 then d:= d + 4 * dx + 6 |
|
266 else begin |
|
267 d:= d + 4 * (dx - dy) + 10; |
|
268 dec(dy) |
|
269 end; |
|
270 inc(dx) |
|
271 end; |
|
272 if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); |
|
273 end; |
|
274 |
258 // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function |
275 // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function |
259 FillRoundInLand(X, Y, Radius, 0); |
276 FillRoundInLand(X, Y, Radius, 0); |
260 inc(Radius, 4); |
277 |
261 dx:= 0; |
278 // draw explosion border |
262 dy:= Radius; |
279 begin |
263 d:= 3 - 2 * Radius; |
280 inc(Radius, 4); |
264 while (dx < dy) do |
281 dx:= 0; |
265 begin |
282 dy:= Radius; |
266 FillLandCircleLinesEBC(x, y, dx, dy); |
283 d:= 3 - 2 * Radius; |
267 if (d < 0) |
284 while (dx < dy) do |
268 then d:= d + 4 * dx + 6 |
285 begin |
269 else begin |
286 FillLandCircleLinesEBC(x, y, dx, dy); |
270 d:= d + 4 * (dx - dy) + 10; |
287 if (d < 0) |
271 dec(dy) |
288 then d:= d + 4 * dx + 6 |
272 end; |
289 else begin |
273 inc(dx) |
290 d:= d + 4 * (dx - dy) + 10; |
274 end; |
291 dec(dy) |
275 if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); |
292 end; |
|
293 inc(dx) |
|
294 end; |
|
295 if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); |
|
296 end; |
276 |
297 |
277 tx:= max(X - Radius - 1, 0); |
298 tx:= max(X - Radius - 1, 0); |
278 dx:= min(X + Radius + 1, LAND_WIDTH) - tx; |
299 dx:= min(X + Radius + 1, LAND_WIDTH) - tx; |
279 ty:= max(Y - Radius - 1, 0); |
300 ty:= max(Y - Radius - 1, 0); |
280 dy:= min(Y + Radius + 1, LAND_HEIGHT) - ty; |
301 dy:= min(Y + Radius + 1, LAND_HEIGHT) - ty; |