DBC FloodFill using Memblock by Ashingda 2717th 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 |