author  koda 
Thu, 18 Mar 2010 02:27:46 +0000  
changeset 3017  4a52e0705011 
parent 2981  d0471586a616 
child 3038  4e48c276a468 
permissions  rwrr 
4  1 
(* 
1066  2 
* Hedgewars, a free turn based strategy game 
883  3 
* Copyright (c) 20052008 Andrey Korotaev <unC0Rr@gmail.com> 
4  4 
* 
183  5 
* This program is free software; you can redistribute it and/or modify 
6 
* it under the terms of the GNU General Public License as published by 

7 
* the Free Software Foundation; version 2 of the License 

4  8 
* 
183  9 
* This program is distributed in the hope that it will be useful, 
10 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 

11 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12 
* GNU General Public License for more details. 

4  13 
* 
183  14 
* You should have received a copy of the GNU General Public License 
15 
* along with this program; if not, write to the Free Software 

16 
* Foundation, Inc., 59 Temple Place  Suite 330, Boston, MA 021111307, USA 

4  17 
*) 
18 

2599  19 
{$INCLUDE "options.inc"} 
2587
0dfa56a8513c
fix a segfault in the iphone simulator by moving options.inc at the beginning of the file
koda
parents:
2376
diff
changeset

20 

4  21 
unit uLand; 
22 
interface 

2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

23 
uses SDLh, uLandTemplates, uFloat, uConsts, 
2152  24 
{$IFDEF GLES11} 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

25 
gles11; 
1906  26 
{$ELSE} 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

27 
GL; 
1906  28 
{$ENDIF} 
2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

29 

1760  30 
type TLandArray = packed array[0 .. LAND_HEIGHT  1, 0 .. LAND_WIDTH  1] of LongWord; 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

31 
TCollisionArray = packed array[0 .. LAND_HEIGHT  1, 0 .. LAND_WIDTH  1] of Word; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

32 
TPreview = packed array[0..127, 0..31] of byte; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

33 
TDirtyTag = packed array[0 .. LAND_HEIGHT div 32  1, 0 .. LAND_WIDTH div 32  1] of byte; 
4  34 

2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

35 
var Land: TCollisionArray; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

36 
LandPixels: TLandArray; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

37 
LandDirty: TDirtyTag; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

38 
hasBorder: boolean; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

39 
hasGirders: boolean; 
2981  40 
isMap: boolean; 
2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

41 
playHeight, playWidth, leftX, rightX, topY, MaxHedgehogs: Longword; // idea is that a template can specify height/width. Or, a map, a height/width by the dimensions of the image. If the map has pixels near top of image, it triggers border. 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

42 
LandBackSurface: PSDL_Surface; 
4  43 

2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

44 
procedure init_uLand; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

45 
procedure free_uLand; 
37  46 
procedure GenMap; 
766  47 
function GenPreview: TPreview; 
367  48 
procedure CheckLandDigest(s: shortstring); 
2692
ce9992075118
better network support + initial work for returning to frontend
koda
parents:
2665
diff
changeset

49 
function LandBackPixel(x, y: LongInt): LongWord; 
4  50 

51 
implementation 

1806  52 
uses uConsole, uStore, uMisc, uRandom, uTeams, uLandObjects, uSHA, uIO, uAmmos, uLandTexture; 
4  53 

54 
type TPixAr = record 

55 
Count: Longword; 

22  56 
ar: array[0..Pred(cMaxEdgePoints)] of TPoint; 
4  57 
end; 
58 

37  59 
procedure LogLandDigest; 
316  60 
var ctx: TSHA1Context; 
61 
dig: TSHA1Digest; 

62 
s: shortstring; 

37  63 
begin 
316  64 
SHA1Init(ctx); 
2157  65 
SHA1UpdateLongwords(ctx, @Land, sizeof(Land) div 4); 
316  66 
dig:= SHA1Final(ctx); 
367  67 
s:='M{'+inttostr(dig[0])+':' 
316  68 
+inttostr(dig[1])+':' 
69 
+inttostr(dig[2])+':' 

70 
+inttostr(dig[3])+':' 

71 
+inttostr(dig[4])+'}'; 

699  72 
CheckLandDigest(s); 
367  73 
SendIPCRaw(@s[0], Length(s) + 1) 
74 
end; 

75 

76 
procedure CheckLandDigest(s: shortstring); 

77 
const digest: shortstring = ''; 

78 
begin 

368  79 
{$IFDEF DEBUGFILE} 
80 
AddFileLog('CheckLandDigest: ' + s); 

81 
{$ENDIF} 

367  82 
if digest = '' then 
83 
digest:= s 

84 
else 

700  85 
TryDo(s = digest, 'Different maps generated, sorry', true) 
37  86 
end; 
87 

371  88 
procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword); 
358  89 
var 
371  90 
eX, eY, dX, dY: LongInt; 
91 
i, sX, sY, x, y, d: LongInt; 

358  92 
begin 
93 
eX:= 0; 

94 
eY:= 0; 

95 
dX:= X2  X1; 

96 
dY:= Y2  Y1; 

97 

98 
if (dX > 0) then sX:= 1 

99 
else 

100 
if (dX < 0) then 

101 
begin 

102 
sX:= 1; 

103 
dX:= dX 

104 
end else sX:= dX; 

105 

106 
if (dY > 0) then sY:= 1 

107 
else 

108 
if (dY < 0) then 

109 
begin 

110 
sY:= 1; 

111 
dY:= dY 

112 
end else sY:= dY; 

113 

114 
if (dX > dY) then d:= dX 

115 
else d:= dY; 

116 

117 
x:= X1; 

