' imgput() ... draw image. support H V flip, 90/180/270 degree rotation. ' Original by counting_pine ' https://www.freebasic.net/forum/viewtopic.php?t=12074 ' ' Added transparent color by mieki256 (2024/02/06) ' Last updated: <2024/02/07 21:11:30 +0900> #ifndef __IMGPUTT__ #define __IMGPUTT__ #include "crt.bi" enum IMGPUT_TRANSFORM TRANSFORM_HFLIP = 1 TRANSFORM_VFLIP = 2 TRANSFORM_D1FLIP = 4 TRANSFORM_R90 = TRANSFORM_HFLIP or TRANSFORM_D1FLIP TRANSFORM_R180 = TRANSFORM_HFLIP or TRANSFORM_VFLIP TRANSFORM_R270 = TRANSFORM_VFLIP or TRANSFORM_D1FLIP TRANSFORM_D2FLIP = TRANSFORM_R180 or TRANSFORM_D1FLIP TRANSFORM_NONE = 0 end enum #define IMGPUT_TRANS 0 #define IMGPUT_PSET 1 ' imgputt ' Put the image to screen. enable transparent color ' ' srcImg : Source image ' [dstImg] : Destination buffer (image). Default 0 ' [x, y] : position. Default (0, 0) ' [transform] : Transform type. look IMGPUT_TRANSFORM. Default TRANSFORM_NONE ' [mode] : IMGPUT_TRANS = 0 is Trans, IMGPUT_PSET = 1 is Pset sub imgputt overload( _ byval srcImg as any ptr, _ byval dstImg as any ptr = 0, _ byval x as integer = 0, _ byval y as integer = 0, _ byval transform as IMGPUT_TRANSFORM = TRANSFORM_NONE, _ ByVal mode As Integer = IMGPUT_TRANS ) If transform = TRANSFORM_NONE Then ' transform none If mode = IMGPUT_TRANS Then Put (x, y), srcImg, Trans Else Put (x, y), srcImg, Pset End If return End If Dim As Integer simgw, simgh, dimgw, dimgh ' width, height Dim As Integer srcBypp, dstBypp ' 1 dot byte size Dim As Integer spitch, dpitch ' 1 raster byte size dim as integer sx0, sx1, sy0, sy1, sdx, sdy dim as integer dx0, dx1, dy0, dy1, ddx, ddy dim as const integer ptr spx1 = @sx0, spx2 = @sx1 dim as const integer ptr spy1 = @sy0, spy2 = @sy1 dim as any ptr srcPData, dstPData dim as integer screenDest = 0 ' get source image information if imageinfo( srcImg, simgw, simgh, srcBypp, spitch, srcPData ) then exit Sub ' get dest image information if dstImg <> 0 then if imageinfo( dstImg, dimgw, dimgh, dstBypp, dpitch, dstPData ) then exit sub else dstPData = Screenptr() if dstPData = NULL then exit sub screeninfo( dimgw, dimgh, , dstBypp, dpitch ) screenDest = 1 end if if srcBypp <> dstBypp then exit sub sdx = srcBypp ' 1 dot byte size sdy = spitch ' 1 raster byte size sx0 = 0 sx1 = simgw - 1 sy0 = 0 sy1 = simgh - 1 ddx = dstBypp ddy = dpitch '' set up transform if (transform and TRANSFORM_D1FLIP) then swap sdx, sdy swap sx0, sy0 swap sx1, sy1 end If if (transform and TRANSFORM_HFLIP) Then sdx = -sdx swap spx1, spx2 End If if (transform and TRANSFORM_VFLIP) Then sdy = -sdy swap spy1, spy2 End If ' clipping dx0 = x dy0 = y dx1 = x + sx1 - sx0 dy1 = y + sy1 - sy0 ' check out of area If dx0 >= dimgw Or dx1 < 0 Or dy0 >= dimgh Or dy1 < 0 Then Return if dx0 < 0 then sx0 -= dx0 : dx0 = 0 if dy0 < 0 then sy0 -= dy0 : dy0 = 0 if dx1 >= dimgw then sx1 += (dimgw - 1 - dx1) : dx1 = (dimgw - 1) if dy1 >= dimgh then sy1 += (dimgh - 1 - dy1) : dy1 = (dimgh - 1) ' find starting corner addresses dim as any ptr spr, dpr spr = srcPData + *spy1 * abs(sdy) + *spx1 * abs(sdx) dpr = dstPData + dy0 * abs(ddy) + dx0 * abs(ddx) ' put image if screenDest then screenlock If mode = 0 Then ' Trans. enable transparent color select case SrcBypp case 1: ' 8bit mode Dim As ubyte ptr sp, dp for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 If *sp <> 0 Then *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y case 2: ' 16bit mode Dim As ushort ptr sp, dp sdx /= 2 for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 If *sp <> &HF81F Then *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y case 4: ' 32bit mode Dim As ulong ptr sp, dp sdx /= 4 for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 If (*sp And &H00FFFFFF) <> &H00FF00FF Then *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y end select Else ' Pset. disable transparent color if sdx = srcBypp then dim as integer rowBytes = srcBypp * (sx1 - sx0 + 1) for y = sy0 to sy1 memcpy( dpr, spr, rowBytes ) spr += sdy dpr += ddy next y Else select case SrcBypp case 1: ' 8bit mode Dim As ubyte ptr sp, dp for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y case 2: ' 16bit mode Dim As ushort ptr sp, dp sdx /= 2 for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y case 4: ' 32bit mode Dim As ulong ptr sp, dp sdx /= 4 for y As Integer = sy0 to sy1 sp = spr dp = dpr for x As Integer = sx0 to sx1 *dp = *sp sp += sdx dp += 1 next x spr += sdy dpr += ddy next y end select End If End If if screenDest then screenunlock end sub ' imgputt ' ' transform : Transform type. 0, 90, 180, 270 or IMGPUT_TRANSFORM sub imgputt overload( _ byval srcImg as any ptr, _ byval dstImg as any ptr = 0, _ byval x as integer = 0, _ byval y as integer = 0, _ byval transform as integer, _ ByVal mode As Integer = IMGPUT_TRANS ) if transform and -8 then select case transform mod 360 case 0: transform = TRANSFORM_NONE case 90, -270: transform = TRANSFORM_R90 case 180, -180: transform = TRANSFORM_R180 case 270, -90: transform = TRANSFORM_R270 end select end if imgputt( srcImg, dstImg, x, y, cast(IMGPUT_TRANSFORM, transform), mode ) end sub #endif