1 (* |
1 (* |
2 * Hedgewars, a free turn based strategy game |
2 * Hedgewars, a free turn based strategy game |
3 * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com> |
3 * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com> |
4 * |
4 * |
5 * This program is free software; you can redistribute it and/or modify |
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 |
6 * it under the terms of the GNU General Public License as published by |
7 * the Free Software Foundation; version 2 of the License |
7 * the Free Software Foundation; version 2 of the License |
8 * |
8 * |
25 procedure AddObjects(); |
25 procedure AddObjects(); |
26 procedure FreeLandObjects(); |
26 procedure FreeLandObjects(); |
27 procedure LoadThemeConfig; |
27 procedure LoadThemeConfig; |
28 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; |
28 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; |
29 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); |
29 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word); |
|
30 procedure BlitImageUsingMask(cpX, cpY: Longword; Image, Mask: PSDL_Surface); |
30 procedure AddOnLandObjects(Surface: PSDL_Surface); |
31 procedure AddOnLandObjects(Surface: PSDL_Surface); |
|
32 procedure SetLand(var LandWord: Word; Pixel: LongWord); inline; |
31 |
33 |
32 implementation |
34 implementation |
33 uses uStore, uConsts, uConsole, uRandom, uSound, GLunit |
35 uses uStore, uConsts, uConsole, uRandom, uSound, GLunit |
34 , uTypes, uVariables, uUtils, uDebug, SysUtils |
36 , uTypes, uVariables, uUtils, uDebug, SysUtils |
35 , uPhysFSLayer; |
37 , uPhysFSLayer; |
40 cThemeCFGFilename = 'theme.cfg'; |
42 cThemeCFGFilename = 'theme.cfg'; |
41 |
43 |
42 type TRectsArray = array[0..MaxRects] of TSDL_Rect; |
44 type TRectsArray = array[0..MaxRects] of TSDL_Rect; |
43 PRectArray = ^TRectsArray; |
45 PRectArray = ^TRectsArray; |
44 TThemeObject = record |
46 TThemeObject = record |
45 Surf: PSDL_Surface; |
47 Surf, Mask: PSDL_Surface; |
46 inland: TSDL_Rect; |
48 inland: TSDL_Rect; |
47 outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect; |
49 outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect; |
48 rectcnt: Longword; |
50 rectcnt: Longword; |
49 Width, Height: Longword; |
51 Width, Height: Longword; |
50 Maxcnt: Longword; |
52 Maxcnt: Longword; |
66 var Rects: PRectArray; |
68 var Rects: PRectArray; |
67 RectCount: Longword; |
69 RectCount: Longword; |
68 ThemeObjects: TThemeObjects; |
70 ThemeObjects: TThemeObjects; |
69 SprayObjects: TSprayObjects; |
71 SprayObjects: TSprayObjects; |
70 |
72 |
71 |
73 procedure SetLand(var LandWord: Word; Pixel: LongWord); inline; |
|
74 begin |
|
75 // this an if instead of masking colours to avoid confusing map creators |
|
76 if ((AMask and Pixel) = 0) then |
|
77 LandWord:= 0 |
|
78 else if Pixel = $FFFFFFFF then // white |
|
79 LandWord:= lfObject |
|
80 else if Pixel = AMask then // black |
|
81 begin |
|
82 LandWord:= lfBasic; |
|
83 disableLandBack:= false |
|
84 end |
|
85 else if Pixel = (AMask or RMask) then // red |
|
86 LandWord:= lfIndestructible |
|
87 else if Pixel = (AMask or BMask) then // blue |
|
88 LandWord:= lfObject or lfIce |
|
89 else if Pixel = (AMask or GMask) then // green |
|
90 LandWord:= lfObject or lfBouncy |
|
91 end; |
72 |
92 |
73 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; |
93 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline; |
74 begin |
94 begin |
75 BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0); |
95 BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0); |
76 end; |
96 end; |
112 Land[cpY + y, cpX + x]:= lfObject; |
132 Land[cpY + y, cpX + x]:= lfObject; |
113 Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags |
133 Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags |
114 end; |
134 end; |
115 end; |
135 end; |
116 p:= @(p^[Image^.pitch shr 2]) |
136 p:= @(p^[Image^.pitch shr 2]) |
|
137 end; |
|
138 |
|
139 if SDL_MustLock(Image) then |
|
140 SDL_UnlockSurface(Image); |
|
141 WriteLnToConsole(msgOK) |
|
142 end; |
|
143 |
|
144 procedure BlitImageUsingMask(cpX, cpY: Longword; Image, Mask: PSDL_Surface); |
|
145 var p, mp: PLongwordArray; |
|
146 x, y: Longword; |
|
147 bpp: LongInt; |
|
148 begin |
|
149 WriteToConsole('Generating collision info... '); |
|
150 |
|
151 if SDL_MustLock(Image) then |
|
152 SDLTry(SDL_LockSurface(Image) >= 0, true); |
|
153 |
|
154 bpp:= Image^.format^.BytesPerPixel; |
|
155 TryDo(bpp = 4, 'Land object should be 32bit', true); |
|
156 |
|
157 p:= Image^.pixels; |
|
158 mp:= Mask^.pixels; |
|
159 for y:= 0 to Pred(Image^.h) do |
|
160 begin |
|
161 for x:= 0 to Pred(Image^.w) do |
|
162 begin |
|
163 if (cReducedQuality and rqBlurryLand) = 0 then |
|
164 begin |
|
165 if (LandPixels[cpY + y, cpX + x] = 0) |
|
166 or (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then |
|
167 LandPixels[cpY + y, cpX + x]:= p^[x]; |
|
168 end |
|
169 else |
|
170 if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then |
|
171 LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x]; |
|
172 |
|
173 if (Land[cpY + y, cpX + x] <= lfAllObjMask) or (Land[cpY + y, cpX + x] and lfObject <> 0) then |
|
174 SetLand(Land[cpY + y, cpX + x], mp^[x]); |
|
175 end; |
|
176 p:= @(p^[Image^.pitch shr 2]); |
|
177 mp:= @(mp^[Mask^.pitch shr 2]) |
117 end; |
178 end; |
118 |
179 |
119 if SDL_MustLock(Image) then |
180 if SDL_MustLock(Image) then |
120 SDL_UnlockSurface(Image); |
181 SDL_UnlockSurface(Image); |
121 WriteLnToConsole(msgOK) |
182 WriteLnToConsole(msgOK) |
326 until x >= LAND_WIDTH - Width; |
387 until x >= LAND_WIDTH - Width; |
327 bRes:= cnt <> 0; |
388 bRes:= cnt <> 0; |
328 if bRes then |
389 if bRes then |
329 begin |
390 begin |
330 i:= getrandom(cnt); |
391 i:= getrandom(cnt); |
331 BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf); |
392 if Obj.Mask <> nil then |
|
393 BlitImageUsingMask(ar[i].x, ar[i].y, Obj.Surf, Obj.Mask) |
|
394 else BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf); |
332 AddRect(ar[i].x, ar[i].y, Width, Height); |
395 AddRect(ar[i].x, ar[i].y, Width, Height); |
333 dec(Maxcnt) |
396 dec(Maxcnt) |
334 end |
397 end |
335 else Maxcnt:= 0 |
398 else Maxcnt:= 0 |
336 end; |
399 end; |
555 begin |
618 begin |
556 inc(ThemeObjects.Count); |
619 inc(ThemeObjects.Count); |
557 with ThemeObjects.objs[Pred(ThemeObjects.Count)] do |
620 with ThemeObjects.objs[Pred(ThemeObjects.Count)] do |
558 begin |
621 begin |
559 i:= Pos(',', s); |
622 i:= Pos(',', s); |
560 Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps); |
623 Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps or ifCritical); |
561 Width:= Surf^.w; |
624 Width:= Surf^.w; |
562 Height:= Surf^.h; |
625 Height:= Surf^.h; |
|
626 Mask:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i)))+'_mask', ifTransparent or ifIgnoreCaps); |
563 Delete(s, 1, i); |
627 Delete(s, 1, i); |
564 i:= Pos(',', s); |
628 i:= Pos(',', s); |
565 Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
629 Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i)))); |
566 Delete(s, 1, i); |
630 Delete(s, 1, i); |
567 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then |
631 if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then |