118 
y:= Y1; 

2376  119 

358  120 
for i:= 0 to d do 
121 
begin 

122 
inc(eX, dX); 

123 
inc(eY, dY); 

124 
if (eX > d) then 

125 
begin 

126 
dec(eX, d); 

127 
inc(x, sX); 

128 
end; 

129 
if (eY > d) then 

130 
begin 

131 
dec(eY, d); 

132 
inc(y, sY); 

133 
end; 

364  134 

1753  135 
if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then 
358  136 
Land[y, x]:= Color; 
137 
end 

138 
end; 

139 

365  140 
procedure DrawEdge(var pa: TPixAr; Color: Longword); 
371  141 
var i: LongInt; 
4  142 
begin 
365  143 
i:= 0; 
4  144 
with pa do 
371  145 
while i < LongInt(Count)  1 do 
365  146 
if (ar[i + 1].X = NTPX) then inc(i, 2) 
147 
else begin 

148 
DrawLine(ar[i].x, ar[i].y, ar[i + 1].x, ar[i + 1].y, Color); 

149 
inc(i) 

150 
end 

22  151 
end; 
152 

365  153 
procedure Vector(p1, p2, p3: TPoint; var Vx, Vy: hwFloat); 
154 
var d1, d2, d: hwFloat; 

364  155 
begin 
498  156 
Vx:= int2hwFloat(p1.X  p3.X); 
157 
Vy:= int2hwFloat(p1.Y  p3.Y); 

158 
d:= DistanceI(p2.X  p1.X, p2.Y  p1.Y); 

159 
d1:= DistanceI(p2.X  p3.X, p2.Y  p3.Y); 

365  160 
d2:= Distance(Vx, Vy); 
161 
if d1 < d then d:= d1; 

162 
if d2 < d then d:= d2; 

163 
d:= d * _1div3; 

164 
if d2.QWordValue = 0 then 

165 
begin 

498  166 
Vx:= _0; 
167 
Vy:= _0 

365  168 
end else 
169 
begin 

498  170 
d2:= _1 / d2; 
365  171 
Vx:= Vx * d2; 
172 
Vy:= Vy * d2; 

173 

174 
Vx:= Vx * d; 

175 
Vy:= Vy * d 

176 
end 

177 
end; 

178 

371  179 
procedure AddLoopPoints(var pa, opa: TPixAr; StartI, EndI: LongInt; Delta: hwFloat); 
180 
var i, pi, ni: LongInt; 

365  181 
NVx, NVy, PVx, PVy: hwFloat; 
498  182 
x1, x2, y1, y2: LongInt; 
183 
tsq, tcb, t, r1, r2, r3, cx1, cx2, cy1, cy2: hwFloat; 

371  184 
X, Y: LongInt; 
365  185 
begin 
186 
pi:= EndI; 

187 
i:= StartI; 

188 
ni:= Succ(StartI); 

189 
Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy); 

190 
repeat 

191 
inc(pi); 

192 
if pi > EndI then pi:= StartI; 

193 
inc(i); 

194 
if i > EndI then i:= StartI; 

195 
inc(ni); 

196 
if ni > EndI then ni:= StartI; 

197 
PVx:= NVx; 

198 
PVy:= NVy; 

199 
Vector(opa.ar[pi], opa.ar[i], opa.ar[ni], NVx, NVy); 

200 

201 
x1:= opa.ar[pi].x; 

202 
y1:= opa.ar[pi].y; 

203 
x2:= opa.ar[i].x; 

204 
y2:= opa.ar[i].y; 

498  205 
cx1:= int2hwFloat(x1)  PVx; 
206 
cy1:= int2hwFloat(y1)  PVy; 

207 
cx2:= int2hwFloat(x2) + NVx; 

208 
cy2:= int2hwFloat(y2) + NVy; 

209 
t:= _0; 

364  210 
while t.Round = 0 do 
211 
begin 

212 
tsq:= t * t; 

213 
tcb:= tsq * t; 

498  214 
r1:= (_1  t*3 + tsq*3  tcb); 
215 
r2:= ( t*3  tsq*6 + tcb*3); 

216 
r3:= ( tsq*3  tcb*3); 

430  217 
X:= hwRound(r1 * x1 + r2 * cx1 + r3 * cx2 + tcb * x2); 
218 
Y:= hwRound(r1 * y1 + r2 * cy1 + r3 * cy2 + tcb * y2); 

364  219 
t:= t + Delta; 
220 
pa.ar[pa.Count].x:= X; 

221 
pa.ar[pa.Count].y:= Y; 

222 
inc(pa.Count); 

223 
TryDo(pa.Count <= cMaxEdgePoints, 'Edge points overflow', true) 

224 
end; 

365  225 
until i = StartI; 
226 
pa.ar[pa.Count].x:= opa.ar[StartI].X; 

227 
pa.ar[pa.Count].y:= opa.ar[StartI].Y; 

364  228 
inc(pa.Count) 
229 
end; 

230 

365  231 
procedure BezierizeEdge(var pa: TPixAr; Delta: hwFloat); 
495  232 
var i, StartLoop: LongInt; 
365  233 
opa: TPixAr; 
234 
begin 

235 
opa:= pa; 

236 
pa.Count:= 0; 

237 
i:= 0; 

238 
StartLoop:= 0; 

371  239 
while i < LongInt(opa.Count) do 
365  240 
if (opa.ar[i + 1].X = NTPX) then 
241 
begin 

242 
AddLoopPoints(pa, opa, StartLoop, i, Delta); 

243 
inc(i, 2); 

244 
StartLoop:= i; 

