18 |
18 |
19 {$INCLUDE "options.inc"} |
19 {$INCLUDE "options.inc"} |
20 |
20 |
21 unit uLandGraphics; |
21 unit uLandGraphics; |
22 interface |
22 interface |
23 uses uFloat, uConsts; |
23 uses uFloat, uConsts, uTypes; |
24 |
24 |
25 type PRangeArray = ^TRangeArray; |
25 type PRangeArray = ^TRangeArray; |
26 TRangeArray = array[0..31] of record |
26 TRangeArray = array[0..31] of record |
27 Left, Right: LongInt; |
27 Left, Right: LongInt; |
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; LandFlag: Word): boolean; |
32 function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean; |
33 function DrawExplosion(X, Y, Radius: LongInt): Longword; |
33 function DrawExplosion(X, Y, Radius: LongInt): Longword; |
34 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
34 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
35 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); |
35 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); |
36 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); |
36 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); |
37 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean); |
37 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean); |
|
38 function LandBackPixel(x, y: LongInt): LongWord; |
38 |
39 |
39 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean; |
40 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean; |
40 |
41 |
41 implementation |
42 implementation |
42 uses SDLh, uMisc, uLand, uLandTexture; |
43 uses SDLh, uLandTexture, uVariables, uUtils, uDebug; |
43 |
44 |
44 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); |
45 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); |
45 var i: LongInt; |
46 var i: LongInt; |
46 begin |
47 begin |
47 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
48 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
48 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
49 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
49 if (Land[y + dy, i] and lfIndestructible) = 0 then |
50 if (Land[y + dy, i] and lfIndestructible) = 0 then |
50 Land[y + dy, i]:= Value; |
51 Land[y + dy, i]:= Value; |
51 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
52 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
52 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
53 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
53 if (Land[y - dy, i] and lfIndestructible) = 0 then |
54 if (Land[y - dy, i] and lfIndestructible) = 0 then |
54 Land[y - dy, i]:= Value; |
55 Land[y - dy, i]:= Value; |
55 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
56 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
56 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
57 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
57 if (Land[y + dx, i] and lfIndestructible) = 0 then |
58 if (Land[y + dx, i] and lfIndestructible) = 0 then |
58 Land[y + dx, i]:= Value; |
59 Land[y + dx, i]:= Value; |
59 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
60 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
60 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
61 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
61 if (Land[y - dx, i] and lfIndestructible) = 0 then |
62 if (Land[y - dx, i] and lfIndestructible) = 0 then |
62 Land[y - dx, i]:= Value; |
63 Land[y - dx, i]:= Value; |
63 end; |
64 end; |
64 |
65 |
65 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean); |
66 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean); |
66 var i: LongInt; |
67 var i: LongInt; |
67 begin |
68 begin |
68 if not doSet then |
69 if not doSet then |
69 begin |
70 begin |
70 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
71 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
71 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
72 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
72 if (Land[y + dy, i] > 0) and (Land[y + dy, i] < 256) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data |
73 if (Land[y + dy, i] > 0) and (Land[y + dy, i] < 256) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data |
73 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
74 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
74 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
75 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
75 if (Land[y - dy, i] > 0) and (Land[y - dy, i] < 256) then dec(Land[y - dy, i]); |
76 if (Land[y - dy, i] > 0) and (Land[y - dy, i] < 256) then dec(Land[y - dy, i]); |
76 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
77 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
77 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
78 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
78 if (Land[y + dx, i] > 0) and (Land[y + dx, i] < 256) then dec(Land[y + dx, i]); |
79 if (Land[y + dx, i] > 0) and (Land[y + dx, i] < 256) then dec(Land[y + dx, i]); |
79 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
80 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
80 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
81 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
81 if (Land[y - dx, i] > 0) and (Land[y - dx, i] < 256) then dec(Land[y - dx, i]); |
82 if (Land[y - dx, i] > 0) and (Land[y - dx, i] < 256) then dec(Land[y - dx, i]); |
82 end else |
83 end else |
83 begin |
84 begin |
84 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
85 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then |
85 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
86 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
86 if (Land[y + dy, i] < 256) then |
87 if (Land[y + dy, i] < 256) then |
87 inc(Land[y + dy, i]); |
88 inc(Land[y + dy, i]); |
88 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
89 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then |
89 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
90 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
90 if (Land[y - dy, i] < 256) then |
91 if (Land[y - dy, i] < 256) then |
91 inc(Land[y - dy, i]); |
92 inc(Land[y - dy, i]); |
92 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
93 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then |
93 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
94 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
94 if (Land[y + dx, i] < 256) then |
95 if (Land[y + dx, i] < 256) then |
95 inc(Land[y + dx, i]); |
96 inc(Land[y + dx, i]); |
96 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
97 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then |
97 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
98 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
98 if (Land[y - dx, i] < 256) then |
99 if (Land[y - dx, i] < 256) then |
99 inc(Land[y - dx, i]); |
100 inc(Land[y - dx, i]); |
100 end |
101 end |
101 end; |
102 end; |
102 |
103 |
143 procedure FillLandCircleLines0(x, y, dx, dy: LongInt); |
144 procedure FillLandCircleLines0(x, y, dx, dy: LongInt); |
144 var i, t: LongInt; |
145 var i, t: LongInt; |
145 begin |
146 begin |
146 t:= y + dy; |
147 t:= y + dy; |
147 if (t and LAND_HEIGHT_MASK) = 0 then |
148 if (t and LAND_HEIGHT_MASK) = 0 then |
148 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
149 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
149 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
150 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
150 if (cReducedQuality and rqBlurryLand) = 0 then |
151 if (cReducedQuality and rqBlurryLand) = 0 then |
151 LandPixels[t, i]:= 0 |
152 LandPixels[t, i]:= 0 |
152 else |
153 else |
153 LandPixels[t div 2, i div 2]:= 0; |
154 LandPixels[t div 2, i div 2]:= 0; |
154 |
155 |
155 t:= y - dy; |
156 t:= y - dy; |
156 if (t and LAND_HEIGHT_MASK) = 0 then |
157 if (t and LAND_HEIGHT_MASK) = 0 then |
157 for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do |
158 for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do |
158 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
159 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
159 if (cReducedQuality and rqBlurryLand) = 0 then |
160 if (cReducedQuality and rqBlurryLand) = 0 then |
160 LandPixels[t, i]:= 0 |
161 LandPixels[t, i]:= 0 |
161 else |
162 else |
162 LandPixels[t div 2, i div 2]:= 0; |
163 LandPixels[t div 2, i div 2]:= 0; |
163 |
164 |
164 t:= y + dx; |
165 t:= y + dx; |
165 if (t and LAND_HEIGHT_MASK) = 0 then |
166 if (t and LAND_HEIGHT_MASK) = 0 then |
166 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
167 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
167 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
168 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
168 if (cReducedQuality and rqBlurryLand) = 0 then |
169 if (cReducedQuality and rqBlurryLand) = 0 then |
169 LandPixels[t, i]:= 0 |
170 LandPixels[t, i]:= 0 |
170 else |
171 else |
171 LandPixels[t div 2, i div 2]:= 0; |
172 LandPixels[t div 2, i div 2]:= 0; |
172 |
173 |
173 t:= y - dx; |
174 t:= y - dx; |
174 if (t and LAND_HEIGHT_MASK) = 0 then |
175 if (t and LAND_HEIGHT_MASK) = 0 then |
175 for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do |
176 for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do |
176 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
177 if (not isMap and ((Land[t, i] and lfIndestructible) = 0)) or ((Land[t, i] and lfBasic) <> 0) then |
177 if (cReducedQuality and rqBlurryLand) = 0 then |
178 if (cReducedQuality and rqBlurryLand) = 0 then |
178 LandPixels[t, i]:= 0 |
179 LandPixels[t, i]:= 0 |
179 else |
180 else |
180 LandPixels[t div 2, i div 2]:= 0; |
181 LandPixels[t div 2, i div 2]:= 0; |
391 inc(dx) |
392 inc(dx) |
392 end; |
393 end; |
393 if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); |
394 if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); |
394 end; |
395 end; |
395 |
396 |
396 tx:= max(X - Radius - 1, 0); |
397 tx:= Max(X - Radius - 1, 0); |
397 dx:= min(X + Radius + 1, LAND_WIDTH) - tx; |
398 dx:= Min(X + Radius + 1, LAND_WIDTH) - tx; |
398 ty:= max(Y - Radius - 1, 0); |
399 ty:= Max(Y - Radius - 1, 0); |
399 dy:= min(Y + Radius + 1, LAND_HEIGHT) - ty; |
400 dy:= Min(Y + Radius + 1, LAND_HEIGHT) - ty; |
400 UpdateLandTexture(tx, dx, ty, dy); |
401 UpdateLandTexture(tx, dx, ty, dy); |
401 DrawExplosion:= cnt |
402 DrawExplosion:= cnt |
402 end; |
403 end; |
403 |
404 |
404 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
405 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); |
405 var tx, ty, i: LongInt; |
406 var tx, ty, i: LongInt; |
406 begin |
407 begin |
407 for i:= 0 to Pred(Count) do |
408 for i:= 0 to Pred(Count) do |
408 begin |
409 begin |
409 for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do |
410 for ty:= Max(y - Radius, 0) to Min(y + Radius, LAND_HEIGHT) do |
410 for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do |
411 for tx:= Max(0, ar^[i].Left - Radius) to Min(LAND_WIDTH, ar^[i].Right + Radius) do |
411 if (Land[ty, tx] and lfBasic) <> 0 then |
412 if (Land[ty, tx] and lfBasic) <> 0 then |
412 if (cReducedQuality and rqBlurryLand) = 0 then |
413 if (cReducedQuality and rqBlurryLand) = 0 then |
413 LandPixels[ty, tx]:= LandBackPixel(tx, ty) |
414 LandPixels[ty, tx]:= LandBackPixel(tx, ty) |
414 else |
415 else |
415 LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty) |
416 LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty) |