147 // copy from complete src |
147 // copy from complete src |
148 copyToXYFromRect(src, dest, 0, 0, src^.w, src^.h, destX, destY); |
148 copyToXYFromRect(src, dest, 0, 0, src^.w, src^.h, destX, destY); |
149 end; |
149 end; |
150 |
150 |
151 procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); |
151 procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt); |
152 var i, j, iX, iY, dX, dY, lX, lY: LongInt; |
152 var spi, dpi, iX, iY, dX, dY, lX, lY, aT: LongInt; |
153 srcPixels, destPixels: PLongWordArray; |
153 srcPixels, destPixels: PLongWordArray; |
154 r0, g0, b0, a0, r1, g1, b1, a1: Byte; |
154 rD, gD, bD, aD, rT, gT, bT: Byte; |
155 begin |
155 begin |
156 SDL_LockSurface(src); |
156 SDL_LockSurface(src); |
157 SDL_LockSurface(dest); |
157 SDL_LockSurface(dest); |
158 |
158 |
159 srcPixels:= src^.pixels; |
159 srcPixels:= src^.pixels; |
162 // what's the offset between src and dest coords? |
162 // what's the offset between src and dest coords? |
163 dX:= destX - srcX; |
163 dX:= destX - srcX; |
164 dY:= destY - srcY; |
164 dY:= destY - srcY; |
165 |
165 |
166 // let's figure out where the rectangle we can actually copy ends |
166 // let's figure out where the rectangle we can actually copy ends |
167 lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW + dx, dest^.w) - dx ) ) - 1; |
167 lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW, dest^.w) - dx ) ) - 1; |
168 lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH + dy, dest^.h) - dY ) ) - 1; |
168 lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH, dest^.h) - dY ) ) - 1; |
169 |
169 |
170 for iX:= srcX to lX do |
170 for iX:= srcX to lX do |
171 for iY:= srcY to lY do |
171 for iY:= srcY to lY do |
172 begin |
172 begin |
173 i:= (iY + dY) * dest^.w + (iX + dX); |
173 // src pixel index |
174 j:= iY * src^.w + iX; |
174 spi:= iY * src^.w + iX; |
175 if srcPixels^[j] and AMask <> 0 then |
175 // dest pixel index |
176 begin |
176 dpi:= (iY + dY) * dest^.w + (iX + dX); |
177 SDL_GetRGBA(destPixels^[i], dest^.format, @r0, @g0, @b0, @a0); |
177 |
178 SDL_GetRGBA(srcPixels^[j], src^.format, @r1, @g1, @b1, @a1); |
178 // get src alpha (and set it as target alpha for now) |
179 r0:= (r0 * (255 - LongInt(a1)) + r1 * LongInt(a1)) div 255; |
179 aT:= (srcPixels^[spi] and AMask) shr AShift; |
180 g0:= (g0 * (255 - LongInt(a1)) + g1 * LongInt(a1)) div 255; |
180 |
181 b0:= (b0 * (255 - LongInt(a1)) + b1 * LongInt(a1)) div 255; |
181 // src pixel opaque? |
182 a0:= a0 + ((255 - LongInt(a0)) * a1 div 255); |
182 if aT = 255 then |
183 destPixels^[i]:= SDL_MapRGBA(dest^.format, r0, g0, b0, a0); |
183 begin |
184 end; |
184 // just copy full pixel |
|
185 destPixels^[dpi]:= srcPixels^[spi]; |
|
186 continue; |
|
187 end; |
|
188 |
|
189 // get dst alpha (without shift for now) |
|
190 aD:= (destPixels^[dpi] and AMask) shr AShift; |
|
191 |
|
192 // dest completely transparent? |
|
193 if aD = 0 then |
|
194 begin |
|
195 // just copy src pixel |
|
196 destPixels^[dpi]:= srcPixels^[spi]; |
|
197 continue; |
|
198 end; |
|
199 |
|
200 // looks like some blending is necessary |
|
201 |
|
202 // set color of target RGB to src for now |
|
203 SDL_GetRGB(srcPixels^[spi], src^.format, @rT, @gT, @bT); |
|
204 SDL_GetRGB(destPixels^[dpi], dest^.format, @rD, @gD, @bD); |
|
205 // note: this is not how to correctly blend RGB, just sayin' (R,G,B are not linear...) |
|
206 rT:= (rD * (255 - aT) + rT * aT) div 255; |
|
207 gT:= (gD * (255 - aT) + gT * aT) div 255; |
|
208 bT:= (bD * (255 - aT) + bT * aT) div 255; |
|
209 aT:= aD + ((255 - LongInt(aD)) * aT div 255); |
|
210 |
|
211 destPixels^[dpi]:= SDL_MapRGBA(dest^.format, rT, gT, bT, aT); |
185 end; |
212 end; |
186 |
213 |
187 SDL_UnlockSurface(src); |
214 SDL_UnlockSurface(src); |
188 SDL_UnlockSurface(dest); |
215 SDL_UnlockSurface(dest); |
189 end; |
216 end; |
190 |
217 |
191 procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline; |
218 procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline; |
192 begin |
219 begin |
193 DrawSpriteFrame2Surf(sprite, dest, x, y, 0); |
220 DrawSpriteFrame2Surf(sprite, dest, x, y, 0); |
194 end; |
221 end; |
195 |
222 |
196 procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt); |
223 procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt); |
197 var numFramesFirstCol, row, col: LongInt; |
224 var numFramesFirstCol, row, col: LongInt; |
198 begin |
225 begin |