28 procedure AddOnLandObjects(Surface: PSDL_Surface); |
28 procedure AddOnLandObjects(Surface: PSDL_Surface); |
29 |
29 |
30 implementation |
30 implementation |
31 uses uLand, uStore, uConsts, uMisc, uConsole, uRandom, uVisualGears, uFloat, uSound, uWorld, |
31 uses uLand, uStore, uConsts, uMisc, uConsole, uRandom, uVisualGears, uFloat, uSound, uWorld, |
32 {$IFDEF GLES11} |
32 {$IFDEF GLES11} |
33 gles11; |
33 gles11; |
34 {$ELSE} |
34 {$ELSE} |
35 GL; |
35 GL; |
36 {$ENDIF} |
36 {$ENDIF} |
37 |
37 |
38 const MaxRects = 512; |
38 const MaxRects = 512; |
39 MAXOBJECTRECTS = 16; |
39 MAXOBJECTRECTS = 16; |
40 MAXTHEMEOBJECTS = 32; |
40 MAXTHEMEOBJECTS = 32; |
84 |
84 |
85 if Width = 0 then Width:= Image^.w; |
85 if Width = 0 then Width:= Image^.w; |
86 |
86 |
87 p:= Image^.pixels; |
87 p:= Image^.pixels; |
88 for y:= 0 to Pred(Image^.h) do |
88 for y:= 0 to Pred(Image^.h) do |
89 begin |
89 begin |
90 for x:= 0 to Pred(Width) do |
90 for x:= 0 to Pred(Width) do |
91 if LandPixels[cpY + y, cpX + x] = 0 then |
91 if LandPixels[cpY + y, cpX + x] = 0 then |
92 begin |
92 begin |
93 LandPixels[cpY + y, cpX + x]:= p^[x]; |
93 LandPixels[cpY + y, cpX + x]:= p^[x]; |
94 if (p^[x] and AMask) <> 0 then Land[cpY + y, cpX + x]:= COLOR_OBJECT; |
94 if (p^[x] and AMask) <> 0 then Land[cpY + y, cpX + x]:= COLOR_OBJECT; |
95 end; |
95 end; |
96 p:= @(p^[Image^.pitch shr 2]); |
96 p:= @(p^[Image^.pitch shr 2]); |
97 end; |
97 end; |
98 |
98 |
99 if SDL_MustLock(Image) then |
99 if SDL_MustLock(Image) then |
100 SDL_UnlockSurface(Image); |
100 SDL_UnlockSurface(Image); |
101 WriteLnToConsole(msgOK) |
101 WriteLnToConsole(msgOK) |
102 end; |
102 end; |
145 var tmpsurf: PSDL_Surface; |
145 var tmpsurf: PSDL_Surface; |
146 x1, x2, y, k, i: LongInt; |
146 x1, x2, y, k, i: LongInt; |
147 rr: TSDL_Rect; |
147 rr: TSDL_Rect; |
148 bRes: boolean; |
148 bRes: boolean; |
149 |
149 |
150 function CountNonZeroz(x, y: LongInt): Longword; |
150 function CountNonZeroz(x, y: LongInt): Longword; |
151 var i: LongInt; |
151 var i: LongInt; |
152 lRes: Longword; |
152 lRes: Longword; |
153 begin |
153 begin |
154 lRes:= 0; |
154 lRes:= 0; |
155 for i:= y to y + 15 do |
155 for i:= y to y + 15 do |
156 if Land[i, x] <> 0 then inc(lRes); |
156 if Land[i, x] <> 0 then inc(lRes); |
157 CountNonZeroz:= lRes; |
157 CountNonZeroz:= lRes; |
158 end; |
158 end; |
159 |
159 |
160 begin |
160 begin |
161 y:= topY+150; |
161 y:= topY+150; |
162 repeat |
162 repeat |
163 inc(y, 24); |
163 inc(y, 24); |
164 x1:= gX; |
164 x1:= gX; |
165 x2:= gX; |
165 x2:= gX; |
166 |
166 |
167 while (x1 > Longint(leftX)+150) and (CountNonZeroz(x1, y) = 0) do dec(x1, 2); |
167 while (x1 > Longint(leftX)+150) and (CountNonZeroz(x1, y) = 0) do dec(x1, 2); |
168 |
168 |
169 i:= x1 - 12; |
169 i:= x1 - 12; |
170 repeat |
170 repeat |
171 dec(x1, 2); |
171 dec(x1, 2); |
172 k:= CountNonZeroz(x1, y) |
172 k:= CountNonZeroz(x1, y) |
173 until (x1 < Longint(leftX)+150) or (k = 0) or (k = 16) or (x1 < i); |
173 until (x1 < Longint(leftX)+150) or (k = 0) or (k = 16) or (x1 < i); |
174 |
174 |
175 inc(x1, 2); |
175 inc(x1, 2); |
176 if k = 16 then |
176 if k = 16 then |
177 begin |
177 begin |
178 while (x2 < (rightX-150)) and (CountNonZeroz(x2, y) = 0) do inc(x2, 2); |
178 while (x2 < (rightX-150)) and (CountNonZeroz(x2, y) = 0) do inc(x2, 2); |
179 i:= x2 + 12; |
179 i:= x2 + 12; |
180 repeat |
180 repeat |
181 inc(x2, 2); |
181 inc(x2, 2); |
182 k:= CountNonZeroz(x2, y) |
182 k:= CountNonZeroz(x2, y) |
183 until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768); |
183 until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768); |
184 if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768) |
184 if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768) |
185 and not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144) then break; |
185 and not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144) then break; |
186 end; |
186 end; |
187 x1:= 0; |
187 x1:= 0; |
188 until y > (LAND_HEIGHT-125); |
188 until y > (LAND_HEIGHT-125); |
189 |
189 |
190 if x1 > 0 then |
190 if x1 > 0 then |
191 begin |
191 begin |
192 bRes:= true; |
192 bRes:= true; |
193 tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
193 tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
194 if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptGraphics] + '/Girder', ifCritical or ifTransparent or ifIgnoreCaps); |
194 if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptGraphics] + '/Girder', ifCritical or ifTransparent or ifIgnoreCaps); |
195 |
195 |
196 rr.x:= x1; |
196 rr.x:= x1; |
197 while rr.x < x2 do |
197 while rr.x < x2 do |
198 begin |
198 begin |
199 BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf); |
199 BlitImageAndGenerateCollisionInfo(rr.x, y, min(x2 - rr.x, tmpsurf^.w), tmpsurf); |
200 inc(rr.x, tmpsurf^.w); |
200 inc(rr.x, tmpsurf^.w); |
201 end; |
201 end; |
202 SDL_FreeSurface(tmpsurf); |
202 SDL_FreeSurface(tmpsurf); |
203 |
203 |
204 AddRect(x1 - 8, y - 32, x2 - x1 + 16, 80); |
204 AddRect(x1 - 8, y - 32, x2 - x1 + 16, 80); |
205 end |
205 end |
206 else bRes:= false; |
206 else bRes:= false; |
207 |
207 |
208 AddGirder:= bRes; |
208 AddGirder:= bRes; |
209 end; |
209 end; |
303 r: TSDL_Rect; |
303 r: TSDL_Rect; |
304 bRes: boolean; |
304 bRes: boolean; |
305 begin |
305 begin |
306 cnt:= 0; |
306 cnt:= 0; |
307 with Obj do |
307 with Obj do |
308 begin |
308 begin |
309 if Maxcnt = 0 then |
309 if Maxcnt = 0 then |
310 exit(false); |
310 exit(false); |
311 x:= 0; |
311 x:= 0; |
312 r.x:= 0; |
312 r.x:= 0; |
313 r.y:= 0; |
313 r.y:= 0; |
314 r.w:= Width; |
314 r.w:= Width; |
315 r.h:= Height + 16; |
315 r.h:= Height + 16; |
316 repeat |
316 repeat |
317 y:= 8; |
317 y:= 8; |
318 repeat |
318 repeat |
319 if CheckLand(r, x, y - 8, COLOR_LAND) |
319 if CheckLand(r, x, y - 8, COLOR_LAND) |
320 and not CheckIntersect(x, y, Width, Height) then |
320 and not CheckIntersect(x, y, Width, Height) then |
321 begin |
321 begin |
322 ar[cnt].x:= x; |
322 ar[cnt].x:= x; |
323 ar[cnt].y:= y; |
323 ar[cnt].y:= y; |
324 inc(cnt); |
324 inc(cnt); |
325 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
325 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
326 begin |
326 begin |
327 y:= 5000; |
327 y:= 5000; |
328 x:= 5000; |
328 x:= 5000; |
329 end |
329 end |
330 end; |
330 end; |
331 inc(y, 12); |
331 inc(y, 12); |
332 until y > LAND_HEIGHT - 1 - Height - 8; |
332 until y > LAND_HEIGHT - 1 - Height - 8; |
333 inc(x, getrandom(12) + 12) |
333 inc(x, getrandom(12) + 12) |
334 until x > LAND_WIDTH - 1 - Width; |
334 until x > LAND_WIDTH - 1 - Width; |
335 bRes:= cnt <> 0; |
335 bRes:= cnt <> 0; |
336 if bRes then |
336 if bRes then |
337 begin |
337 begin |
338 i:= getrandom(cnt); |
338 i:= getrandom(cnt); |
339 r.x:= ar[i].X; |
339 r.x:= ar[i].X; |
340 r.y:= ar[i].Y; |
340 r.y:= ar[i].Y; |
341 r.w:= Width; |
341 r.w:= Width; |
342 r.h:= Height; |
342 r.h:= Height; |
343 SDL_UpperBlit(Obj.Surf, nil, Surface, @r); |
343 SDL_UpperBlit(Obj.Surf, nil, Surface, @r); |
344 AddRect(ar[i].x - 32, ar[i].y - 32, Width + 64, Height + 64); |
344 AddRect(ar[i].x - 32, ar[i].y - 32, Width + 64, Height + 64); |
345 dec(Maxcnt) |
345 dec(Maxcnt) |
346 end else Maxcnt:= 0 |
346 end else Maxcnt:= 0 |
347 end; |
347 end; |
348 TryPut:= bRes; |
348 TryPut:= bRes; |
349 end; |
349 end; |
350 |
350 |
351 procedure ReadThemeInfo(var ThemeObjects: TThemeObjects; var SprayObjects: TSprayObjects); |
351 procedure ReadThemeInfo(var ThemeObjects: TThemeObjects; var SprayObjects: TSprayObjects); |
352 var s: shortstring; |
352 var s: shortstring; |
353 f: textfile; |
353 f: textfile; |
354 i, ii: LongInt; |
354 i, ii: LongInt; |
355 vobcount: Longword; |
355 vobcount: Longword; |
356 c1, c2: TSDL_Color; |
356 c1, c2: TSDL_Color; |
357 |
357 |
358 procedure CheckRect(Width, Height, x, y, w, h: LongWord); |
358 procedure CheckRect(Width, Height, x, y, w, h: LongWord); |
359 begin |
359 begin |
360 if (x + w > Width) then OutError('Object''s rectangle exceeds image: x + w (' + inttostr(x) + ' + ' + inttostr(w) + ') > Width (' + inttostr(Width) + ')', true); |
360 if (x + w > Width) then OutError('Object''s rectangle exceeds image: x + w (' + inttostr(x) + ' + ' + inttostr(w) + ') > Width (' + inttostr(Width) + ')', true); |
361 if (y + h > Height) then OutError('Object''s rectangle exceeds image: y + h (' + inttostr(y) + ' + ' + inttostr(h) + ') > Height (' + inttostr(Height) + ')', true); |
361 if (y + h > Height) then OutError('Object''s rectangle exceeds image: y + h (' + inttostr(y) + ' + ' + inttostr(h) + ') > Height (' + inttostr(Height) + ')', true); |
362 end; |
362 end; |
363 |
363 |
364 begin |
364 begin |
365 |
365 |
366 AddProgress; |
366 AddProgress; |
367 |
367 |
394 // TODO - adjust all the theme cloud numbers. This should not be a permanent fix |
394 // TODO - adjust all the theme cloud numbers. This should not be a permanent fix |
395 cCloudsNumber:= cCloudsNumber * (LAND_WIDTH div 2048); |
395 cCloudsNumber:= cCloudsNumber * (LAND_WIDTH div 2048); |
396 |
396 |
397 Readln(f, ThemeObjects.Count); |
397 Readln(f, ThemeObjects.Count); |
398 for i:= 0 to Pred(ThemeObjects.Count) do |
398 for i:= 0 to Pred(ThemeObjects.Count) do |
399 begin |
399 begin |
400 Readln(f, s); // filename |
400 Readln(f, s); // filename |
401 with ThemeObjects.objs[i] do |
401 with ThemeObjects.objs[i] do |
402 begin |
402 begin |
403 Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + s, ifCritical or ifTransparent or ifIgnoreCaps); |
403 Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + s, ifCritical or ifTransparent or ifIgnoreCaps); |
404 Width:= Surf^.w; |
404 Width:= Surf^.w; |
405 Height:= Surf^.h; |
405 Height:= Surf^.h; |
406 Read(f, Maxcnt); |
406 Read(f, Maxcnt); |
407 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then OutError('Object''s max count should be between 1 and '+ inttostr(MAXTHEMEOBJECTS) +' (it was '+ inttostr(Maxcnt) +').', true); |
407 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then OutError('Object''s max count should be between 1 and '+ inttostr(MAXTHEMEOBJECTS) +' (it was '+ inttostr(Maxcnt) +').', true); |
408 with inland do |
408 with inland do |
409 begin |
409 begin |
410 Read(f, x, y, w, h); |
410 Read(f, x, y, w, h); |
411 CheckRect(Width, Height, x, y, w, h) |
411 CheckRect(Width, Height, x, y, w, h) |
412 end; |
412 end; |
413 Read(f, rectcnt); |
413 Read(f, rectcnt); |
414 for ii:= 1 to rectcnt do |
414 for ii:= 1 to rectcnt do |
415 with outland[ii] do |
415 with outland[ii] do |
416 begin |
416 begin |
417 Read(f, x, y, w, h); |
417 Read(f, x, y, w, h); |
418 CheckRect(Width, Height, x, y, w, h) |
418 CheckRect(Width, Height, x, y, w, h) |
419 end; |
419 end; |
420 ReadLn(f) |
420 ReadLn(f) |
421 end; |
421 end; |
422 end; |
422 end; |
423 |
423 |
424 // sprays |
424 // sprays |
425 Readln(f, SprayObjects.Count); |
425 Readln(f, SprayObjects.Count); |
426 for i:= 0 to Pred(SprayObjects.Count) do |
426 for i:= 0 to Pred(SprayObjects.Count) do |
427 begin |
427 begin |
451 |
451 |
452 procedure AddThemeObjects(var ThemeObjects: TThemeObjects); |
452 procedure AddThemeObjects(var ThemeObjects: TThemeObjects); |
453 var i, ii, t: LongInt; |
453 var i, ii, t: LongInt; |
454 b: boolean; |
454 b: boolean; |
455 begin |
455 begin |
456 if ThemeObjects.Count = 0 then exit; |
456 if ThemeObjects.Count = 0 then exit; |
457 WriteLnToConsole('Adding theme objects...'); |
457 WriteLnToConsole('Adding theme objects...'); |
458 |
458 |
459 for i:=0 to ThemeObjects.Count do |
459 for i:=0 to ThemeObjects.Count do |
460 ThemeObjects.objs[i].Maxcnt := max(1, (ThemeObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map |
460 ThemeObjects.objs[i].Maxcnt := max(1, (ThemeObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map |
461 |
461 |
462 repeat |
462 repeat |
463 t := getrandom(ThemeObjects.Count); |
463 t := getrandom(ThemeObjects.Count); |
464 b := false; |
464 b := false; |
465 for i:=0 to ThemeObjects.Count do |
465 for i:=0 to ThemeObjects.Count do |
466 begin |
466 begin |
467 ii := (i+t) mod ThemeObjects.Count; |
467 ii := (i+t) mod ThemeObjects.Count; |
468 |
468 |
469 if ThemeObjects.objs[ii].Maxcnt <> 0 then |
469 if ThemeObjects.objs[ii].Maxcnt <> 0 then |
470 b := b or TryPut(ThemeObjects.objs[ii]) |
470 b := b or TryPut(ThemeObjects.objs[ii]) |
471 end; |
471 end; |
472 until not b; |
472 until not b; |
473 end; |
473 end; |
474 |
474 |
475 procedure AddSprayObjects(Surface: PSDL_Surface; var SprayObjects: TSprayObjects); |
475 procedure AddSprayObjects(Surface: PSDL_Surface; var SprayObjects: TSprayObjects); |
476 var i, ii, t: LongInt; |
476 var i, ii, t: LongInt; |
477 b: boolean; |
477 b: boolean; |
478 begin |
478 begin |
479 if SprayObjects.Count = 0 then exit; |
479 if SprayObjects.Count = 0 then exit; |
480 WriteLnToConsole('Adding spray objects...'); |
480 WriteLnToConsole('Adding spray objects...'); |
481 |
481 |
482 for i:=0 to SprayObjects.Count do |
482 for i:=0 to SprayObjects.Count do |
483 SprayObjects.objs[i].Maxcnt := max(1, (SprayObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map |
483 SprayObjects.objs[i].Maxcnt := max(1, (SprayObjects.objs[i].Maxcnt * MaxHedgehogs) div 18); // Maxcnt is proportional to map size, but allow objects to span even if we're on a tiny map |
484 |
484 |
485 repeat |
485 repeat |
486 t := getrandom(SprayObjects.Count); |
486 t := getrandom(SprayObjects.Count); |
487 b := false; |
487 b := false; |
488 for i:=0 to SprayObjects.Count do |
488 for i:=0 to SprayObjects.Count do |
489 begin |
489 begin |
490 ii := (i+t) mod SprayObjects.Count; |
490 ii := (i+t) mod SprayObjects.Count; |
491 |
491 |
492 if SprayObjects.objs[ii].Maxcnt <> 0 then |
492 if SprayObjects.objs[ii].Maxcnt <> 0 then |
493 b := b or TryPut(SprayObjects.objs[ii], Surface) |
493 b := b or TryPut(SprayObjects.objs[ii], Surface) |
494 end; |
494 end; |
495 until not b; |
495 until not b; |
496 end; |
496 end; |
497 |
497 |
498 procedure AddObjects(); |
498 procedure AddObjects(); |
499 var i, int: Longword; |
499 var i, int: Longword; |
500 begin |
500 begin |