# HG changeset patch # User sheepluva # Date 1480987118 -3600 # Node ID f61bd25b9f70f9bbbac46b1c3013819ae6cdd08b # Parent 22bd1099d51f50871be701c20102307fdb4b3f77 tweak landtex filling some more. cuz it's fun diff -r 22bd1099d51f -r f61bd25b9f70 hedgewars/pas2cRedo.pas --- a/hedgewars/pas2cRedo.pas Tue Dec 06 01:05:46 2016 +0100 +++ b/hedgewars/pas2cRedo.pas Tue Dec 06 02:18:38 2016 +0100 @@ -8,6 +8,7 @@ LongWord = uinteger; Cardinal = uinteger; PtrInt = integer; + SizeInt = PtrInt; Word = uinteger; Byte = integer; SmallInt = integer; diff -r 22bd1099d51f -r f61bd25b9f70 hedgewars/pas2cSystem.pas --- a/hedgewars/pas2cSystem.pas Tue Dec 06 01:05:46 2016 +0100 +++ b/hedgewars/pas2cSystem.pas Tue Dec 06 02:18:38 2016 +0100 @@ -7,6 +7,7 @@ LongWord = uinteger; Cardinal = uinteger; PtrInt = integer; + SizeInt = PtrInt; Word = uinteger; Byte = integer; SmallInt = integer; diff -r 22bd1099d51f -r f61bd25b9f70 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Tue Dec 06 01:05:46 2016 +0100 +++ b/hedgewars/uLand.pas Tue Dec 06 02:18:38 2016 +0100 @@ -165,88 +165,90 @@ end end; -procedure ColorizeLandFast(Surface: PSDL_Surface); -var ltsurf: PSDL_Surface; - x, y, ltw, lth, c, modc, lastfull: LongInt; - srcp, dstp: Pointer; +procedure ColorizeLandFast(mapsurf: PSDL_Surface); +var ltexsurf: PSDL_Surface; + i: LongInt; + ltlnp, srcp, dstp, stopp: Pointer; + c: SizeInt; begin - ltsurf:= LoadDataImage(ptCurrTheme, 'LandTex', ifCritical or ifIgnoreCaps); - ltw:= ltsurf^.w; - lth:= ltsurf^.h; + ltexsurf:= LoadDataImage(ptCurrTheme, 'LandTex', ifCritical or ifIgnoreCaps); - // pointer to ltturf pixels. will be moved from line to line - srcp:= ltsurf^.pixels; - // pointer to Surface pixels. will be moved forward with every move() - dstp:= Surface^.pixels; + // pointer to current line of ltexsurf pixels. will be moved from line to line + ltlnp:= ltexsurf^.pixels; + // pointer to mapsurf pixels. will jump forward after every move() + dstp:= mapsurf^.pixels; + + // time to get serious + SDL_LockSurface(mapsurf); + SDL_LockSurface(ltexsurf); + + // for now only fill a row with the height of landtex. do vertical copies within mapsurf after - // amount of pixels to write per move() - c:= ltsurf^.pitch; - // amount of pixels to write for line's remainer move() - modc:= Surface^.pitch mod c; + // do this loop for each line of ltexsurf (unless we run out of map height first) + for i:= 1 to min(ltexsurf^.h, mapsurf^.h) do + begin + // amount of pixels to write in first move() + c:= ltexsurf^.pitch; - SDL_LockSurface(Surface); - SDL_LockSurface(ltsurf); + // protect from odd cases where landtex wider than map + if c > mapsurf^.pitch then + c:= mapsurf^.pitch; + + // write line of landtex to mapsurf + move(ltlnp^, dstp^, c); - y:= 0; - // last x where a full line from src may be written to - lastfull:= Surface^.w - ltw; - // only copy in one row of landtex. do copies within Surface after - while (y < lth) and (y < Surface^.h) do - begin - x:= 0; - // fill dst line with src lines - while x <= lastfull do + // fill the rest of the line by copying left-to-right until full + + // new src is start of line that we've just written to + srcp:= dstp; + // set stop pointer to start of next pixel line of mapsurf + stopp:= dstp + mapsurf^.pitch; + // move dst pointer to after what we've just written + inc(dstp, c); + + // loop until dstp went past end of line + while dstp < stopp do begin + // copy all from left of dstp to right of it (or just fill the gap if smaller) + c:= min(dstp-srcp, stopp-dstp); move(srcp^, dstp^, c); inc(dstp, c); - inc(x, ltw); end; - // if it didn't fit perfectly, copy remainder - if modc > 0 then - begin - move(srcp^, dstp^, modc); - inc(dstp, modc); - end; - - // move to next line in src surface - inc(srcp, ltsurf^.pitch); - inc(y); + // move to next line in ltexsurf + inc(ltlnp, ltexsurf^.pitch); end; - // we don't need ltsurf anymore -> cleanup - srcp:= nil; - SDL_UnlockSurface(ltsurf); - SDL_FreeSurface(ltsurf); + // we don't need ltexsurf itself anymore -> cleanup + ltlnp:= nil; + SDL_UnlockSurface(ltexsurf); + SDL_FreeSurface(ltexsurf); + ltexsurf:= nil; - // from now on only copy pixels within Surface + // from now on only copy pixels within mapsurf - // start reading from position 0, but continue writing at dstp - srcp:= Surface^.pixels; // copy all the already written lines at once for that get number of written bytes so far - c:= dstp - srcp; // effectively same as c:= lth * Surface^.pitch; - // also figure out the remainder again - modc:= (Surface^.h mod lth) * Surface^.pitch; // effectivle same as modc:= (Surface^.pitch * Surface^.h) mod c; + // already written pixels are between start and current dstp + srcp:= mapsurf^.pixels; - // last y where a full copy may be written to - lastfull:= Surface^.h - lth; + // first byte after end of pixels + stopp:= srcp + (mapsurf^.pitch * mapsurf^.h); - // copy filled area down - while y <= lastfull do + while dstp < stopp do begin + // copy all from before dstp to after (or just fill the gap if smaller) + c:= min(dstp-srcp, stopp-dstp); + // worried about size of c with humongous maps? don't be: + // the OS wouldn't have allowed allocation of object with size > max of SizeInt anyway move(srcp^, dstp^, c); - inc(srcp, c); inc(dstp, c); - inc(y, lth); end; - // if it didn't fit perfectly, copy remainder - if modc > 0 then - begin - move(srcp^, dstp^, modc); - end; - - SDL_UnlockSurface(Surface); + // cleanup + srcp:= nil; + dstp:= nil; + stopp:= nil; + SDL_UnlockSurface(mapsurf); // freed in freeModule() below LandBackSurface:= LoadDataImage(ptCurrTheme, 'LandBackTex', ifIgnoreCaps or ifTransparent);