245 
pa.ar[pa.Count].X:= NTPX; 

246 
inc(pa.Count); 

247 
end else inc(i) 

248 
end; 

249 

371  250 
procedure FillLand(x, y: LongInt); 
4  251 
var Stack: record 
252 
Count: Longword; 

253 
points: array[0..8192] of record 

371  254 
xl, xr, y, dir: LongInt; 
4  255 
end 
256 
end; 

257 

371  258 
procedure Push(_xl, _xr, _y, _dir: LongInt); 
4  259 
begin 
75  260 
TryDo(Stack.Count <= 8192, 'FillLand: stack overflow', true); 
4  261 
_y:= _y + _dir; 
1760  262 
if (_y < 0) or (_y >= LAND_HEIGHT) then exit; 
4  263 
with Stack.points[Stack.Count] do 
264 
begin 

265 
xl:= _xl; 

266 
xr:= _xr; 

267 
y:= _y; 

268 
dir:= _dir 

269 
end; 

75  270 
inc(Stack.Count) 
4  271 
end; 
272 

371  273 
procedure Pop(var _xl, _xr, _y, _dir: LongInt); 
4  274 
begin 
275 
dec(Stack.Count); 

276 
with Stack.points[Stack.Count] do 

277 
begin 

278 
_xl:= xl; 

279 
_xr:= xr; 

280 
_y:= y; 

281 
_dir:= dir 

282 
end 

283 
end; 

284 

371  285 
var xl, xr, dir: LongInt; 
351  286 
begin 
4  287 
Stack.Count:= 0; 
288 
xl:= x  1; 

289 
xr:= x; 

23  290 
Push(xl, xr, y, 1); 
291 
Push(xl, xr, y, 1); 

4  292 
while Stack.Count > 0 do 
293 
begin 

294 
Pop(xl, xr, y, dir); 

51  295 
while (xl > 0) and (Land[y, xl] <> 0) do dec(xl); 
1760  296 
while (xr < LAND_WIDTH  1) and (Land[y, xr] <> 0) do inc(xr); 
4  297 
while (xl < xr) do 
298 
begin 

51  299 
while (xl <= xr) and (Land[y, xl] = 0) do inc(xl); 
4  300 
x:= xl; 
51  301 
while (xl <= xr) and (Land[y, xl] <> 0) do 
4  302 
begin 
51  303 
Land[y, xl]:= 0; 
4  304 
inc(xl) 
305 
end; 

22  306 
if x < xl then 
307 
begin 

308 
Push(x, Pred(xl), y, dir); 

309 
Push(x, Pred(xl), y,dir); 

310 
end; 

4  311 
end; 
312 
end; 

313 
end; 

314 

2647  315 
function LandBackPixel(x, y: LongInt): LongWord; 
316 
var p: PLongWordArray; 

317 
begin 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

318 
if LandBackSurface = nil then LandBackPixel:= 0 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

319 
else 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

320 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

321 
p:= LandBackSurface^.pixels; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

322 
LandBackPixel:= p^[LandBackSurface^.w * (y mod LandBackSurface^.h) + (x mod LandBackSurface^.w)];// or $FF000000; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

323 
end 
2647  324 
end; 
325 

4  326 
procedure ColorizeLand(Surface: PSDL_Surface); 
327 
var tmpsurf: PSDL_Surface; 

1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

328 
r, rr: TSDL_Rect; 
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

329 
x, yd, yu: LongInt; 
4  330 
begin 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

331 
tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/LandTex', ifCritical or ifIgnoreCaps); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

332 
r.y:= 0; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

333 
while r.y < LAND_HEIGHT do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

334 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

335 
r.x:= 0; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

336 
while r.x < LAND_WIDTH do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

337 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

338 
SDL_UpperBlit(tmpsurf, nil, Surface, @r); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

339 
inc(r.x, tmpsurf^.w) 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

340 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

341 
inc(r.y, tmpsurf^.h) 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

342 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

343 
SDL_FreeSurface(tmpsurf); 
4  344 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

345 
// freed in free_uLand() below 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

346 
LandBackSurface:= LoadImage(Pathz[ptCurrTheme] + '/LandBackTex', ifIgnoreCaps or ifTransparent); 
2647  347 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

348 
tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Border', ifCritical or ifIgnoreCaps or ifTransparent); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

349 
for x:= 0 to LAND_WIDTH  1 do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

350 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

351 
yd:= LAND_HEIGHT  1; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

352 
repeat 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

353 
while (yd > 0) and (Land[yd, x] = 0) do dec(yd); 
2376  354 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

355 
if (yd < 0) then yd:= 0; 
1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

356 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

357 
while (yd < LAND_HEIGHT) and (Land[yd, x] <> 0) do inc(yd); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

358 
dec(yd); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

359 
yu:= yd; 
2376  360 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

361 
while (yu > 0 ) and (Land[yu, x] <> 0) do dec(yu); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

362 
while (yu < yd ) and (Land[yu, x] = 0) do inc(yu); 
2376  363 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

364 
if (yd < LAND_HEIGHT  1) and ((yd  yu) >= 16) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

365 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

366 
rr.x:= x; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

367 
rr.y:= yd  15; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

368 
r.x:= x mod tmpsurf^.w; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

369 
r.y:= 16; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

370 
r.w:= 1; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

371 
r.h:= 16; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

372 
SDL_UpperBlit(tmpsurf, @r, Surface, @rr); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

373 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

374 
if (yu > 0) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

375 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

376 
rr.x:= x; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

377 
rr.y:= yu; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

378 
r.x:= x mod tmpsurf^.w; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

