' imgput() ... draw image. support H V flip, 90/180/270 degree rotation. ' by counting_pine ' https://www.freebasic.net/forum/viewtopic.php?t=12074 ' ' Added transparent color by mieki256 (2024/02/06) #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 ' 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] : 0 = Trans, 1 = 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 = 0 ) If transform = TRANSFORM_NONE Then ' transform none If mode = 0 Then Put (x, y), srcImg, Trans Else Put (x, y), srcImg, Pset End If return End If dim as integer srcWidth, srcHeight, srcBypp, srcPitch dim as integer dstWidth, dstHeight, dstBypp, dstPitch dim as integer srcXLow, srcXUpp, srcYLow, srcYUpp, srcDx, srcDy dim as integer dstXLow, dstXUpp, dstYLow, dstYUpp, dstDx, dstDy dim as const integer ptr srcPX1 = @srcXLow, srcPX2 = @srcXUpp dim as const integer ptr srcPY1 = @srcYLow, srcPY2 = @srcYUpp dim as any ptr srcPData, spr, sp dim as any ptr dstPData, dpr, dp dim as integer screenDest = 0 dim as integer rowBytes if imageinfo( srcImg, srcWidth, srcHeight, srcBypp, srcPitch, srcPData ) then exit sub if dstImg <> 0 then if imageinfo( dstImg, dstWidth, dstHeight, dstBypp, dstPitch, dstPData ) then exit sub else dstPData = screenptr: if dstPData = 0 then exit sub screeninfo( dstWidth, dstHeight, , dstBypp, dstPitch ) screenDest = 1 end if if srcBypp <> dstBypp then exit sub srcDx = srcBypp : srcDy = srcPitch srcXLow = 0 : srcXUpp = srcWidth - 1 srcYLow = 0 : srcYUpp = srcHeight - 1 dstDx = dstBypp : dstDy = dstPitch '' set up transform if (transform and TRANSFORM_D1FLIP) then swap srcDx, srcDy swap srcXLow, srcYLow swap srcXUpp, srcYUpp end if if (transform and TRANSFORM_HFLIP) then srcDx = -srcDx: swap srcPX1, srcPX2 if (transform and TRANSFORM_VFLIP) then srcDy = -srcDy: swap srcPY1, srcPY2 '' clipping dstXLow = x: dstXUpp = x + srcXUpp - srcXLow dstYLow = y: dstYUpp = y + srcYUpp - srcYLow if dstXLow < 0 then srcXLow -= dstXLow: dstXLow = 0 if dstYLow < 0 then srcYLow -= dstYLow: dstYLow = 0 if dstXUpp >= dstWidth then srcXUpp += dstWidth-1 - dstXUpp: dstXUpp = dstWidth-1 if dstYUpp >= dstHeight then srcYUpp += dstHeight-1 - dstYUpp: dstYUpp = dstHeight-1 '' find starting corner addresses spr = srcPData + *srcPY1 * abs(srcDy) + *srcPX1 * abs(srcDx) dpr = dstPData + dstYLow * abs(dstDy) + dstXLow * abs(dstDx) '' put image #macro PUT_TYPE( t, tcol ) for y = srcYLow to srcYUpp sp = spr dp = dpr for x = srcXLow to srcXUpp Dim As t c = *cast( t ptr, sp ) If c <> tcol Then *cast( t ptr, dp ) = c sp += srcDx dp += dstDx next x spr += srcDy dpr += dstDy next y #endmacro #macro PUT_TYPE_MSK( t, msk, tcol ) for y = srcYLow to srcYUpp sp = spr dp = dpr for x = srcXLow to srcXUpp Dim As t c = *cast( t ptr, sp ) If (c And msk) <> tcol Then *cast( t ptr, dp ) = c sp += srcDx dp += dstDx next x spr += srcDy dpr += dstDy next y #endmacro #macro PUT_TYPE_PSET( t ) for y = srcYLow to srcYUpp sp = spr dp = dpr for x = srcXLow to srcXUpp *cast( t ptr, dp ) = *cast( t ptr, sp ) sp += srcDx dp += dstDx next x spr += srcDy dpr += dstDy next y #endmacro #macro PUT_ROWS_PSET() rowBytes = srcBypp * (srcXUpp - srcXLow + 1) for y = srcYLow to srcYUpp memcpy( dpr, spr, rowBytes ) spr += srcDy dpr += dstDy next y #endmacro if screenDest then screenlock If mode = 0 Then ' Trans. enable transparent color select case SrcBypp case 1: PUT_TYPE( ubyte, 0 ) case 2: PUT_TYPE( ushort, &HF81F) case 4: PUT_TYPE_MSK( uinteger, &H00FFFFFF, &H00FF00FF ) end select Else ' Pset. disable transparent color if srcDx = srcBypp then PUT_ROWS_PSET() Else select case SrcBypp case 1: PUT_TYPE_PSET( ubyte ) case 2: PUT_TYPE_PSET( ushort ) case 4: PUT_TYPE_PSET( uinteger ) 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 = 0 ) 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