37 MAXTHEMEOBJECTS = 32; |
37 MAXTHEMEOBJECTS = 32; |
38 |
38 |
39 type PRectArray = ^TRectsArray; |
39 type PRectArray = ^TRectsArray; |
40 TRectsArray = array[0..MaxRects] of TSDL_Rect; |
40 TRectsArray = array[0..MaxRects] of TSDL_Rect; |
41 TThemeObject = record |
41 TThemeObject = record |
42 Surf: PSDL_Surface; |
42 Surf: PSDL_Surface; |
43 inland: TSDL_Rect; |
43 inland: TSDL_Rect; |
44 outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect; |
44 outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect; |
45 rectcnt: Longword; |
45 rectcnt: Longword; |
46 Width, Height: Longword; |
46 Width, Height: Longword; |
47 Maxcnt: Longword; |
47 Maxcnt: Longword; |
48 end; |
48 end; |
49 TThemeObjects = record |
49 TThemeObjects = record |
50 Count: LongInt; |
50 Count: LongInt; |
51 objs: array[0..Pred(MAXTHEMEOBJECTS)] of TThemeObject; |
51 objs: array[0..Pred(MAXTHEMEOBJECTS)] of TThemeObject; |
52 end; |
52 end; |
53 TSprayObject = record |
53 TSprayObject = record |
54 Surf: PSDL_Surface; |
54 Surf: PSDL_Surface; |
55 Width, Height: Longword; |
55 Width, Height: Longword; |
56 Maxcnt: Longword; |
56 Maxcnt: Longword; |
57 end; |
57 end; |
58 TSprayObjects = record |
58 TSprayObjects = record |
59 Count: LongInt; |
59 Count: LongInt; |
60 objs: array[0..Pred(MAXTHEMEOBJECTS)] of TSprayObject |
60 objs: array[0..Pred(MAXTHEMEOBJECTS)] of TSprayObject |
61 end; |
61 end; |
62 |
62 |
72 bpp: LongInt; |
72 bpp: LongInt; |
73 begin |
73 begin |
74 WriteToConsole('Generating collision info... '); |
74 WriteToConsole('Generating collision info... '); |
75 |
75 |
76 if SDL_MustLock(Image) then |
76 if SDL_MustLock(Image) then |
77 SDLTry(SDL_LockSurface(Image) >= 0, true); |
77 SDLTry(SDL_LockSurface(Image) >= 0, true); |
78 |
78 |
79 bpp:= Image^.format^.BytesPerPixel; |
79 bpp:= Image^.format^.BytesPerPixel; |
80 TryDo(bpp = 4, 'Land object should be 32bit', true); |
80 TryDo(bpp = 4, 'Land object should be 32bit', true); |
81 |
81 |
82 if Width = 0 then Width:= Image^.w; |
82 if Width = 0 then |
|
83 Width:= Image^.w; |
83 |
84 |
84 p:= Image^.pixels; |
85 p:= Image^.pixels; |
85 for y:= 0 to Pred(Image^.h) do |
86 for y:= 0 to Pred(Image^.h) do |
86 begin |
87 begin |
87 for x:= 0 to Pred(Width) do |
88 for x:= 0 to Pred(Width) do |
88 if (p^[x] and AMask) <> 0 then |
89 if (p^[x] and AMask) <> 0 then |
89 begin |
90 begin |
90 if (cReducedQuality and rqBlurryLand) = 0 then |
91 if (cReducedQuality and rqBlurryLand) = 0 then |
91 begin |
92 begin |
92 if (LandPixels[cpY + y, cpX + x] = 0) or |
93 if (LandPixels[cpY + y, cpX + x] = 0) |
93 (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then |
94 or (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then |
94 LandPixels[cpY + y, cpX + x]:= p^[x]; |
95 LandPixels[cpY + y, cpX + x]:= p^[x]; |
95 end |
96 end |
96 else |
97 else |
97 if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then |
98 if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then |
98 LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x]; |
99 LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x]; |
105 end; |
106 end; |
106 p:= @(p^[Image^.pitch shr 2]) |
107 p:= @(p^[Image^.pitch shr 2]) |
107 end; |
108 end; |
108 |
109 |
109 if SDL_MustLock(Image) then |
110 if SDL_MustLock(Image) then |
110 SDL_UnlockSurface(Image); |
111 SDL_UnlockSurface(Image); |
111 WriteLnToConsole(msgOK) |
112 WriteLnToConsole(msgOK) |
112 end; |
113 end; |
113 |
114 |
114 procedure AddRect(x1, y1, w1, h1: LongInt); |
115 procedure AddRect(x1, y1, w1, h1: LongInt); |
115 begin |
116 begin |
116 with Rects^[RectCount] do |
117 with Rects^[RectCount] do |
117 begin |
118 begin |
118 x:= x1; |
119 x:= x1; |
119 y:= y1; |
120 y:= y1; |
120 w:= w1; |
121 w:= w1; |
121 h:= h1 |
122 h:= h1 |
122 end; |
123 end; |
123 inc(RectCount); |
124 inc(RectCount); |
124 TryDo(RectCount < MaxRects, 'AddRect: overflow', true) |
125 TryDo(RectCount < MaxRects, 'AddRect: overflow', true) |
125 end; |
126 end; |
126 |
127 |
127 procedure InitRects; |
128 procedure InitRects; |
140 res: boolean = false; |
141 res: boolean = false; |
141 begin |
142 begin |
142 |
143 |
143 i:= 0; |
144 i:= 0; |
144 if RectCount > 0 then |
145 if RectCount > 0 then |
145 repeat |
146 repeat |
146 with Rects^[i] do |
147 with Rects^[i] do |
147 res:= (x < x1 + w1) and (x1 < x + w) and |
148 res:= (x < x1 + w1) and (x1 < x + w) and (y < y1 + h1) and (y1 < y + h); |
148 (y < y1 + h1) and (y1 < y + h); |
149 inc(i) |
149 inc(i) |
150 until (i = RectCount) or (res); |
150 until (i = RectCount) or (res); |
|
151 CheckIntersect:= res; |
151 CheckIntersect:= res; |
152 end; |
152 end; |
153 |
153 |
154 |
154 |
155 function CountNonZeroz(x, y: LongInt): Longword; |
155 function CountNonZeroz(x, y: LongInt): Longword; |
156 var i: LongInt; |
156 var i: LongInt; |
157 lRes: Longword; |
157 lRes: Longword; |
158 begin |
158 begin |
159 lRes:= 0; |
159 lRes:= 0; |
160 for i:= y to y + 15 do |
160 for i:= y to y + 15 do |
161 if Land[i, x] <> 0 then inc(lRes); |
161 if Land[i, x] <> 0 then |
|
162 inc(lRes); |
162 CountNonZeroz:= lRes; |
163 CountNonZeroz:= lRes; |
163 end; |
164 end; |
164 |
165 |
165 function AddGirder(gX: LongInt): boolean; |
166 function AddGirder(gX: LongInt): boolean; |
166 var tmpsurf: PSDL_Surface; |
167 var tmpsurf: PSDL_Surface; |
172 repeat |
173 repeat |
173 inc(y, 24); |
174 inc(y, 24); |
174 x1:= gX; |
175 x1:= gX; |
175 x2:= gX; |
176 x2:= gX; |
176 |
177 |
177 while (x1 > Longint(leftX)+150) and (CountNonZeroz(x1, y) = 0) do dec(x1, 2); |
178 while (x1 > Longint(leftX)+150) and (CountNonZeroz(x1, y) = 0) do |
|
179 dec(x1, 2); |
178 |
180 |
179 i:= x1 - 12; |
181 i:= x1 - 12; |
180 repeat |
182 repeat |
181 dec(x1, 2); |
183 dec(x1, 2); |
182 k:= CountNonZeroz(x1, y) |
184 k:= CountNonZeroz(x1, y) |
183 until (x1 < Longint(leftX)+150) or (k = 0) or (k = 16) or (x1 < i); |
185 until (x1 < Longint(leftX)+150) or (k = 0) or (k = 16) or (x1 < i); |
184 |
186 |
185 inc(x1, 2); |
187 inc(x1, 2); |
186 if k = 16 then |
188 if k = 16 then |
187 begin |
189 begin |
188 while (x2 < (rightX-150)) and (CountNonZeroz(x2, y) = 0) do inc(x2, 2); |
190 while (x2 < (rightX-150)) and (CountNonZeroz(x2, y) = 0) do |
|
191 inc(x2, 2); |
189 i:= x2 + 12; |
192 i:= x2 + 12; |
190 repeat |
193 repeat |
191 inc(x2, 2); |
194 inc(x2, 2); |
192 k:= CountNonZeroz(x2, y) |
195 k:= CountNonZeroz(x2, y) |
193 until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768); |
196 until (x2 >= (rightX-150)) or (k = 0) or (k = 16) or (x2 > i) or (x2 - x1 >= 768); |
|
197 |
194 if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768) |
198 if (x2 < (rightX - 150)) and (k = 16) and (x2 - x1 > 250) and (x2 - x1 < 768) |
195 and (not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144)) then break; |
199 and (not CheckIntersect(x1 - 32, y - 64, x2 - x1 + 64, 144)) then |
|
200 break; |
196 end; |
201 end; |
197 x1:= 0; |
202 x1:= 0; |
198 until y > (LAND_HEIGHT-125); |
203 until y > (LAND_HEIGHT-125); |
199 |
204 |
200 if x1 > 0 then |
205 if x1 > 0 then |
201 begin |
206 begin |
202 bRes:= true; |
207 bRes:= true; |
203 tmpsurf:= LoadImage(UserPathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
208 tmpsurf:= LoadImage(UserPathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
204 if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
209 if tmpsurf = nil then |
205 if tmpsurf = nil then tmpsurf:= LoadImage(UserPathz[ptGraphics] + '/Girder', ifTransparent or ifIgnoreCaps); |
210 tmpsurf:= LoadImage(Pathz[ptCurrTheme] + '/Girder', ifTransparent or ifIgnoreCaps); |
206 if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptGraphics] + '/Girder', ifCritical or ifTransparent or ifIgnoreCaps); |
211 if tmpsurf = nil then |
|
212 tmpsurf:= LoadImage(UserPathz[ptGraphics] + '/Girder', ifTransparent or ifIgnoreCaps); |
|
213 if tmpsurf = nil then |
|
214 tmpsurf:= LoadImage(Pathz[ptGraphics] + '/Girder', ifCritical or ifTransparent or ifIgnoreCaps); |
207 |
215 |
208 rr.x:= x1; |
216 rr.x:= x1; |
209 while rr.x < x2 do |
217 while rr.x < x2 do |
210 begin |
218 begin |
211 // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun |
219 // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun |
234 by:= rect.y + rect.h; |
242 by:= rect.y + rect.h; |
235 {$WARNINGS OFF} |
243 {$WARNINGS OFF} |
236 tmpx:= rect.x; |
244 tmpx:= rect.x; |
237 tmpx2:= bx; |
245 tmpx2:= bx; |
238 while (tmpx <= bx - rect.w div 2 - 1) and bRes do |
246 while (tmpx <= bx - rect.w div 2 - 1) and bRes do |
239 begin |
247 begin |
240 bRes:= ((rect.y and LAND_HEIGHT_MASK) = 0) and ((by and LAND_HEIGHT_MASK) = 0) and |
248 bRes:= ((rect.y and LAND_HEIGHT_MASK) = 0) and ((by and LAND_HEIGHT_MASK) = 0) |
241 ((tmpx and LAND_WIDTH_MASK) = 0) and ((tmpx2 and LAND_WIDTH_MASK) = 0) and |
249 and ((tmpx and LAND_WIDTH_MASK) = 0) and ((tmpx2 and LAND_WIDTH_MASK) = 0) |
242 (Land[rect.y, tmpx] = Color) and (Land[by, tmpx] = Color) and |
250 and (Land[rect.y, tmpx] = Color) and (Land[by, tmpx] = Color) |
243 (Land[rect.y, tmpx2] = Color) and (Land[by, tmpx2] = Color); |
251 and (Land[rect.y, tmpx2] = Color) and (Land[by, tmpx2] = Color); |
244 inc(tmpx); |
252 inc(tmpx); |
245 dec(tmpx2) |
253 dec(tmpx2) |
246 end; |
254 end; |
247 tmpy:= rect.y+1; |
255 tmpy:= rect.y+1; |
248 tmpy2:= by-1; |
256 tmpy2:= by-1; |
249 while (tmpy <= by - rect.h div 2 - 1) and bRes do |
257 while (tmpy <= by - rect.h div 2 - 1) and bRes do |
250 begin |
258 begin |
251 bRes:= ((tmpy and LAND_HEIGHT_MASK) = 0) and ((tmpy2 and LAND_HEIGHT_MASK) = 0) and |
259 bRes:= ((tmpy and LAND_HEIGHT_MASK) = 0) and ((tmpy2 and LAND_HEIGHT_MASK) = 0) |
252 ((rect.x and LAND_WIDTH_MASK) = 0) and ((bx and LAND_WIDTH_MASK) = 0) and |
260 and ((rect.x and LAND_WIDTH_MASK) = 0) and ((bx and LAND_WIDTH_MASK) = 0) |
253 (Land[tmpy, rect.x] = Color) and (Land[tmpy, bx] = Color) and |
261 and (Land[tmpy, rect.x] = Color) and (Land[tmpy, bx] = Color) |
254 (Land[tmpy2, rect.x] = Color) and (Land[tmpy2, bx] = Color); |
262 and (Land[tmpy2, rect.x] = Color) and (Land[tmpy2, bx] = Color); |
255 inc(tmpy); |
263 inc(tmpy); |
256 dec(tmpy2) |
264 dec(tmpy2) |
257 end; |
265 end; |
258 {$WARNINGS ON} |
266 {$WARNINGS ON} |
259 CheckLand:= bRes; |
267 CheckLand:= bRes; |
260 end; |
268 end; |
261 |
269 |
262 function CheckCanPlace(x, y: Longword; var Obj: TThemeObject): boolean; |
270 function CheckCanPlace(x, y: Longword; var Obj: TThemeObject): boolean; |
263 var i: Longword; |
271 var i: Longword; |
264 bRes: boolean; |
272 bRes: boolean; |
265 begin |
273 begin |
266 with Obj do |
274 with Obj do |
267 if CheckLand(inland, x, y, lfBasic) then |
275 if CheckLand(inland, x, y, lfBasic) then |
268 begin |
276 begin |
269 bRes:= true; |
277 bRes:= true; |
270 i:= 1; |
278 i:= 1; |
271 while bRes and (i <= rectcnt) do |
279 while bRes and (i <= rectcnt) do |
272 begin |
280 begin |
273 bRes:= CheckLand(outland[i], x, y, 0); |
281 bRes:= CheckLand(outland[i], x, y, 0); |
274 inc(i) |
282 inc(i) |
275 end; |
283 end; |
276 if bRes then |
284 if bRes then |
277 bRes:= not CheckIntersect(x, y, Width, Height) |
285 bRes:= not CheckIntersect(x, y, Width, Height) |
278 end else |
286 end |
|
287 else |
279 bRes:= false; |
288 bRes:= false; |
280 CheckCanPlace:= bRes; |
289 CheckCanPlace:= bRes; |
281 end; |
290 end; |
282 |
291 |
283 function TryPut(var Obj: TThemeObject): boolean; overload; |
292 function TryPut(var Obj: TThemeObject): boolean; overload; |
287 cnt, i: Longword; |
296 cnt, i: Longword; |
288 bRes: boolean; |
297 bRes: boolean; |
289 begin |
298 begin |
290 cnt:= 0; |
299 cnt:= 0; |
291 with Obj do |
300 with Obj do |
292 begin |
301 begin |
293 if Maxcnt = 0 then |
302 if Maxcnt = 0 then |
294 exit(false); |
303 exit(false); |
295 x:= 0; |
304 x:= 0; |
296 repeat |
305 repeat |
297 y:= topY+32; // leave room for a hedgie to teleport in |
306 y:= topY+32; // leave room for a hedgie to teleport in |
298 repeat |
307 repeat |
299 if CheckCanPlace(x, y, Obj) then |
308 if CheckCanPlace(x, y, Obj) then |
300 begin |
309 begin |
301 ar[cnt].x:= x; |
310 ar[cnt].x:= x; |
302 ar[cnt].y:= y; |
311 ar[cnt].y:= y; |
303 inc(cnt); |
312 inc(cnt); |
304 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
313 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
305 begin |
314 begin |
306 y:= 5000; |
315 y:= 5000; |
307 x:= 5000; |
316 x:= 5000; |
308 end |
317 end |
309 end; |
318 end; |
310 inc(y, 3); |
319 inc(y, 3); |
311 until y >= LAND_HEIGHT - Height; |
320 until y >= LAND_HEIGHT - Height; |
312 inc(x, getrandom(6) + 3) |
321 inc(x, getrandom(6) + 3) |
313 until x >= LAND_WIDTH - Width; |
322 until x >= LAND_WIDTH - Width; |
314 bRes:= cnt <> 0; |
323 bRes:= cnt <> 0; |
315 if bRes then |
324 if bRes then |
316 begin |
325 begin |
317 i:= getrandom(cnt); |
326 i:= getrandom(cnt); |
318 BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf); |
327 BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf); |
319 AddRect(ar[i].x, ar[i].y, Width, Height); |
328 AddRect(ar[i].x, ar[i].y, Width, Height); |
320 dec(Maxcnt) |
329 dec(Maxcnt) |
321 end else Maxcnt:= 0 |
330 end |
322 end; |
331 else Maxcnt:= 0 |
|
332 end; |
323 TryPut:= bRes; |
333 TryPut:= bRes; |
324 end; |
334 end; |
325 |
335 |
326 function TryPut(var Obj: TSprayObject; Surface: PSDL_Surface): boolean; overload; |
336 function TryPut(var Obj: TSprayObject; Surface: PSDL_Surface): boolean; overload; |
327 const MaxPointsIndex = 8095; |
337 const MaxPointsIndex = 8095; |
344 repeat |
354 repeat |
345 y:= 8; |
355 y:= 8; |
346 repeat |
356 repeat |
347 if CheckLand(r, x, y - 8, lfBasic) |
357 if CheckLand(r, x, y - 8, lfBasic) |
348 and (not CheckIntersect(x, y, Width, Height)) then |
358 and (not CheckIntersect(x, y, Width, Height)) then |
349 begin |
|
350 ar[cnt].x:= x; |
|
351 ar[cnt].y:= y; |
|
352 inc(cnt); |
|
353 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
|
354 begin |
359 begin |
355 y:= 5000; |
360 ar[cnt].x:= x; |
356 x:= 5000; |
361 ar[cnt].y:= y; |
357 end |
362 inc(cnt); |
358 end; |
363 if cnt > MaxPointsIndex then // buffer is full, do not check the rest land |
|
364 begin |
|
365 y:= 5000; |
|
366 x:= 5000; |
|
367 end |
|
368 end; |
359 inc(y, 12); |
369 inc(y, 12); |
360 until y >= LAND_HEIGHT - Height - 8; |
370 until y >= LAND_HEIGHT - Height - 8; |
361 inc(x, getrandom(12) + 12) |
371 inc(x, getrandom(12) + 12) |
362 until x >= LAND_WIDTH - Width; |
372 until x >= LAND_WIDTH - Width; |
363 bRes:= cnt <> 0; |
373 bRes:= cnt <> 0; |
398 if cGrayScale then |
409 if cGrayScale then |
399 begin |
410 begin |
400 for i:= 0 to 3 do |
411 for i:= 0 to 3 do |
401 begin |
412 begin |
402 t:= round(SDWaterColorArray[i].r * RGB_LUMINANCE_RED + SDWaterColorArray[i].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[i].b * RGB_LUMINANCE_BLUE); |
413 t:= round(SDWaterColorArray[i].r * RGB_LUMINANCE_RED + SDWaterColorArray[i].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[i].b * RGB_LUMINANCE_BLUE); |
403 if t > 255 then t:= 255; |
414 if t > 255 then |
|
415 t:= 255; |
404 SDWaterColorArray[i].r:= t; |
416 SDWaterColorArray[i].r:= t; |
405 SDWaterColorArray[i].g:= t; |
417 SDWaterColorArray[i].g:= t; |
406 SDWaterColorArray[i].b:= t |
418 SDWaterColorArray[i].b:= t |
407 end; |
419 end; |
408 for i:= 0 to 1 do |
420 for i:= 0 to 1 do |
409 begin |
421 begin |
410 t:= round(WaterColorArray[i].r * RGB_LUMINANCE_RED + WaterColorArray[i].g * RGB_LUMINANCE_GREEN + WaterColorArray[i].b * RGB_LUMINANCE_BLUE); |
422 t:= round(WaterColorArray[i].r * RGB_LUMINANCE_RED + WaterColorArray[i].g * RGB_LUMINANCE_GREEN + WaterColorArray[i].b * RGB_LUMINANCE_BLUE); |
411 if t > 255 then t:= 255; |
423 if t > 255 then |
|
424 t:= 255; |
412 WaterColorArray[i].r:= t; |
425 WaterColorArray[i].r:= t; |
413 WaterColorArray[i].g:= t; |
426 WaterColorArray[i].g:= t; |
414 WaterColorArray[i].b:= t |
427 WaterColorArray[i].b:= t |
415 end |
428 end |
416 end; |
429 end; |
417 |
430 |
418 s:= UserPathz[ptCurrTheme] + '/' + cThemeCFGFilename; |
431 s:= UserPathz[ptCurrTheme] + '/' + cThemeCFGFilename; |
419 if not FileExists(s) then s:= Pathz[ptCurrTheme] + '/' + cThemeCFGFilename; |
432 if not FileExists(s) then |
|
433 s:= Pathz[ptCurrTheme] + '/' + cThemeCFGFilename; |
420 WriteLnToConsole('Reading objects info...'); |
434 WriteLnToConsole('Reading objects info...'); |
421 Assign(f, s); |
435 Assign(f, s); |
422 {$I-} |
436 {$I-} |
423 filemode:= 0; // readonly |
437 filemode:= 0; // readonly |
424 Reset(f); |
438 Reset(f); |
443 Delete(s, 1, i); |
459 Delete(s, 1, i); |
444 i:= Pos(',', s); |
460 i:= Pos(',', s); |
445 SkyColor.g:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
461 SkyColor.g:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
446 Delete(s, 1, i); |
462 Delete(s, 1, i); |
447 SkyColor.b:= StrToInt(Trim(s)); |
463 SkyColor.b:= StrToInt(Trim(s)); |
448 if cGrayScale then |
464 if cGrayScale |
|
465 then |
449 begin |
466 begin |
450 t:= round(SkyColor.r * RGB_LUMINANCE_RED + SkyColor.g * RGB_LUMINANCE_GREEN + SkyColor.b * RGB_LUMINANCE_BLUE); |
467 t:= round(SkyColor.r * RGB_LUMINANCE_RED + SkyColor.g * RGB_LUMINANCE_GREEN + SkyColor.b * RGB_LUMINANCE_BLUE); |
451 if t > 255 then t:= 255; |
468 if t > 255 then |
|
469 t:= 255; |
452 SkyColor.r:= t; |
470 SkyColor.r:= t; |
453 SkyColor.g:= t; |
471 SkyColor.g:= t; |
454 SkyColor.b:= t |
472 SkyColor.b:= t |
455 end; |
473 end; |
456 glClearColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255, 0.99); |
474 glClearColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255, 0.99); |
488 WaterColorArray[0].b:= StrToInt(Trim(s)); |
507 WaterColorArray[0].b:= StrToInt(Trim(s)); |
489 WaterColorArray[0].a := 255; |
508 WaterColorArray[0].a := 255; |
490 if cGrayScale then |
509 if cGrayScale then |
491 begin |
510 begin |
492 t:= round(WaterColorArray[0].r * RGB_LUMINANCE_RED + WaterColorArray[0].g * RGB_LUMINANCE_GREEN + WaterColorArray[0].b * RGB_LUMINANCE_BLUE); |
511 t:= round(WaterColorArray[0].r * RGB_LUMINANCE_RED + WaterColorArray[0].g * RGB_LUMINANCE_GREEN + WaterColorArray[0].b * RGB_LUMINANCE_BLUE); |
493 if t > 255 then t:= 255; |
512 if t > 255 then |
|
513 t:= 255; |
494 WaterColorArray[0].r:= t; |
514 WaterColorArray[0].r:= t; |
495 WaterColorArray[0].g:= t; |
515 WaterColorArray[0].g:= t; |
496 WaterColorArray[0].b:= t |
516 WaterColorArray[0].b:= t |
497 end; |
517 end; |
498 WaterColorArray[1]:= WaterColorArray[0]; |
518 WaterColorArray[1]:= WaterColorArray[0]; |
508 WaterColorArray[2].b:= StrToInt(Trim(s)); |
528 WaterColorArray[2].b:= StrToInt(Trim(s)); |
509 WaterColorArray[2].a := 255; |
529 WaterColorArray[2].a := 255; |
510 if cGrayScale then |
530 if cGrayScale then |
511 begin |
531 begin |
512 t:= round(WaterColorArray[2].r * RGB_LUMINANCE_RED + WaterColorArray[2].g * RGB_LUMINANCE_GREEN + WaterColorArray[2].b * RGB_LUMINANCE_BLUE); |
532 t:= round(WaterColorArray[2].r * RGB_LUMINANCE_RED + WaterColorArray[2].g * RGB_LUMINANCE_GREEN + WaterColorArray[2].b * RGB_LUMINANCE_BLUE); |
513 if t > 255 then t:= 255; |
533 if t > 255 then |
|
534 t:= 255; |
514 WaterColorArray[2].r:= t; |
535 WaterColorArray[2].r:= t; |
515 WaterColorArray[2].g:= t; |
536 WaterColorArray[2].g:= t; |
516 WaterColorArray[2].b:= t |
537 WaterColorArray[2].b:= t |
517 end; |
538 end; |
518 WaterColorArray[3]:= WaterColorArray[2]; |
539 WaterColorArray[3]:= WaterColorArray[2]; |
520 else if key = 'water-opacity' then |
541 else if key = 'water-opacity' then |
521 begin |
542 begin |
522 cWaterOpacity:= StrToInt(Trim(s)); |
543 cWaterOpacity:= StrToInt(Trim(s)); |
523 cSDWaterOpacity:= cWaterOpacity |
544 cSDWaterOpacity:= cWaterOpacity |
524 end |
545 end |
525 else if key = 'music' then MusicFN:= Trim(s) |
546 else if key = 'music' then |
|
547 MusicFN:= Trim(s) |
526 else if key = 'clouds' then |
548 else if key = 'clouds' then |
527 begin |
549 begin |
528 cCloudsNumber:= Word(StrToInt(Trim(s))) * cScreenSpace div LAND_WIDTH; |
550 cCloudsNumber:= Word(StrToInt(Trim(s))) * cScreenSpace div LAND_WIDTH; |
529 cSDCloudsNumber:= cCloudsNumber |
551 cSDCloudsNumber:= cCloudsNumber |
530 end |
552 end |
533 inc(ThemeObjects.Count); |
555 inc(ThemeObjects.Count); |
534 with ThemeObjects.objs[Pred(ThemeObjects.Count)] do |
556 with ThemeObjects.objs[Pred(ThemeObjects.Count)] do |
535 begin |
557 begin |
536 i:= Pos(',', s); |
558 i:= Pos(',', s); |
537 Surf:= LoadImage(UserPathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps); |
559 Surf:= LoadImage(UserPathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps); |
538 if Surf = nil then Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifCritical or ifTransparent or ifIgnoreCaps); |
560 if Surf = nil then |
|
561 Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifCritical or ifTransparent or ifIgnoreCaps); |
539 Width:= Surf^.w; |
562 Width:= Surf^.w; |
540 Height:= Surf^.h; |
563 Height:= Surf^.h; |
541 Delete(s, 1, i); |
564 Delete(s, 1, i); |
542 i:= Pos(',', s); |
565 i:= Pos(',', s); |
543 Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
566 Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
544 Delete(s, 1, i); |
567 Delete(s, 1, i); |
545 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then OutError('Object''s max count should be between 1 and '+ inttostr(MAXTHEMEOBJECTS) +' (it was '+ inttostr(Maxcnt) +').', true); |
568 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then |
|
569 OutError('Object''s max count should be between 1 and '+ inttostr(MAXTHEMEOBJECTS) +' (it was '+ inttostr(Maxcnt) +').', true); |
546 with inland do |
570 with inland do |
547 begin |
571 begin |
548 i:= Pos(',', s); |
572 i:= Pos(',', s); |
549 x:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
573 x:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
550 Delete(s, 1, i); |
574 Delete(s, 1, i); |
572 y:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
596 y:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
573 Delete(s, 1, i); |
597 Delete(s, 1, i); |
574 i:= Pos(',', s); |
598 i:= Pos(',', s); |
575 w:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
599 w:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
576 Delete(s, 1, i); |
600 Delete(s, 1, i); |
577 if ii = rectcnt then h:= StrToInt(Trim(s)) |
601 if ii = rectcnt then |
|
602 h:= StrToInt(Trim(s)) |
578 else |
603 else |
579 begin |
604 begin |
580 i:= Pos(',', s); |
605 i:= Pos(',', s); |
581 h:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
606 h:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
582 Delete(s, 1, i) |
607 Delete(s, 1, i) |
590 inc(SprayObjects.Count); |
615 inc(SprayObjects.Count); |
591 with SprayObjects.objs[Pred(SprayObjects.Count)] do |
616 with SprayObjects.objs[Pred(SprayObjects.Count)] do |
592 begin |
617 begin |
593 i:= Pos(',', s); |
618 i:= Pos(',', s); |
594 Surf:= LoadImage(UserPathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps); |
619 Surf:= LoadImage(UserPathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps); |
595 if Surf = nil then Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifCritical or ifTransparent or ifIgnoreCaps); |
620 if Surf = nil then |
|
621 Surf:= LoadImage(Pathz[ptCurrTheme] + '/' + Trim(Copy(s, 1, Pred(i))), ifCritical or ifTransparent or ifIgnoreCaps); |
596 Width:= Surf^.w; |
622 Width:= Surf^.w; |
597 Height:= Surf^.h; |
623 Height:= Surf^.h; |
598 Delete(s, 1, i); |
624 Delete(s, 1, i); |
599 Maxcnt:= StrToInt(Trim(s)); |
625 Maxcnt:= StrToInt(Trim(s)); |
600 end; |
626 end; |
616 vobVelocity:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
642 vobVelocity:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
617 Delete(s, 1, i); |
643 Delete(s, 1, i); |
618 vobFallSpeed:= StrToInt(Trim(s)); |
644 vobFallSpeed:= StrToInt(Trim(s)); |
619 end; |
645 end; |
620 end |
646 end |
621 else if key = 'flatten-flakes' then cFlattenFlakes:= true |
647 else if key = 'flatten-flakes' then |
622 else if key = 'flatten-clouds' then cFlattenClouds:= true |
648 cFlattenFlakes:= true |
|
649 else if key = 'flatten-clouds' then |
|
650 cFlattenClouds:= true |
623 else if key = 'sd-water-top' then |
651 else if key = 'sd-water-top' then |
624 begin |
652 begin |
625 i:= Pos(',', s); |
653 i:= Pos(',', s); |
626 SDWaterColorArray[0].r:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
654 SDWaterColorArray[0].r:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
627 Delete(s, 1, i); |
655 Delete(s, 1, i); |
631 SDWaterColorArray[0].b:= StrToInt(Trim(s)); |
659 SDWaterColorArray[0].b:= StrToInt(Trim(s)); |
632 SDWaterColorArray[0].a := 255; |
660 SDWaterColorArray[0].a := 255; |
633 if cGrayScale then |
661 if cGrayScale then |
634 begin |
662 begin |
635 t:= round(SDWaterColorArray[0].r * RGB_LUMINANCE_RED + SDWaterColorArray[0].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[0].b * RGB_LUMINANCE_BLUE); |
663 t:= round(SDWaterColorArray[0].r * RGB_LUMINANCE_RED + SDWaterColorArray[0].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[0].b * RGB_LUMINANCE_BLUE); |
636 if t > 255 then t:= 255; |
664 if t > 255 then |
|
665 t:= 255; |
637 SDWaterColorArray[0].r:= t; |
666 SDWaterColorArray[0].r:= t; |
638 SDWaterColorArray[0].g:= t; |
667 SDWaterColorArray[0].g:= t; |
639 SDWaterColorArray[0].b:= t |
668 SDWaterColorArray[0].b:= t |
640 end; |
669 end; |
641 SDWaterColorArray[1]:= SDWaterColorArray[0]; |
670 SDWaterColorArray[1]:= SDWaterColorArray[0]; |
651 SDWaterColorArray[2].b:= StrToInt(Trim(s)); |
680 SDWaterColorArray[2].b:= StrToInt(Trim(s)); |
652 SDWaterColorArray[2].a := 255; |
681 SDWaterColorArray[2].a := 255; |
653 if cGrayScale then |
682 if cGrayScale then |
654 begin |
683 begin |
655 t:= round(SDWaterColorArray[2].r * RGB_LUMINANCE_RED + SDWaterColorArray[2].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[2].b * RGB_LUMINANCE_BLUE); |
684 t:= round(SDWaterColorArray[2].r * RGB_LUMINANCE_RED + SDWaterColorArray[2].g * RGB_LUMINANCE_GREEN + SDWaterColorArray[2].b * RGB_LUMINANCE_BLUE); |
656 if t > 255 then t:= 255; |
685 if t > 255 then |
|
686 t:= 255; |
657 SDWaterColorArray[2].r:= t; |
687 SDWaterColorArray[2].r:= t; |
658 SDWaterColorArray[2].g:= t; |
688 SDWaterColorArray[2].g:= t; |
659 SDWaterColorArray[2].b:= t |
689 SDWaterColorArray[2].b:= t |
660 end; |
690 end; |
661 SDWaterColorArray[3]:= SDWaterColorArray[2]; |
691 SDWaterColorArray[3]:= SDWaterColorArray[2]; |
662 end |
692 end |
663 else if key = 'sd-water-opacity' then cSDWaterOpacity:= StrToInt(Trim(s)) |
693 else if key = 'sd-water-opacity' then |
664 else if key = 'sd-clouds' then cSDCloudsNumber:= Word(StrToInt(Trim(s))) * cScreenSpace div LAND_WIDTH |
694 cSDWaterOpacity:= StrToInt(Trim(s)) |
|
695 else if key = 'sd-clouds' then |
|
696 cSDCloudsNumber:= Word(StrToInt(Trim(s))) * cScreenSpace div LAND_WIDTH |
665 else if key = 'sd-flakes' then |
697 else if key = 'sd-flakes' then |
666 begin |
698 begin |
667 i:= Pos(',', s); |
699 i:= Pos(',', s); |
668 vobSDCount:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
700 vobSDCount:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
669 Delete(s, 1, i); |
701 Delete(s, 1, i); |
716 |
749 |
717 procedure AddThemeObjects(var ThemeObjects: TThemeObjects); |
750 procedure AddThemeObjects(var ThemeObjects: TThemeObjects); |
718 var i, ii, t: LongInt; |
751 var i, ii, t: LongInt; |
719 b: boolean; |
752 b: boolean; |
720 begin |
753 begin |
721 if ThemeObjects.Count = 0 then exit; |
754 if ThemeObjects.Count = 0 then |
|
755 exit; |
722 WriteLnToConsole('Adding theme objects...'); |
756 WriteLnToConsole('Adding theme objects...'); |
723 |
757 |
724 for i:=0 to ThemeObjects.Count do |
758 for i:=0 to ThemeObjects.Count do |
725 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 |
759 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 |
726 |
760 |
739 |
773 |
740 procedure AddSprayObjects(Surface: PSDL_Surface; var SprayObjects: TSprayObjects); |
774 procedure AddSprayObjects(Surface: PSDL_Surface; var SprayObjects: TSprayObjects); |
741 var i, ii, t: LongInt; |
775 var i, ii, t: LongInt; |
742 b: boolean; |
776 b: boolean; |
743 begin |
777 begin |
744 if SprayObjects.Count = 0 then exit; |
778 if SprayObjects.Count = 0 then |
|
779 exit; |
745 WriteLnToConsole('Adding spray objects...'); |
780 WriteLnToConsole('Adding spray objects...'); |
746 |
781 |
747 for i:=0 to SprayObjects.Count do |
782 for i:=0 to SprayObjects.Count do |
748 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 |
783 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 |
749 |
784 |