379 
r.y:= 0; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

380 
r.w:= 1; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

381 
r.h:= min(16, yd  yu + 1); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

382 
SDL_UpperBlit(tmpsurf, @r, Surface, @rr); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

383 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

384 
yd:= yu  1; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

385 
until yd < 0; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

386 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

387 
SDL_FreeSurface(tmpsurf); 
4  388 
end; 
389 

358  390 
procedure SetPoints(var Template: TEdgeTemplate; var pa: TPixAr); 
371  391 
var i: LongInt; 
22  392 
begin 
23  393 
with Template do 
394 
begin 

358  395 
pa.Count:= BasePointsCount; 
396 
for i:= 0 to pred(pa.Count) do 

23  397 
begin 
371  398 
pa.ar[i].x:= BasePoints^[i].x + LongInt(GetRandom(BasePoints^[i].w)); 
1792  399 
if pa.ar[i].x <> NTPX then 
400 
pa.ar[i].x:= pa.ar[i].x + ((LAND_WIDTH  Template.TemplateWidth) div 2); 

1776  401 
pa.ar[i].y:= BasePoints^[i].y + LongInt(GetRandom(BasePoints^[i].h)) + LAND_HEIGHT  Template.TemplateHeight 
23  402 
end; 
1183
540cea859395
Step 4: repair girder rendering (girder is 32bit now)
unc0rr
parents:
1182
diff
changeset

403 

358  404 
if canMirror then 
360  405 
if getrandom(2) = 0 then 
358  406 
begin 
407 
for i:= 0 to pred(BasePointsCount) do 

365  408 
if pa.ar[i].x <> NTPX then 
1760  409 
pa.ar[i].x:= LAND_WIDTH  1  pa.ar[i].x; 
358  410 
for i:= 0 to pred(FillPointsCount) do 
1760  411 
FillPoints^[i].x:= LAND_WIDTH  1  FillPoints^[i].x; 
358  412 
end; 
22  413 

2338
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

414 
(* Experiment in making this option more useful 
2376  415 
if ((not isNegative) and (cTemplateFilter = 4)) or 
2338
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

416 
(canFlip and (getrandom(2) = 0)) then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

417 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

418 
for i:= 0 to pred(BasePointsCount) do 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

419 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

420 
pa.ar[i].y:= LAND_HEIGHT  1  pa.ar[i].y + (LAND_HEIGHT  TemplateHeight) * 2; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

421 
if pa.ar[i].y > LAND_HEIGHT  1 then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

422 
pa.ar[i].y:= LAND_HEIGHT  1; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

423 
end; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

424 
for i:= 0 to pred(FillPointsCount) do 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

425 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

426 
FillPoints^[i].y:= LAND_HEIGHT  1  FillPoints^[i].y + (LAND_HEIGHT  TemplateHeight) * 2; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

427 
if FillPoints^[i].y > LAND_HEIGHT  1 then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

428 
FillPoints^[i].y:= LAND_HEIGHT  1; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

429 
end; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

430 
end; 
2376  431 
end 
2338
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

432 
*) 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

433 
// template recycling. Pull these off the floor a bit 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

434 
if (not isNegative) and (cTemplateFilter = 4) then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

435 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

436 
for i:= 0 to pred(BasePointsCount) do 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

437 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

438 
dec(pa.ar[i].y, 100); 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

439 
if pa.ar[i].y < 0 then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

440 
pa.ar[i].y:= 0; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

441 
end; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

442 
for i:= 0 to pred(FillPointsCount) do 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

443 
begin 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

444 
dec(FillPoints^[i].y, 100); 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

445 
if FillPoints^[i].y < 0 then 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

446 
FillPoints^[i].y:= 0; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

447 
end; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

448 
end; 
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

449 

8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

450 
if (canFlip and (getrandom(2) = 0)) then 
358  451 
begin 
452 
for i:= 0 to pred(BasePointsCount) do 

1760  453 
pa.ar[i].y:= LAND_HEIGHT  1  pa.ar[i].y; 
358  454 
for i:= 0 to pred(FillPointsCount) do 
1760  455 
FillPoints^[i].y:= LAND_HEIGHT  1  FillPoints^[i].y; 
358  456 
end; 
457 
end 

4  458 
end; 
67  459 

561  460 
function CheckIntersect(V1, V2, V3, V4: TPoint): boolean; 
461 
var c1, c2, dm: LongInt; 

462 
begin 

463 
dm:= (V4.y  V3.y) * (V2.x  V1.x)  (V4.x  V3.x) * (V2.y  V1.y); 

464 
c1:= (V4.x  V3.x) * (V1.y  V3.y)  (V4.y  V3.y) * (V1.x  V3.x); 

465 
if dm = 0 then exit(false); 

466 

467 
c2:= (V2.x  V3.x) * (V1.y  V3.y)  (V2.y  V3.y) * (V1.x  V3.x); 

468 
if dm > 0 then 

469 
begin 

470 
if (c1 < 0) or (c1 > dm) then exit(false); 

471 
if (c2 < 0) or (c2 > dm) then exit(false) 

472 
end else 

473 
begin 

474 
if (c1 > 0) or (c1 < dm) then exit(false); 

475 
if (c2 > 0) or (c2 < dm) then exit(false) 

476 
end; 

477 

478 
//AddFileLog('1 (' + inttostr(V1.x) + ',' + inttostr(V1.y) + ')x(' + inttostr(V2.x) + ',' + inttostr(V2.y) + ')'); 

479 
//AddFileLog('2 (' + inttostr(V3.x) + ',' + inttostr(V3.y) + ')x(' + inttostr(V4.x) + ',' + inttostr(V4.y) + ')'); 

