PLAYBASIC SOURCE CODES


Hal Teach me to code Morphing Shapes

Hal Teach me to code  -  Morphing Shapes

  This tiny source code snippet uses PlayBASIC's shapes to draw batches of line fragments. The fragments are all connected in a circle were each vertex is waving and rotating.  On their own the effect is really simple; but when you overlay (rotate and scale) a bunch of them on top of each other it creates a sort of button effect similar to the robotic voice in the classic science function movie 2001 A Space Odyssey.  Excuse my poor impressions of Hal in this  video.. It's just for laughs







PlayBASIC Code:
; PROJECT : Morphing Shape Tunnel
; AUTHOR  : Learn To Code PlayBASIC - http://PlayBASIC.com
; CREATED : 11/05/2022
; EDITED  : 13/05/2022
; ---------------------------------------------------------------------

    openscreen 1280,960,32,1
    
positionscreen getscreenxpos(),10

Count=360*3

  RingShape = NewShape(Count, Count)
  
  //  Set the edge links for this shape.
  For lp =0 to Count-2
      SetShapeEdge  RingShape,lp, lp,lp+1
  next 
  ; // link the last one back to the first  
  SetShapeEdge RingShape,lp,lp,0


    Screen=NewFxImage(GetSurfaceWidth(),GetSurfaceHeight())
    
        Scaler#=2

      Rings=10
        Ringcolour=$505050
        ColourCountDown=200

  do

        rendertoimage Screen
      
      inkmode 1+2048
        boxc 0,0,getsurfacewidth(),getsurfaceheight(),true,$f0e0d0
      
      mx#=getsurfacewidth()/2
      my#=GetSurfaceheight()/2
      
            Scaler#=wrapvalue(scaler#+0.25,1,100)

      
      for lp =0 to Count-1
            ; randomly init the vertex as polar coordinates        
            Angle#=(360.0/Count)*lp
