163 LandPixels[y div 2, x div 2]:= c |
163 LandPixels[y div 2, x div 2]:= c |
164 end; |
164 end; |
165 end |
165 end |
166 end; |
166 end; |
167 |
167 |
168 procedure ColorizeLandFast(Surface: PSDL_Surface); |
168 procedure ColorizeLandFast(mapsurf: PSDL_Surface); |
169 var ltsurf: PSDL_Surface; |
169 var ltexsurf: PSDL_Surface; |
170 x, y, ltw, lth, c, modc, lastfull: LongInt; |
170 i: LongInt; |
171 srcp, dstp: Pointer; |
171 ltlnp, srcp, dstp, stopp: Pointer; |
172 begin |
172 c: SizeInt; |
173 ltsurf:= LoadDataImage(ptCurrTheme, 'LandTex', ifCritical or ifIgnoreCaps); |
173 begin |
174 ltw:= ltsurf^.w; |
174 ltexsurf:= LoadDataImage(ptCurrTheme, 'LandTex', ifCritical or ifIgnoreCaps); |
175 lth:= ltsurf^.h; |
175 |
176 |
176 // pointer to current line of ltexsurf pixels. will be moved from line to line |
177 // pointer to ltturf pixels. will be moved from line to line |
177 ltlnp:= ltexsurf^.pixels; |
178 srcp:= ltsurf^.pixels; |
178 // pointer to mapsurf pixels. will jump forward after every move() |
179 // pointer to Surface pixels. will be moved forward with every move() |
179 dstp:= mapsurf^.pixels; |
180 dstp:= Surface^.pixels; |
180 |
181 |
181 // time to get serious |
182 // amount of pixels to write per move() |
182 SDL_LockSurface(mapsurf); |
183 c:= ltsurf^.pitch; |
183 SDL_LockSurface(ltexsurf); |
184 // amount of pixels to write for line's remainer move() |
184 |
185 modc:= Surface^.pitch mod c; |
185 // for now only fill a row with the height of landtex. do vertical copies within mapsurf after |
186 |
186 |
187 SDL_LockSurface(Surface); |
187 // do this loop for each line of ltexsurf (unless we run out of map height first) |
188 SDL_LockSurface(ltsurf); |
188 for i:= 1 to min(ltexsurf^.h, mapsurf^.h) do |
189 |
189 begin |
190 y:= 0; |
190 // amount of pixels to write in first move() |
191 // last x where a full line from src may be written to |
191 c:= ltexsurf^.pitch; |
192 lastfull:= Surface^.w - ltw; |
192 |
193 // only copy in one row of landtex. do copies within Surface after |
193 // protect from odd cases where landtex wider than map |
194 while (y < lth) and (y < Surface^.h) do |
194 if c > mapsurf^.pitch then |
195 begin |
195 c:= mapsurf^.pitch; |
196 x:= 0; |
196 |
197 // fill dst line with src lines |
197 // write line of landtex to mapsurf |
198 while x <= lastfull do |
198 move(ltlnp^, dstp^, c); |
199 begin |
199 |
|
200 // fill the rest of the line by copying left-to-right until full |
|
201 |
|
202 // new src is start of line that we've just written to |
|
203 srcp:= dstp; |
|
204 // set stop pointer to start of next pixel line of mapsurf |
|
205 stopp:= dstp + mapsurf^.pitch; |
|
206 // move dst pointer to after what we've just written |
|
207 inc(dstp, c); |
|
208 |
|
209 // loop until dstp went past end of line |
|
210 while dstp < stopp do |
|
211 begin |
|
212 // copy all from left of dstp to right of it (or just fill the gap if smaller) |
|
213 c:= min(dstp-srcp, stopp-dstp); |
200 move(srcp^, dstp^, c); |
214 move(srcp^, dstp^, c); |
201 inc(dstp, c); |
215 inc(dstp, c); |
202 inc(x, ltw); |
|
203 end; |
216 end; |
204 |
217 |
205 // if it didn't fit perfectly, copy remainder |
218 // move to next line in ltexsurf |
206 if modc > 0 then |
219 inc(ltlnp, ltexsurf^.pitch); |
207 begin |
220 end; |
208 move(srcp^, dstp^, modc); |
221 |
209 inc(dstp, modc); |
222 // we don't need ltexsurf itself anymore -> cleanup |
210 end; |
223 ltlnp:= nil; |
211 |
224 SDL_UnlockSurface(ltexsurf); |
212 // move to next line in src surface |
225 SDL_FreeSurface(ltexsurf); |
213 inc(srcp, ltsurf^.pitch); |
226 ltexsurf:= nil; |
214 inc(y); |
227 |
215 end; |
228 // from now on only copy pixels within mapsurf |
216 |
229 |
217 // we don't need ltsurf anymore -> cleanup |
230 // copy all the already written lines at once for that get number of written bytes so far |
|
231 // already written pixels are between start and current dstp |
|
232 srcp:= mapsurf^.pixels; |
|
233 |
|
234 // first byte after end of pixels |
|
235 stopp:= srcp + (mapsurf^.pitch * mapsurf^.h); |
|
236 |
|
237 while dstp < stopp do |
|
238 begin |
|
239 // copy all from before dstp to after (or just fill the gap if smaller) |
|
240 c:= min(dstp-srcp, stopp-dstp); |
|
241 // worried about size of c with humongous maps? don't be: |
|
242 // the OS wouldn't have allowed allocation of object with size > max of SizeInt anyway |
|
243 move(srcp^, dstp^, c); |
|
244 inc(dstp, c); |
|
245 end; |
|
246 |
|
247 // cleanup |
218 srcp:= nil; |
248 srcp:= nil; |
219 SDL_UnlockSurface(ltsurf); |
249 dstp:= nil; |
220 SDL_FreeSurface(ltsurf); |
250 stopp:= nil; |
221 |
251 SDL_UnlockSurface(mapsurf); |
222 // from now on only copy pixels within Surface |
|
223 |
|
224 // start reading from position 0, but continue writing at dstp |
|
225 srcp:= Surface^.pixels; |
|
226 // copy all the already written lines at once for that get number of written bytes so far |
|
227 c:= dstp - srcp; // effectively same as c:= lth * Surface^.pitch; |
|
228 // also figure out the remainder again |
|
229 modc:= (Surface^.h mod lth) * Surface^.pitch; // effectivle same as modc:= (Surface^.pitch * Surface^.h) mod c; |
|
230 |
|
231 // last y where a full copy may be written to |
|
232 lastfull:= Surface^.h - lth; |
|
233 |
|
234 // copy filled area down |
|
235 while y <= lastfull do |
|
236 begin |
|
237 move(srcp^, dstp^, c); |
|
238 inc(srcp, c); |
|
239 inc(dstp, c); |
|
240 inc(y, lth); |
|
241 end; |
|
242 |
|
243 // if it didn't fit perfectly, copy remainder |
|
244 if modc > 0 then |
|
245 begin |
|
246 move(srcp^, dstp^, modc); |
|
247 end; |
|
248 |
|
249 SDL_UnlockSurface(Surface); |
|
250 |
252 |
251 // freed in freeModule() below |
253 // freed in freeModule() below |
252 LandBackSurface:= LoadDataImage(ptCurrTheme, 'LandBackTex', ifIgnoreCaps or ifTransparent); |
254 LandBackSurface:= LoadDataImage(ptCurrTheme, 'LandBackTex', ifIgnoreCaps or ifTransparent); |
253 if (LandBackSurface <> nil) and GrayScale then Surface2GrayScale(LandBackSurface); |
255 if (LandBackSurface <> nil) and GrayScale then Surface2GrayScale(LandBackSurface); |
254 end; |
256 end; |