480 
CheckIntersect:= true 

481 
end; 

482 

483 
function CheckSelfIntersect(var pa: TPixAr; ind: Longword): boolean; 

484 
var i: Longword; 

485 
begin 

486 
if (ind <= 0) or (ind >= Pred(pa.Count)) then exit(false); 

487 
for i:= 1 to pa.Count  3 do 

488 
if (i <= ind  1) or (i >= ind + 2) then 

489 
begin 

490 
if (i <> ind  1) and 

491 
CheckIntersect(pa.ar[ind], pa.ar[ind  1], pa.ar[i], pa.ar[i  1]) then exit(true); 

492 
if (i <> ind + 2) and 

493 
CheckIntersect(pa.ar[ind], pa.ar[ind + 1], pa.ar[i], pa.ar[i  1]) then exit(true); 

494 
end; 

495 
CheckSelfIntersect:= false 

496 
end; 

497 

429  498 
procedure RandomizePoints(var pa: TPixAr); 
364  499 
const cEdge = 55; 
561  500 
cMinDist = 8; 
371  501 
var radz: array[0..Pred(cMaxEdgePoints)] of LongInt; 
561  502 
i, k, dist, px, py: LongInt; 
364  503 
begin 
504 
radz[0]:= 0; 

505 
for i:= 0 to Pred(pa.Count) do 

506 
with pa.ar[i] do 

365  507 
if x <> NTPX then 
508 
begin 

1760  509 
radz[i]:= Min(Max(x  cEdge, 0), Max(LAND_WIDTH  cEdge  x, 0)); 
510 
radz[i]:= Min(radz[i], Min(Max(y  cEdge, 0), Max(LAND_HEIGHT  cEdge  y, 0))); 

365  511 
if radz[i] > 0 then 
512 
for k:= 0 to Pred(i) do 

364  513 
begin 
429  514 
dist:= Max(abs(x  pa.ar[k].x), abs(y  pa.ar[k].y)); 
365  515 
radz[k]:= Max(0, Min((dist  cMinDist) div 2, radz[k])); 
516 
radz[i]:= Max(0, Min(dist  radz[k]  cMinDist, radz[i])) 

517 
end 

518 
end; 

364  519 

520 
for i:= 0 to Pred(pa.Count) do 

521 
with pa.ar[i] do 

1753  522 
if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then 
364  523 
begin 
561  524 
px:= x; 
525 
py:= y; 

371  526 
x:= x + LongInt(GetRandom(7)  3) * (radz[i] * 5 div 7) div 3; 
561  527 
y:= y + LongInt(GetRandom(7)  3) * (radz[i] * 5 div 7) div 3; 
528 
if CheckSelfIntersect(pa, i) then 

529 
begin 

530 
x:= px; 

531 
y:= py 

532 
end; 

364  533 
end 
67  534 
end; 
535 

364  536 

23  537 
procedure GenBlank(var Template: TEdgeTemplate); 
4  538 
var pa: TPixAr; 
23  539 
i: Longword; 
155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

540 
y, x: Longword; 
4  541 
begin 
1760  542 
for y:= 0 to LAND_HEIGHT  1 do 
543 
for x:= 0 to LAND_WIDTH  1 do 

155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

544 
Land[y, x]:= COLOR_LAND; 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

545 

358  546 
SetPoints(Template, pa); 
429  547 
for i:= 1 to Template.BezierizeCount do 
548 
begin 

431  549 
BezierizeEdge(pa, _0_5); 
561  550 
RandomizePoints(pa); 
429  551 
RandomizePoints(pa) 
552 
end; 

553 
for i:= 1 to Template.RandPassesCount do RandomizePoints(pa); 

365  554 
BezierizeEdge(pa, _0_1); 
27  555 

365  556 
DrawEdge(pa, 0); 
27  557 

358  558 
with Template do 
23  559 
for i:= 0 to pred(FillPointsCount) do 
560 
with FillPoints^[i] do 

89  561 
FillLand(x, y); 
562 

1773  563 
DrawEdge(pa, COLOR_LAND); 
564 

1792  565 
MaxHedgehogs:= Template.MaxHedgehogs; 
1776  566 
hasGirders:= Template.hasGirders; 
567 
playHeight:= Template.TemplateHeight; 

568 
playWidth:= Template.TemplateWidth; 

569 
leftX:= ((LAND_WIDTH  playWidth) div 2); 

570 
rightX:= (playWidth + ((LAND_WIDTH  playWidth) div 2))  1; 

571 
topY:= LAND_HEIGHT  playHeight; 

572 

1797  573 
// force to only cavern even if a cavern map is invertable if cTemplateFilter = 4 ? 
2376  574 
if (cTemplateFilter = 4) or 
2338
8f6508c97f3f
An experiment with increasing number of caves by selecting a few potential noncave maps and adding to the cave map array. Ones selected here might not actually be that playable as caves.
nemo
parents:
2308
diff
changeset

575 
(Template.canInvert and (getrandom(2) = 0)) or 
2376  576 
(not Template.canInvert and Template.isNegative) then 
1776  577 
begin 
578 
hasBorder:= true; 

1773  579 
for y:= 0 to LAND_HEIGHT  1 do 
580 
for x:= 0 to LAND_WIDTH  1 do 

1776  581 
if (y < topY) or (x < leftX) or (x > rightX) then 
582 
Land[y, x]:= 0 

583 
else 

584 
begin 

585 
if Land[y, x] = 0 then 

586 
Land[y, x]:= COLOR_LAND 

