TGC Codebase Backup



DBC FloodFill using Memblock by Ashingda 27

17th Feb 2009 15:56
Summary

Fill a 2d area with a solid color.



Description

Fill a 2d area with a solid color. This function works with both the 16bit and 32bit modes. You can optimize this function to run a bit faster by using a second bitmap and copying it to the screen befor you sync.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    REM ******************************************************************
REM *                                                                *
REM *                DBClassic FloodFill Using Memblock              *
REM *                                                                *
REM ******************************************************************
REM * - Ashingda27                                                   *
REM ******************************************************************
set display mode 640,480,16

sync on
sync rate 0

gosub FloodFillInitialize
gosub TestInitialize


REM **********************************************************************
REM Main Loop
REM **********************************************************************
do
   REM Mouse Input
   mx = mousex()-1
   my = mousey()-1
   mc = mouseclick()


   REM Mouse Check
   if mc = 1
      if KeyM = 0

         REM Start Timer
         T = Timer()

         REM Setting random Fill Color
         c = rgb(rnd(255),rnd(255),rnd(255))

         REM Calling the Function
         FloodFill(mx,my,c)

         REM End Timer
         T = Timer()-T

      endif
      KeyM = 1
      else
      KeyM = 0
   endif

   REM Print the Speed
   ink rgb(255,255,255),0
   text 200,0,"Speed: "+str$(T)+"      "

   REM Update the Screen
   sync

loop




REM **********************************************************************
REM Test Initialize
REM **********************************************************************
TestInitialize:
   REM Draws some shapes to be filled.
   ink rgb(255,255,255),0
   box 320-25,240-5,320+25,240+10
   ink 0,0
   center text 320,240-5,"FloodFill"
   ink rgb(255,255,255),0
   text 0,0,"Click mouse to fill!"

   line 320,10,320-100,10+100
   line 320-100,10+100,320+100,10+100
   line 320,10,320+100,10+100

   circle 100,300,50
   circle 150,350,50

   box 400,300,450,350
   box 500,300,550,350
   line 400,325,500,325

   set text opaque
return




REM **********************************************************************
REM FloodFill Initialize
REM **********************************************************************
FloodFillInitialize:
   wd = bitmap width(0)
   ht = bitmap height(0)
   dp = bitmap depth(0)

   REM Global Variables for FloodFill Function
   dim FloodWidth(0)
   dim FloodHeight(0)
   dim FloodBytes(0)
   dim FloodTargetColor(0)
   dim FloodFillColor(0)

   dim ScanLeftU(0)
   dim ScanRightU(0)
   dim ScanLeftD(ht)
   dim ScanRightD(ht)

   REM Variables used with the Memblock
   FloodWidth(0) = wd
   FloodHeight(0) = ht
   FloodBytes(0) = dp/8
return




REM **********************************************************************
REM Function FloodFill
REM **********************************************************************
Function FloodFill(x,y,FillColor)

   REM Reset Value
   ScanLeftU(0) = 0
   ScanRightU(0) = 0

   REM Reset Array Value
   for Lp = 0 to FloodHeight(0)
      ScanLeftD(Lp) = 0
      ScanRightD(Lp) = 0
   next Lp

   REM Creating the Memblock from the second Bitmap.
   get image 2,0,0,FloodWidth(0),FloodHeight(0),1
   sync
   make memblock from image 1,2


   REM 16Bit Mode or 32bit mode
   if FloodBytes(0) = 2

      REM Getting the FillColor
      r = (rgbr(FillColor)*63488)/255&63488
      g = (rgbg(FillColor)*2016)/255&2016
      b = (rgbb(FillColor)*31)/255&31

      FloodFillColor(0) = r|g|b

      REM Getting Target Color
      pos = 12+(x+y*FloodWidth(0))*FloodBytes(0)
      FloodTargetColor(0) = memblock word(1,pos)
      REM Fills the first Dot
      write memblock word 1,pos,FloodFillColor(0)

      else

      REM Getting the FillColor
      FloodFillColor(0) = FillColor
      REM Getting Target Color
      pos = 12+(x+y*FloodWidth(0))*FloodBytes(0)
      FloodTargetColor(0) = memblock dword(1,pos)
      REM Fills the first Dot
      write memblock dword 1,pos,FloodFillColor(0)

   endif


   REM Calling the FloodLoop
   if FloodTargetColor(0) <> FloodFillColor(0) then FloodLoop(x,y)

   REM Convert to Image and paste onto screen
   make image from memblock 1,1
   paste image 1,0,0

EndFunction




REM **********************************************************************
REM Function FloodLoop
REM **********************************************************************
Function FloodLoop(x,y)

   posY = y*FloodWidth(0)

   REM Left
   for Left = x-1 to 0 step -1
      pos = 12+(Left+posY)*FloodBytes(0)
      REM Check 16bit or 32bit
      if FloodBytes(0) = 2
         if memblock word(1,pos) <> FloodTargetColor(0) then exit
         write memblock word 1,pos,FloodFillColor(0)
         else
         if memblock dword(1,pos) <> FloodTargetColor(0) then exit
         write memblock dword 1,pos,FloodFillColor(0)
      endif
   next Left
   inc Left

   REM Right
   for Right = x+1 to FloodWidth(0)-1
      pos = 12+(Right+posY)*FloodBytes(0)
      REM Check 16bit or 32bit
      if FloodBytes(0) = 2
         if memblock word(1,pos) <> FloodTargetColor(0) then exit
         write memblock word 1,pos,FloodFillColor(0)
         else
         if memblock dword(1,pos) <> FloodTargetColor(0) then exit
         write memblock dword 1,pos,FloodFillColor(0)
      endif
   next Right
   dec Right


   REM Move Up
   dec y
   posY = y*FloodWidth(0)

   if y > 0

      for x = Left to Right

         if x < ScanLeftU(0) or x > ScanRightU(0)

            pos = 12+(x+posY)*FloodBytes(0)

            REM Check 16bit or 32bit
            if FloodBytes(0) = 2
               if memblock word(1,pos) = FloodTargetColor(0)
                  ScanLeftD(y) = Left
                  ScanRightD(y) = Right
                  write memblock word 1,pos,FloodFillColor(0)
                  FloodLoop(x,y)
               endif
               else
               if memblock dword(1,pos) = FloodTargetColor(0)
                  ScanLeftD(y) = Left
                  ScanRightD(y) = Right
                  write memblock dword 1,pos,FloodFillColor(0)
                  FloodLoop(x,y)
               endif
            endif

            else
            x = ScanRightU(0)+1

         endif

      next x

   endif
   inc y

   ScanLeftU(0) = Left
   ScanRightU(0) = Right


   REM Move Down
   ScanY = y
   inc y
   posY = y*FloodWidth(0)

   if y < FloodHeight(0)-1

      for x = Left to Right

         if x < ScanLeftD(ScanY) or x > ScanRightD(ScanY)

            pos = 12+(x+posY)*FloodBytes(0)

            REM Check 16bit or 32bit
            if FloodBytes(0) = 2
               if memblock word(1,pos) = FloodTargetColor(0)
                  write memblock word 1,pos,FloodFillColor(0)
                  FloodLoop(x,y)
               endif
               else
               if memblock dword(1,pos) = FloodTargetColor(0)
                  write memblock dword 1,pos,FloodFillColor(0)
                  FloodLoop(x,y)
               endif
            endif

            else
            x = ScanRightD(ScanY)+1

         endif

      next x

   endif
   dec y

   if y > 0
      ScanLeftD(y-1) = Left
      ScanRightD(y-1) = Right
   endif

EndFunction