;            Radius# =120+cosRadius(WobbleAngle2#+lp*1.23,34)+ Cos(WobbleAngle#+(Angle#*Scaler#))*50
            Radius# =90+cos(WobbleAngle#+(Angle#*Scaler#))*50
            setshapevertex RingShape,lp,Cosradius(Angle#,Radius#)  ,Sinradius(Angle#,Radius#)      
      next
    ;    WobbleAngle2#+=0.43
      WobbleAngle#-=(2.25)*4
      
      lockbuffer
      Scale#=0.5
      
      
      inkmode 1+64
      for lp=0 to Rings
          ink RgbFade( Ringcolour, Float(lp)/Rings *50) 
            rotateshape ringShape,SpinAngle#+lp*10,Scale#
          drawshape RingShape,mx#,my#,1
            Scale#+=0.33
          next
      unlockbuffer
      
      SpinAngle#+=0.2

      
      rendertoscreen
      drawimage Screen,0,0,false
      
      
      ColourCountDown--
      if ColourCountDown<0
              ColourCountDown=30
              Ringcolour= rgbalphaadd( (rndrgb() and $3f3f3f), $080808)
      endif


      sync      
  loop spacekey()






[ Links ]



  - Buy 2001 A Space Odyssey [1968] (Region Free)
 
  - Music:
  The Right Direction by Shane Ivers - https://www.silvermansound.com

  Movie samples - https://movie-sounds.org/ 

2D Vector Library

  2D Vector Library

    This library provides a set of functions for working with 2D vectors. A 2D vector is a geometric object that has both magnitude (length) and direction and can be represented by an ordered pair of real numbers (x, y).

    The functions in this library allow you to create, manipulate, and perform calculations with 2D vectors. Some of the things you can do with these functions include:

  - Set the x and y components of a 2D vector using SetVector2D
  - Convert polar coordinates (angle and radius) to Cartesian coordinates (x and y) using SetPolar2D
  - Copy the values of one 2D vector to another using CopyVector2D
  - Add or subtract two 2D vectors using AddVectors2D or SubVectors2D
  - Multiply or divide two 2D vectors component-wise using MultVectors2D or DivVectors2D
  - Multiply or divide a 2D vector by a scalar value using MultVector2D or DivVector2D
  - Linearly interpolate between two 2D vectors using LerpVector2D
  - Normalize a 2D vector (i.e., set its magnitude to 1) using GetVectorNormal2D
  - Calculate the length or squared length of a 2D vector using GetVectorLength2D or GetVectorSquaredLength2D
  - Check if two 2D vectors are equal using AreVectorsEqual2D
  - Calculate the dot product or cross product of two 2D vectors using DotProduct2D or CrossProduct2D



PlayBASIC Code:
; PROJECT : Vector Library
; AUTHOR  : Kevin Picone - PlayBASIC Tutor - https://PlayBASIC.com
; CREATED : 12/05/2022
; EDITED  : 28/05/2022
; ---------------------------------------------------------------------



        //  Use a typed array to hold all the vectors we'll be using
        Dim vectors(100) as vector2d
        for lp =0 to getArrayElements(vectors())
            vectors(lp)= new vector2D
        next
        
    
        //  declare some pointers of type vector for use in the examples        
        Dim N as vector2d pointer
        Dim V1 as vector2d pointer
        Dim V2 as vector2d pointer
        Dim OldPoint as vector2D pointer

        //  Get pointers to some pre--allocated vectors in our cache array        
        n = Vectors(0).vector2d        
        V1 = Vectors(1).vector2d        
        V2 = Vectors(2).vector2d        


        Dim CurrentPoint as vector2D pointer
        CurrentPOint = Vectors(3).vector2d        
        
        Dim OldPoint as vector2D pointer
        OldPOint = Vectors(4).vector2d        

        Dim Lerp1 as vector2D pointer
        Lerp1 = Vectors(10).vector2d        
        
        Dim Lerp2 as vector2D pointer
        Lerp2 = Vectors(11).vector2d        
        
        
        SetVector2d lerp1, 500,100
        SetPolar2d lerp2, Rnd(36),rndrange(10,100)
        Addvectors2d Lerp2, Lerp2, Lerp1
        
        
        
        // Set up this vector
        Setvector2d OldPOint,Mousex(),MouseY()    
        Flushmouse
        
        // -----------------------------------------------------------
        // -----------------------------------------------------------
        // -----------------------------------------------------------
        Do
        // -----------------------------------------------------------
        // -----------------------------------------------------------
        // -----------------------------------------------------------
                
                CLS
                
                                
                // Set up this vecor
                Setvector2d CurrentPoint,Mousex(),MouseY()    
                
                
                circlec OldPoint.X,OldPoint.Y, 50,true, $00ff00 
                
                circle CurrentPoint.X,CurrentPOint.Y, 50,true 
            
            
                // Subtract target from current  N = Old - Current
                Subvectors2d(N , oldPoint,CurrentPoint)

                ypos= 50

                text 10,Ypos, "Delta:"+StrVector2d$(N)

                //  Get the length of this delta vector
                Dist#=GetVectorLenght2D(N)
                
                // normalize N = and store it back in N  
                GetVectorNormal2D(N , N) 

                text 10,Ypos+30, "Normalized:"+StrVector2d$(N)

            
                //  Scale Normal by Dist# 
                Multvector2d(N , N, Dist#)

                text 10,Ypos+60, "Scaled Normalized:"+StrVector2d$(N)

                //  Add origin (current point) back on. 
                Addvectors2d(N , N, CurrentPoint)
                
                text 10,Ypos+90, "Result:"+StrVector2d$(N)

                
                //  Scale it  so we can draw line between them
                line CurrentPOint.x,CurrentPOint.y,n.x,n.y
            
                if Mousebutton()=1
                        CopyVector2d OldPoint,CurrentPOint
                endif    
            
            
                //  test lerp
                Linec Lerp1.x,Lerp1.y,Lerp2.x,Lerp2.y, $ff00ff
                
                //  
                LerpFrame        =mod(LerpFrame+1,100)                    
                LerpScale#        =LerpFrame/100.0    
            
                LerpVector2d N,Lerp1,Lerp2,LerpScale#
                
                Circlec n.x , n.y, 5, true ,$ff00ff
    
            
                //  Curve Lerp vector to the one between
                LerpVector2d V1,Lerp1,Lerp2,LerpScale#
                LerpVector2d V2,CurrentPoint,OldPoint,LerpScale#
                LerpVector2d V1,V2,V1,LerpScale#
                Circlec v1.x , v1.y, 5, true ,$ff00ff
            
                LerpVector2d V1,Lerp1,Oldpoint,LerpScale#
                LerpVector2d V2,lerp2,CurrentPoint,LerpScale#
                LerpVector2d V1,V2,V1,LerpScale#
                Circlec v1.x , v1.y, 5, true ,$ff00ff
            
                Sync
    loop  Spacekey()
    
    


#1
2D-Vectors-Library-V001.zip (4.85 KB)

Tokenize String Simple String Lexer

  Tokenize String - Simple String Lexer


Here are the main bullet points that summarize what this code does:

  *  The code defines a custom data type named tLexToken that has three fields: TOKEN$, TOKEN_TYPE, and INDEX.

  - The code initializes an array named TOKENS to hold instances of tLexToken. The array has 256 elements.

  - The code creates a string variable named Message$ that contains a string to be tokenized. The string has some numbers, a string literal, and an arithmetic expression.

  - The code calls a function named TOKENIZE_STRING that takes two arguments: a string to be tokenized and an array of tLexToken instances to hold the tokens.

  - The TOKENIZE_STRING function defines three arrays to map ASCII characters to token types: ASCII_MAP, ASCII_WORD, and ASCII_NUMBER. The function also initializes a variable named TOKENS_COUNT to zero.
 
  -  The TOKENIZE_STRING function loops over each character in the input string and checks its ASCII value against the mapping arrays to determine its token type. The function then groups consecutive characters of the same type into a single token and adds it to the TOKENS array.

  - The TOKENIZE_STRING function returns the number of tokens that it has created.
 
  - The main code then loops over the TOKENS array and prints each token's index, type, and value. Finally, the code waits for the user to press a key before terminating.


PlayBASIC Code:
    Type tLexToken
            TOKEN$
            TOKEN_TYPE
            INDEX
    EndType

    Dim TOKENS(256) as tLexToken

    Message$=" This is the string I was to tokenize.  1000 * 2000"
    Message$+= chr$(34)+"String Literal"+chr$(34)
    Message$+= "12+4+5+6"
    print Message$

    Count=TOKENIZE_STRING(Message$, TOKENS())
    For lp =0 to Count-1
        s$ ="("+str$(Tokens(lp).TOKEN_TYPE)+")"
        s$+="="+Tokens(lp).TOKEN
        print "#"+str$(lp)+" "+s$
    next

    Sync
    waitkey
    




    // --------------------------------------------------------------------------------------------------
    // --------------------------------------------------------------------------------------------------
    // -------------------------------------->> TOKENIZE STRING <<---------------------------------------
    // --------------------------------------------------------------------------------------------------
    // --------------------------------------------------------------------------------------------------

    
function TOKENIZE_STRING(InputTEXT$, TOKENS().tLexToken)

        Size          =len(InputTEXT$)

        Static _INIT_LOCALS
        if _INIT_LOCALS=false

            _INIT_LOCALS=true

            dim ASCII_MAP(255)
            dim ASCII_WORD(255)
            dim ASCII_NUMBER(255)
    
            // ----------------------------------------------------------
            // Map common ASCC CHARACTERs
            // ----------------------------------------------------------
            ASCII_MAP(9)    = 9        //  TAB charatcer

            // ----------------------------------------------------------
            //  MAP Characters
            // ----------------------------------------------------------
            WORD$ =" .()+-/*="
            for lp=1 to len(WORD$)
                ThisCHR = mid(WORD$,lp)
                ASCII_MAP(ThisCHR)= ThisCHR
            next
        

        // ----------------------------------------------------------
        //  WORDS  UPPER / LOWER CASE with UNDER SCORES
        // ----------------------------------------------------------
            WORD$ ="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
            for lp=1 to len(WORD$)
                ThisCHR = mid(WORD$,lp)
                ASCII_MAP(ThisCHR)= 1000
            next
    


        // ----------------------------------------------------------
        //  NUMBERS
        // ----------------------------------------------------------
            WORD$ ="0123456789"
            for lp=1 to len(WORD$)
                ThisCHR = mid(WORD$,lp)
                ASCII_MAP(ThisCHR)= 1001
            next

            // ----------------------------------------------------------
            //  STRING LITERAL 
            // ----------------------------------------------------------
            ASCII_MAP(34)    = 1002        //  STRING LITERAL block
        



        // ----------------------------------------------------------
        //  ALPHA NUMERIC WORDS 
        // ----------------------------------------------------------
        
            WORD$ ="0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            for lp=1 to len(WORD$)
                ThisCHR = mid(WORD$,lp)
                ASCII_WORD( ThisCHR)    = ThisCHR
            next
            
        // ----------------------------------------------------------
        //  ALPHA NUMERIC WORDS 
        // ----------------------------------------------------------
    
            WORD$ ="0123456789."
            for lp=1 to len(WORD$)
                ThisCHR = mid(WORD$,lp)
                ASCII_NUMBER( ThisCHR)    = ThisCHR
            next

        endif

        TOKENS_COUNT=0

        for lp=1 to size
            
                ThisCHR = mid(InputTEXT$,lp)
                
                CHR_TYPE = ASCII_MAP(ThisCHR)
                
                //  DECODE RUN OF SAME TYPE OF CHARACTERS        
                if (CHR_TYPE>255)

                        EndPOS = lp    

                        // -------------------------------------------------
                        //  DECODE A WORD    
                        // -------------------------------------------------
                        if (CHR_TYPE=1000)

                            for ScanLP=lp to Size
                                SearchCHR    = mid(InputTEXT$,ScanLP)
                                if (ASCII_WORD(SearchCHR)=0) then exit
                                EndPOS = ScanLP
                            next
                            
                        endif

                        // -------------------------------------------------
                        //  DECODE A NUMBER    
                        // -------------------------------------------------
                        if (CHR_TYPE=1001)

                            for ScanLP=lp to Size
                                SearchCHR    = mid(InputTEXT$,ScanLP)
                                if (ASCII_NUMBER(SearchCHR)=0) then exit
                                EndPOS = ScanLP
                            next
                        endif    

                        // -------------------------------------------------
                        //  DECODE A STRING LITERAL
                        // -------------------------------------------------
                        if (CHR_TYPE=1002)

                            for ScanLP=lp+1 to Size
                                SearchCHR    = mid(InputTEXT$,ScanLP)
                                EndPOS = ScanLP
                                if SearchCHR=34 then exit
                            next
                        endif



                        //  Get This TOKEN
                        TOKEN$ = mid$(InputTEXT$, lp, (EndPOS+1)-lp) 

                        TOKENS(TOKENS_COUNT)                = new tLexTOKEN
                        TOKENS(TOKENS_COUNT).TOKEN        = TOKEN$
                        TOKENS(TOKENS_COUNT).TOKEN_TYPE  = CHR_TYPE
                        TOKENS(TOKENS_COUNT).INDEX          = lp
                        TOKENS_COUNT++;
                        lp=EndPOS    
                        continue
                endif
    

                if (CHR_TYPE)
                        TOKENS(TOKENS_COUNT) = new tLexTOKEN
                        TOKENS(TOKENS_COUNT).TOKEN        = chr$(ThisCHR)
                        TOKENS(TOKENS_COUNT).TOKEN_TYPE    = CHR_TYPE
                        TOKENS(TOKENS_COUNT).INDEX          = lp
                        TOKENS_COUNT++
                endif
        next    
endfunction TOKENS_COUNT
COMMANDS USED: DIM | CHR$ | PRINT | STR$ | SYNC | WAITKEY | LEN | MID | MID$ | NEW |

Make Cogs Shapes Example

Make Cogs - Shapes Example

  Here's a cool old example that you'll find deep inside the PlayBASIC example packs





PlayBASIC Code:
; PROJECT : Make_Cogs
; AUTHOR  : Kevin Picone
; CREATED : 11/04/2006
; EDITED  : 21/06/2006
; ---------------------------------------------------------------------



    Cog=Create_Cog_Shape(100,80,23)


    ScreenCX=GetScreenWidth()/2
    ScreenCY=GetScreenHeight()/2
    
    ShapeColour=rgb(255,255,255)

    TestShape    =newconvexshape(200,4)
    TestShape2    =newconvexshape(100,4)
    mergeshape testshape2,testshape


    Do
        
        cls rgb(100,100,100)

        mx=mousex()
        my=mousey()
        dx#=ScreencX-mx
        dy#=ScreencY-mY
        lockbuffer
        
            ShadowX#=ScreenCX+(dx#/2)
            ShadowY#=ScreenCY+(dy#/2)

            ink rgbfade(shapecolour,20)
            rotateshape cog,angle#,2

            DrawShape Cog,ShadowX#,ShadowY#,2
            
            ; draw the foreground version of the spinning cog shape
            rotateshape cog,angle#,1
            ink ShapeCOlour
            inkmode 1

                DrawShape cog,ScreenCX,ScreenCY,2
            unlockbuffer

            ; bump the rotation angle    
            angle#=wrapangle(angle#,1)    

        sync
    loop        
        
    


Function Create_Cog_Shape(outterRadius,InnerRadius,sides)
    sides=sides -(mod(sides,2))    
    EdgeCount    =Sides*2
    VertexCount    =Sides*2
    ThisShape    =NewShape(VertexCount+1,EdgeCount+1)

    For lp=0 to sides
        x#=Cosradius(angle#,OutterRadius)
      y#=Sinradius(angle#,OutterRadius)
        SetshapeVertex thisshape,Numberofvertex,x#,y#
        inc Numberofvertex
        x#=Cosradius(angle#,InnerRadius)
      y#=Sinradius(angle#,InnerRadius)
        SetshapeVertex Thisshape,Numberofvertex,x#,y#
        inc Numberofvertex
        angle#=angle#+(360.0/Sides)
    next


    For Vertex=0 to Numberofvertex-2 step 2
        NextVertex=vertex+1
        if NextVertex=>Numberofvertex then nextVertex=Numberofvertex-NextVertex
        SetshapeEdge Thisshape,Edge,vertex,Nextvertex
        inc edge

        if Outline
            SrcVertex=Vertex
            NextVertex2=vertex+2
            if NextVertex2=>Numberofvertex then nextVertex2=Numberofvertex-NextVertex
        else
            SrcVertex=NextVertex
            NextVertex2=vertex+3
            if NextVertex2=>Numberofvertex then nextVertex2=Numberofvertex-NextVertex
        endif

        SetshapeEdge Thisshape,Edge,Srcvertex,Nextvertex2
        inc edge

        Outline=1-Outline
    next
    
EndFunction ThisShape

Clip Rectangle To Rectangle

Clip Rectangle To Rectangle

  In this example, we're clipping the background rectangle to the foreground rectangle. This results in 16 possible layouts that the pair of rectangles can have in relation to each other. The goal is to output a list of areas that represent the visible portion of the background rectangle without overlapping any pixels



PlayBASIC Code:
; PROJECT : Clip Foreground Rectangle TO Background Rectangle
; AUTHOR  : Kev Picone - https://PlayBASIC.com
; CREATED : 8/04/2023
; EDITED  : 9/04/2023
; ---------------------------------------------------------------------

    loadfont "courier new",1, 40

    Type tRect
            x1,y1
            x2,y2
            Colour
    EndType
    
    Dim Rects(16) as tRect

    Global RectCount    =0

    do


        Dim Back as tRect Pointer
        Back = new TRect

        w= rndrange(100,500)
        h= rndrange(100,500)
        X=rnd( getscreenwidth() * 0.60)
        Y=rnd(getscreenheight() * 0.60)
        Back.x1 = x
        Back.y1 = y
        Back.x2 = x+w
        Back.y2 = y+h
        Back.colour =rndrgb()    

        Dim Front as tRect Pointer
        Front = new TRect
    
        W= 500
        H= 150
        
        // --------------------------------------------------------
        Do
        // --------------------------------------------------------
            cls $203040
        
                Boxc Back.x1,Back.y1,Back.x2,Back.y2,true,Back.Colour
    
    
                Front.x1=mousex()
                    Front.y1=mousey()
                Front.x2=Front.x1+W
                Front.y2=Front.y1+H
    
                box Front.x1,Front.y1,Front.x2,Front.y2,true
    
    
                inkmode 1+1024
                Status =ClipRectangles(Front,Back)
                inkmode 1
    
                for lp =0 to Status-1
                    X1=Rects(lp).x1
                        y1=Rects(lp).y1    
                    x2=Rects(lp).x2    
                    y2=Rects(lp).y2
                    boxc x1,y1,x2,y2,false, $00ff00
                    boxc x1+1,y1+1,x2-1,y2-1,false, $00ff00

                    s$ =" X1="+str$(X1)
                    s$+=" Y1="+str$(Y1)
                    s$+=" Y1="+str$(X2)
                    s$+=" Y1="+str$(Y2)

                    Print "#"+str$(lp)+s$
                            
                next

                if Status=-2
                    Print "Foreground covers background"
                endif

                if mousebutton()=2
                        w=rndrange(50,500)
                        h=rndrange(50,350)
                endif
    
            sync

        // --------------------------------------------------------
        loop spacekey()
        // --------------------------------------------------------

        free front
        free back

            
loop    




Function ClipRectangles(Front as tRect Pointer, Back as tRect Pointer)

        RectCount    =0
        Count = -1    

        if int(Front)=0 or int(Back)=0 then ExitFunction -1

        // chec if the Front rect to the left or right of te back rect
        if Front.X2<Back.X1 then exitfunction Count
        if Front.X1>Back.X2 then exitfunction Count
    
        //  check if the FRONT is ABOVE or BELLOW the BACK rect
        if Front.Y2<Back.Y1 then exitfunction Count
        if Front.Y1>Back.Y2 then exitfunction Count


        //  Make bit pattern for what side each point is to its patern
        Layout    = (Front.X1>=Back.X1 << 1)+ ( Front.X2>Back.X2) 
        Layout    =Layout<<2

        Layout+= Front.Y1>=Back.Y1 << 1
        Layout+= Front.Y2>Back.Y2 

        Filled    =true
        static ThisRGB    
        
        ThisRGB = -1
        
        print bin$(Layout)
        
        Select LayOut

                // ---------------------------------------------
                case %0000
                // ---------------------------------------------

                        //  front is covering back to left and 
                        //  above and bellow back
                        SetBox( Front.x2    ,Back.y1        ,back.x2    ,front.y2    , ThisRGB)
                        SetBox( Back.x1    ,front.y2    ,back.x2    ,back.y2        , ThisRGB)

                // ---------------------------------------------
                case %0001
                // ---------------------------------------------

                        //  front is covering back to left and 
                        //  above and bellow back
                        SetBox( Front.x2,Back.y1    ,back.x2    ,back.y2, ThisRGB )



                // ---------------------------------------------
                case %0010
                // ---------------------------------------------

                        // top chunk
                        SetBox( Back.x1,Back.y1    ,back.x2    , front.y1, ThisRGB )

                        // bottom chunk
                        SetBox( Back.x1,front.y2    ,back.x2    , back.y2, ThisRGB )

                        //  middle chuck to the right of the front rect
                        SetBox( Front.x2,front.y1    ,back.x2    ,front.y2, ThisRGB )

        

                // ---------------------------------------------
                case %0011
                // ---------------------------------------------

                        //  The front rect is covering back rect
                        SetBox( Back.x1,Back.y1    ,Back.x2    ,Front.y1, ThisRGB )
                        SetBox( front.x2,front.y1,back.x2,back.y2    ,ThisRGB )

                // ---------------------------------------------
                case %0100
                // ---------------------------------------------

                        //  visible left edge of back
                        SetBox( Back.x1,front.y2    ,back.x2    ,back.y2, ThisRGB )


            
                // ---------------------------------------------
                case %0101
                // ---------------------------------------------

                        // draw nothing// front overlaps backdrop
                        exitfunction -2
        


            
                // ---------------------------------------------
                case %0110
                // ---------------------------------------------

                        // Top 
                        SetBox( Back.x1,back.y1    ,back.x2    ,front.y1, ThisRGB )

                        // bottom 
                        SetBox( Back.x1,front.y2    ,back.x2    ,back.y2, ThisRGB )

                // ---------------------------------------------
                case %0111
                // ---------------------------------------------

                        //  visible left edge of back
                        SetBox( Back.x1,back.y1    ,back.x2    ,front.y1, ThisRGB )



                // ---------------------------------------------
                case %1000
                // ---------------------------------------------


                        // chunks of either side
                        SetBox( Back.x1    ,Back.y1    ,front.x1    ,front.y2, ThisRGB )
                        SetBox( front.x2    ,Back.y1    ,back.x2    , front.y2, ThisRGB )
    
                        // bottom section
                        SetBox( Back.x1    ,front.y2    ,back.x2    ,back.y2, ThisRGB )
                                                


                // ---------------------------------------------
                case %1001
                // ---------------------------------------------
                        SetBox( Back.x1,Back.y1    ,front.x1    ,back.y2, ThisRGB )
                        SetBox( front.x2,Back.y1    ,back.x2    ,back.y2, ThisRGB )


                // ---------------------------------------------
                case %1010
                // ---------------------------------------------

                        // front rect is inside the background rect
                        // Top Chunk
                        SetBox( Back.x1,Back.y1    ,back.x2    ,front.y1, ThisRGB )
                        // bottom
                        SetBox( Back.x1,front.y2    ,back.x2    ,back.y2, ThisRGB )

                        // Left chunk
                        SetBox( Back.x1,front.y1    ,front.x1    ,front.y2, ThisRGB )

                        //  right chunk
                        SetBox( front.x2,front.y1    ,back.x2    ,front.y2, ThisRGB )


                // ---------------------------------------------
                case %1011
                // ---------------------------------------------

                        // top section
                        SetBox( Back.x1,back.y1    ,back.x2    ,front.y1, ThisRGB )

                        //  left and right blocks
                        SetBox( Back.x1,front.y1    ,front.x1    ,back.y2, ThisRGB )
                        SetBox( front.x2,front.y1    ,back.x2    ,back.y2, ThisRGB )
        
        
                // ---------------------------------------------
                case %1100
                // ---------------------------------------------

                        //  visible left edge of back
                        SetBox( Back.x1,Back.y1    ,front.x1    ,back.y2, ThisRGB )

                        //  visible bottom strip of bacl
                        SetBox( front.x1,front.y2    ,back.x2    ,back.y2, ThisRGB )


        

                // ---------------------------------------------
                case %1101
                // ---------------------------------------------

                        //  front is covering back to left and 
                        //  above and bellow back
                        SetBox( Back.x1,Back.y1    ,front.x1    ,back.y2, ThisRGB )

        

                // ---------------------------------------------
                case %1110
                // ---------------------------------------------
                        // top part
                        SetBox( Back.x1,Back.y1    ,Back.x2    ,Front.y1, ThisRGB )

                        //  bottom part
                        SetBox( Back.x1,front.y2    ,Back.x2    ,back.y2, ThisRGB )

                        // left hand box
                        SetBox( Back.x1,front.y1    ,front.x1    ,Front.y2, ThisRGB )
    
        
                // ---------------------------------------------
                case %1111
                // ---------------------------------------------

                        //  The front rect is covering back rect
                        SetBox( Back.x1,Back.y1    ,Back.x2    ,Front.y1, ThisRGB )
                        SetBox( Back.x1,front.y1,front.x1,back.y2    ,ThisRGB )

        EndSelect
        
    
        Count=RectCount
        ThisRGB+=$112233
    
EndFunction Count



function SetBox(X1,Y1,X2,Y2,Colour)
    
        if Rects(RectCount)=0
                Rects(RectCount) = new tRect
        endif
        Rects(RectCount).x1=x1    
        Rects(RectCount).y1=y1    
        Rects(RectCount).x2=x2    
        Rects(RectCount).y2=y2    
        Rects(RectCount).Colour=Colour    
        RectCount++    

      Boxc x1,y1,x2,y2,true,Colour

EndFunction