587 
else if Land[y, x] = COLOR_LAND then 

588 
Land[y, x]:= 0; 

589 
end; 

590 
end; 

23  591 
end; 
592 

371  593 
function SelectTemplate: LongInt; 
161  594 
begin 
1797  595 
case cTemplateFilter of 
596 
0: begin 

597 
SelectTemplate:= getrandom(Succ(High(EdgeTemplates))); 

598 
end; 

599 
1: begin 

600 
SelectTemplate:= SmallTemplates[getrandom(Succ(High(SmallTemplates)))]; 

601 
end; 

602 
2: begin 

603 
SelectTemplate:= MediumTemplates[getrandom(Succ(High(MediumTemplates)))]; 

604 
end; 

605 
3: begin 

606 
SelectTemplate:= LargeTemplates[getrandom(Succ(High(LargeTemplates)))]; 

607 
end; 

608 
4: begin 

609 
SelectTemplate:= CavernTemplates[getrandom(Succ(High(CavernTemplates)))]; 

610 
end; 

611 
5: begin 

612 
SelectTemplate:= WackyTemplates[getrandom(Succ(High(WackyTemplates)))]; 

613 
end; 

614 
end; 

615 
WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter)); 

161  616 
end; 
617 

1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

618 
procedure LandSurface2LandPixels(Surface: PSDL_Surface); 
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

619 
var x, y: LongInt; 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

620 
p: PLongwordArray; 
1180
e56317fdf78d
Start implementing support for 32bit sprites concerned in map generation process.
unc0rr
parents:
1085
diff
changeset

621 
begin 
1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

622 
TryDo(Surface <> nil, 'Assert (LandSurface <> nil) failed', true); 
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

623 

e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

624 
if SDL_MustLock(Surface) then 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

625 
SDLTry(SDL_LockSurface(Surface) >= 0, true); 
1180
e56317fdf78d
Start implementing support for 32bit sprites concerned in map generation process.
unc0rr
parents:
1085
diff
changeset

626 

1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

627 
p:= Surface^.pixels; 
1760  628 
for y:= 0 to LAND_HEIGHT  1 do 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

629 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

630 
for x:= 0 to LAND_WIDTH  1 do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

631 
if Land[y, x] <> 0 then LandPixels[y, x]:= p^[x] or AMask; 
2376  632 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

633 
p:= @(p^[Surface^.pitch div 4]); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

634 
end; 
1180
e56317fdf78d
Start implementing support for 32bit sprites concerned in map generation process.
unc0rr
parents:
1085
diff
changeset

635 

1182
e2e13aa055c1
Step 3: Maps are rendered correctly, but without objects yet
unc0rr
parents:
1181
diff
changeset

636 
if SDL_MustLock(Surface) then 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

637 
SDL_UnlockSurface(Surface); 
1754  638 
end; 
639 

640 
procedure GenLandSurface; 

641 
var tmpsurf: PSDL_Surface; 

642 
begin 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

643 
WriteLnToConsole('Generating land...'); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

644 
GenBlank(EdgeTemplates[SelectTemplate]); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

645 
AddProgress(); 
1754  646 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

647 
tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, LAND_WIDTH, LAND_HEIGHT, 32, RMask, GMask, BMask, 0); 
1754  648 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

649 
TryDo(tmpsurf <> nil, 'Error creating preland surface', true); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

650 
ColorizeLand(tmpsurf); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

651 
AddOnLandObjects(tmpsurf); 
1754  652 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

653 
LandSurface2LandPixels(tmpsurf); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

654 
SDL_FreeSurface(tmpsurf); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

655 
AddProgress(); 
1754  656 
end; 
657 

658 
procedure MakeFortsMap; 

659 
var tmpsurf: PSDL_Surface; 

660 
begin 

2866  661 
MaxHedgehogs:= 32; 
2171
8208946331ba
Smaxx refactor of LoadImage to use flags, iphone changes by koda (mostly use of rgba instead of rgb)
nemo
parents:
2163
diff
changeset

662 
// For now, defining a fort is playable area as 3072x1200  there are no tall forts. The extra height is to avoid triggering border with current code, also if user turns on a border, it will give a bit more maneuvering room. 
1784  663 
playHeight:= 1200; 
2096  664 
playWidth:= 2560; 
1776  665 
leftX:= (LAND_WIDTH  playWidth) div 2; 
666 
rightX:= ((playWidth + (LAND_WIDTH  playWidth) div 2)  1); 

667 
topY:= LAND_HEIGHT  playHeight; 

668 

1754  669 
WriteLnToConsole('Generating forts land...'); 
670 

2171
8208946331ba
Smaxx refactor of LoadImage to use flags, iphone changes by koda (mostly use of rgba instead of rgb)
nemo
parents:
2163
diff
changeset

671 
tmpsurf:= LoadImage(Pathz[ptForts] + '/' + ClansArray[0]^.Teams[0]^.FortName + 'L', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps); 
1784  672 
BlitImageAndGenerateCollisionInfo(leftX+150, LAND_HEIGHT  tmpsurf^.h, tmpsurf^.w, tmpsurf); 
1754  673 
SDL_FreeSurface(tmpsurf); 
674 

2171
8208946331ba
Smaxx refactor of LoadImage to use flags, iphone changes by koda (mostly use of rgba instead of rgb)
nemo
parents:
2163
diff
changeset

675 
tmpsurf:= LoadImage(Pathz[ptForts] + '/' + ClansArray[1]^.Teams[0]^.FortName + 'R', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps); 
1784  676 
BlitImageAndGenerateCollisionInfo(rightX  150  tmpsurf^.w, LAND_HEIGHT  tmpsurf^.h, tmpsurf^.w, tmpsurf); 
1754  677 
SDL_FreeSurface(tmpsurf); 
678 
end; 

679 

1792  680 
// Hi unC0Rr. 
681 
// This is a function that Tiy assures me would not be good for gameplay. 

682 
// It allows the setting of arbitrary portions of landscape as indestructible, or regular, or even blank. 

2154
3d2917be12c3
Change default output to stderr since /tmp doesn't exist under windows and is useless under iphoneos, add a couple of extra parameters
nemo
parents:
2152
diff
changeset

683 
// He said I could add it here only when I swore it would not impact gameplay. Which, as far as I can tell, is true. 
3d2917be12c3
Change default output to stderr since /tmp doesn't exist under windows and is useless under iphoneos, add a couple of extra parameters
nemo
parents:
2152
diff
changeset

684 
// I would just like to play with it with my friends if you do not mind. 
1792  685 
// Can allow for amusing maps. 
686 
procedure LoadMask; 

687 
var tmpsurf: PSDL_Surface; 

688 
p: PLongwordArray; 

689 
x, y, cpX, cpY: Longword; 

690 
begin 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

691 
tmpsurf:= LoadImage(Pathz[ptMapCurrent] + '/mask', ifAlpha or ifTransparent or ifIgnoreCaps); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

692 
if (tmpsurf <> nil) and (tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT) and (tmpsurf^.format^.BytesPerPixel = 4) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

693 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

694 
cpX:= (LAND_WIDTH  tmpsurf^.w) div 2; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

695 
cpY:= LAND_HEIGHT  tmpsurf^.h; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

696 
if SDL_MustLock(tmpsurf) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

697 
SDLTry(SDL_LockSurface(tmpsurf) >= 0, true); 
2376  698 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

699 
p:= tmpsurf^.pixels; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

700 
for y:= 0 to Pred(tmpsurf^.h) do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

701 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

702 
for x:= 0 to Pred(tmpsurf^.w) do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

703 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

704 
if ((AMask and p^[x]) = 0) then // Tiy was having trouble generating transparent black 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

705 
Land[cpY + y, cpX + x]:= 0 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

706 
else if p^[x] = (AMask or RMask) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

707 
Land[cpY + y, cpX + x]:= COLOR_INDESTRUCTIBLE 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

708 
else if p^[x] = $FFFFFFFF then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

709 
Land[cpY + y, cpX + x]:= COLOR_LAND; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

710 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

711 
p:= @(p^[tmpsurf^.pitch div 4]); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

712 
end; 
2243
b4764993f833
additional touch support and nemo's reduced land array size
koda
parents:
2240
diff
changeset

713 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

714 
if SDL_MustLock(tmpsurf) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

715 
SDL_UnlockSurface(tmpsurf); 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

716 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

717 
if (tmpsurf <> nil) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

718 
SDL_FreeSurface(tmpsurf); 
1792  719 
end; 
720 

1754  721 
procedure LoadMap; 
722 
var tmpsurf: PSDL_Surface; 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

723 
s: shortstring; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

724 
f: textfile; 
1754  725 
begin 
2981  726 
isMap:= true; 
1754  727 
WriteLnToConsole('Loading land from file...'); 
728 
AddProgress; 

2171
8208946331ba
Smaxx refactor of LoadImage to use flags, iphone changes by koda (mostly use of rgba instead of rgb)
nemo
parents:
2163
diff
changeset

729 
tmpsurf:= LoadImage(Pathz[ptMapCurrent] + '/map', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps); 
1760  730 
TryDo((tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT), 'Map dimensions too big!', true); 
1754  731 

2154
3d2917be12c3
Change default output to stderr since /tmp doesn't exist under windows and is useless under iphoneos, add a couple of extra parameters
nemo
parents:
2152
diff
changeset

732 
// unC0Rr  should this be passed from the GUI? I am not sure which layer does what 
1792  733 
s:= Pathz[ptMapCurrent] + '/map.cfg'; 
734 
WriteLnToConsole('Fetching map HH limit'); 

735 
Assign(f, s); 

2747  736 
filemode:= 0; // readonly 
1792  737 
Reset(f); 
1795  738 
Readln(f); 
739 
if not eof(f) then Readln(f, MaxHedgehogs); 

740 

2705
2b5625c4ec16
fix a nasty 196 bytes memory leak in engine, plus other stuff for iphone frontend
koda
parents:
2699
diff
changeset

741 
if (MaxHedgehogs = 0) then MaxHedgehogs:= 18; 
1792  742 

1776  743 
playHeight:= tmpsurf^.h; 
744 
playWidth:= tmpsurf^.w; 

745 
leftX:= (LAND_WIDTH  playWidth) div 2; 

746 
rightX:= (playWidth + ((LAND_WIDTH  playWidth) div 2))  1; 

747 
topY:= LAND_HEIGHT  playHeight; 

748 

1754  749 
TryDo(tmpsurf^.format^.BytesPerPixel = 4, 'Map should be 32bit', true); 
750 

1772  751 
BlitImageAndGenerateCollisionInfo( 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

752 
(LAND_WIDTH  tmpsurf^.w) div 2, 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

753 
LAND_HEIGHT  tmpsurf^.h, 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

754 
tmpsurf^.w, 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

755 
tmpsurf); 
1754  756 
SDL_FreeSurface(tmpsurf); 
1792  757 

758 
LoadMask; 

1754  759 
end; 
760 

761 
procedure GenMap; 

1784  762 
var x, y, w, c: Longword; 
1754  763 
begin 
1776  764 
hasBorder:= false; 
2891
e1f902eb0cfe
Formerly "Draw Girders" by MrMfS  now "Disable Girders" to allow template prefs to still exist
nemo
parents:
2866
diff
changeset

765 

1754  766 
LoadThemeConfig; 
2981  767 
isMap:= false; 
1754  768 
if (GameFlags and gfForts) = 0 then 
769 
if Pathz[ptMapCurrent] <> '' then LoadMap 

770 
else GenLandSurface 

771 
else MakeFortsMap; 

772 
AddProgress; 

1760  773 

1754  774 
{$IFDEF DEBUGFILE}LogLandDigest;{$ENDIF} 
1753  775 

1768  776 
// check for land near top 
1784  777 
c:= 0; 
778 
if (GameFlags and gfBorder) <> 0 then 

779 
hasBorder:= true 

780 
else 

781 
for y:= topY to topY + 5 do 

782 
for x:= leftX to rightX do 

783 
if Land[y, x] <> 0 then 

784 
begin 

785 
inc(c); 

786 
if c > 200 then // avoid accidental triggering 

787 
begin 

788 
hasBorder:= true; 

789 
break; 

790 
end; 

791 
end; 

1768  792 

1776  793 
if hasBorder then 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

794 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

795 
for y:= 0 to LAND_HEIGHT  1 do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

796 
for x:= 0 to LAND_WIDTH  1 do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

797 
if (y < topY) or (x < leftX) or (x > rightX) then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

798 
Land[y, x]:= COLOR_INDESTRUCTIBLE; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

799 
// experiment hardcoding cave 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

800 
// also try basing cave dimensions on map/template dimensions, if they exist 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

801 
for w:= 0 to 5 do // width of 3 allowed hogs to be knocked through with grenade 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

802 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

803 
for y:= topY to LAND_HEIGHT  1 do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

804 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

805 
Land[y, leftX + w]:= COLOR_INDESTRUCTIBLE; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

806 
Land[y, rightX  w]:= COLOR_INDESTRUCTIBLE; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

807 
if (y + w) mod 32 < 16 then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

808 
c:= AMask 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

809 
else 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

810 
c:= AMask or RMask or GMask; // FF00FFFF 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

811 
LandPixels[y, leftX + w]:= c; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

812 
LandPixels[y, rightX  w]:= c; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

813 
end; 
1768  814 

2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

815 
for x:= leftX to rightX do 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

816 
begin 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

817 
Land[topY + w, x]:= COLOR_INDESTRUCTIBLE; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

818 
if (x + w) mod 32 < 16 then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

819 
c:= AMask 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

820 
else 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

821 
c:= AMask or RMask or GMask; // FF00FFFF 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

822 
LandPixels[topY + w, x]:= c; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

823 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

824 
end; 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

825 
end; 
1768  826 

2891
e1f902eb0cfe
Formerly "Draw Girders" by MrMfS  now "Disable Girders" to allow template prefs to still exist
nemo
parents:
2866
diff
changeset

827 
if (GameFlags and gfDisableGirders) <> 0 then hasGirders:= false; 
e1f902eb0cfe
Formerly "Draw Girders" by MrMfS  now "Disable Girders" to allow template prefs to still exist
nemo
parents:
2866
diff
changeset

828 

1776  829 
if ((GameFlags and gfForts) = 0) and (Pathz[ptMapCurrent] = '') then AddObjects; 
830 

1807  831 
UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT); 
37  832 
end; 
833 

566  834 
function GenPreview: TPreview; 
371  835 
var x, y, xx, yy, t, bit: LongInt; 
566  836 
Preview: TPreview; 
155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

837 
begin 
160  838 
WriteLnToConsole('Generating preview...'); 
161  839 
GenBlank(EdgeTemplates[SelectTemplate]); 
155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

840 

401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

841 
for y:= 0 to 127 do 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

842 
for x:= 0 to 31 do 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

843 
begin 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

844 
Preview[y, x]:= 0; 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

845 
for bit:= 0 to 7 do 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

846 
begin 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

847 
t:= 0; 
1760  848 
for yy:= y * (LAND_HEIGHT div 128) to y * (LAND_HEIGHT div 128) + 7 do 
849 
for xx:= x * (LAND_WIDTH div 32) + bit * 8 to x * (LAND_WIDTH div 32) + bit * 8 + 7 do 

155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

850 
if Land[yy, xx] <> 0 then inc(t); 
351  851 
if t > 8 then Preview[y, x]:= Preview[y, x] or ($80 shr bit) 
155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

852 
end 
566  853 
end; 
1768  854 
GenPreview:= Preview 
155
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

855 
end; 
401f4ea24715
Engine can generate land preview and send it via IPC
unc0rr
parents:
109
diff
changeset

856 

2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

857 
procedure init_uLand; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

858 
begin 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

859 
LandBackSurface:= nil; 
2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

860 
end; 
51  861 

2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

862 
procedure free_uLand; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

863 
begin 
3017
4a52e0705011
fix the glitch causing passthrough in land objects besides first game
koda
parents:
2981
diff
changeset

864 
FillChar(LandPixels, sizeof(TLandArray), 0); 
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

865 
if LandBackSurface <> nil then 
3f21a9dc93d0
Replace tabs with spaces using 'expand t 4' command
unc0rr
parents:
2905
diff
changeset

866 
SDL_FreeSurface(LandBackSurface); 
2699
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

867 
end; 
249adefa9c1c
replace initialization/finalization statements with custom init functions
koda
parents:
2692
diff
changeset

868 

4  869 
end. 