About 4D Systems PTY LTD
4D Systems, Australia
Home Company Products 4DGL Developers Center Support forum Distributors News & Events Contact us App Notes
4DGL - Sharing our bytes to the world

Big Demo


Codebase / GOLDELOX-GFX / Graphics Applications

Big demo showing off many graphics features.
About this code
Author: 4D Systems
Uploaded on: 03/10/2008

Back to previous page

Source code:

#platform "uOLED-GOLDELOX"

/*  4DGL Demo Application
       - Scope Demo -
 -- All GOLDELOX Platforms --
*/

#inherit "4DGL_16bitColours.fnc"


// constants for the viewport
#CONST
    windowXpos   30
    windowYpos   30
    windowWidth  78
    windowHeight 60
#END

#CONST 
    TRIANGLE         3     
    RECTANGLE      4  
    PENTAGON        5
    HEXAGON         6     
    LEFTCOLOUR          0xF800
    RIGHTCOLOUR       0xFFFF
    TOPCOLOUR           0x001F
    BOTTOMCOLOUR    0x07E0
#END


#CONST    
    LEFTHIT         15
    RIGHTHIT       113
    TOPHIT          15
    BOTTOMHIT    113
#END

#constant XSPEED   3
#constant YSPEED   2
#constant WALL       4   // outer wall thickness


// constant object definitions
#constant ERASEBALL     $ball_x, ball_y, 3, BLACK
#constant DRAWBALL      $ball_x, ball_y, 3, ball_colour

#constant LEFTWALL      $0, 0, WALL , 127, LEFTCOLOUR
#constant RIGHTWALL     $127-WALL , 0, 127, 127, RIGHTCOLOUR
#constant TOPWALL       $0, 0, 127-WALL, WALL , TOPCOLOUR
#constant BOTTOMWALL    $gfx_Rectangle(0, 127-WALL, 127, 127, BOTTOMCOLOUR)  

#constant BALLSIZE 10  // Notice constants can be post declared


var ball_x, ball_y, ball_r, ball_colour;
var xdir, ydir;
var targetX, targetY;

var Xcoords[6], Ycoords[6];     // big enough for a hexagon

#constant SAMPLES 16    

var ScopeBuf[SAMPLES];
var oldseed, loops;

//----------------------------------------------------------------------------------------//
func drawWalls()
    gfx_Set(PEN_SIZE, SOLID);
    gfx_Rectangle(TOPWALL);            // Draw Top Wall
    BOTTOMWALL;                            // Draw Bottom Wall
    gfx_Rectangle(LEFTWALL);           // Draw Left Wall
    gfx_Rectangle(RIGHTWALL);        // Draw Right Wall
endfunc
//----------------------------------------------------------------------------------------//


//----------------------------------------------------------------------------------------//
func collision()
    if(ball_x <= LEFTHIT)
        ball_x := LEFTHIT;
        ball_colour := LEFTCOLOUR;
        xdir := -xdir;
    endif

    if(ball_x >= RIGHTHIT)
        ball_x := RIGHTHIT;
        ball_colour := RIGHTCOLOUR;
        xdir := -xdir;
    endif

    if (ball_y <= TOPHIT) 
        ball_y := TOPHIT;
        ball_colour := TOPCOLOUR;
        ydir := -ydir;
    endif

    if(ball_y >= BOTTOMHIT)
        ball_y := BOTTOMHIT;
        ball_colour := BOTTOMCOLOUR;
        ydir := -ydir;
    endif
endfunc
//----------------------------------------------------------------------------------------//


//----------------------------------------------------------------------------------------//
// blank the screen, draw scope if start of demo loop then do random dot intro
func Blankout()
    var n, x, y;
    
    gfx_Set(PEN_SIZE, SOLID);    
    // clear the window   
    gfx_Rectangle(windowXpos, windowYpos, windowXpos+windowWidth, windowYpos+windowHeight, BLACK);
    
    gfx_Set(CLIPPING, ON);    // turn the clipping on
    
    if ((loops & 63) == 0)        // do waveform timeslot?
        SEED(oldseed);
        n := 0;
        while (n < SAMPLES)
            ScopeBuf[n++] := RAND()/1500;      // fill scope with scaled random data
        wend
        oldseed := RAND();
    
        n := SAMPLES*10;  // repeat the buffer 10 times
        while (n--)
            gfx_Set(OBJECT_COLOUR, LIME);
            gfx_Plot(SAMPLES, ScopeBuf, n, AUTO);   // plot the waveform 
            pause(40);                              // frame delay
            
            // erase the old window
            gfx_Set(PEN_SIZE, SOLID);    
            gfx_Rectangle(windowXpos, windowYpos, windowXpos+windowWidth, windowYpos+windowHeight, BLACK);
        wend
    endif
     
    gfx_Set(PEN_SIZE, SOLID);    
    gfx_Rectangle(windowXpos, windowYpos, windowXpos+windowWidth, windowYpos+windowHeight, BLACK);

    // dots
    SEED(1234);
    n := -3000;
    while (n++<3000)
        x := ABS(RAND()%windowWidth) + windowXpos;
        y := ABS(RAND()%windowHeight) + windowYpos;
        gfx_PutPixel(x , y , RAND());
    wend
    
    // undraw the dots
    SEED(1234);
    n := -3000;
    while (n++<3000)
        x := ABS(RAND()%windowWidth) + windowXpos;
        y := ABS(RAND()%windowHeight) + windowYpos;
        RAND();
        gfx_PutPixel(x , y , 0);
    wend
    
endfunc
//----------------------------------------------------------------------------------------//


//----------------------------------------------------------------------------------------//
// build a polygon with a number of sides determined by var "sides"
// around the current origin. The distance from the origin to the 
// equidistent vertices from origin determined
// by var "distance". var "angle" is the starting angle for the
// first virtices. Draws the polygon in colour var "colr" 
// NB make sure the array is big enough for the required number of sides
//----------------------------------------------------------------------------------------//
func MakePolygon(var angle, var sides, var distance, var colr)
    var index, step;
    index := 0;
    step := 360/sides;                 // work out the step size
    while (sides < 360)                // until we do a complete polygon
        gfx_Orbit(angle, distance);
        Xcoords[index] := targetX;     // build a polygon in the matrix
        Ycoords[index] := targetY;
        index++;
        angle := angle + step;
        sides := sides + step;
    wend
    gfx_Polygon(index, Xcoords, Ycoords, colr);
endfunc
//----------------------------------------------------------------------------------------//


//----------------------------------------------------------------------------------------//
// update the "Frames =" field
//----------------------------------------------------------------------------------------//
func UpdateCounter(var value)
    gfx_Set(CLIPPING, OFF);                 // turn off the clipping
    gfx_MoveTo(88, 100);                     // move graphics cursor to message area
    txt_Set(TEXT_COLOUR, CYAN);
    txt_Set(TEXT_OPACITY, OPAQUE);   // we want solid text so it erases old text
    to(GFX); putnum(UDEC3Z, value);    // print and update the loop count
    txt_Set(TEXT_OPACITY, TRANSPARENT);    // switch back to transparent text
endfunc
//----------------------------------------------------------------------------------------//


//----------------------------------------------------------------------------------------//
func main()
    var dly, angle;

    loops := 0;
    dly := 0;
    angle := 0;

    ball_colour := WHITE;                           // initial ball colour
    xdir := 1; ydir := 1;                             // initial ball direction
    ball_x := 77; ball_y := 33;                   // initial ball position
    
    txt_Set(FONT_SIZE, FONT_SMALL);       // small font
        
    // set generic target variables for the orbit command
    gfx_OrbitInit(&targetX, &targetY); 
    
    // clears screen, turns off clipping
    gfx_Cls();                          

    // preset the clipping area, activated later...
    gfx_ClipWindow(windowXpos, windowYpos, windowXpos+windowWidth, windowYpos+windowHeight);

    // draw a rectangle around the clipped area
    gfx_Set(PEN_SIZE, OUTLINE);
    gfx_Rectangle(windowXpos-1, windowYpos-1, windowXpos+windowWidth+1, windowYpos+windowHeight+1, YELLOW);

    // print all static text messages
    gfx_MoveTo(35, 100);
    to(GFX); putstr("Frames = ");       // place the static message
    
    // draw all initial objects
    drawWalls();                        // draw the Walls                                 
    
    repeat
        pause(14);                      // there is no vsync control, pause

        gfx_Set(CLIPPING, OFF);  // turn off clipping so we can draw outside the clipped area

        // remove the horizontal marker
        if(ball_x < 108) gfx_Triangle(ball_x, 10, ball_x+3, 20, ball_x+6, 10, BLACK); 
        // remove the vertical marker
        if(ball_y < 88) gfx_Triangle(10, ball_y, 20, ball_y+3, 10, ball_y+6, BLACK); 

        if (!(dly++ & 15))             // each 16 times through the main loop,
            if (!(++loops & 15))      // if we're about to start a new pattern
                Blankout();              // draw some pixels to introduce next screen
                ball_x := RAND()%127; ball_y := RAND()%127;   // set ball position
            endif
        endif

        UpdateCounter(dly);     // update the "Frames -" count

       // undraw current object
        gfx_Set(CLIPPING, ON);                      // now turn the clipping back on

        if ((loops & 0x30) == 0x00)
            gfx_MoveTo(ball_x, ball_y);
            txt_Set(TEXT_COLOUR, BLACK);
            to(GFX); print("4DGL");                    // erase the text
        endif

        if ((loops & 0x30) == 0x10)
            gfx_Set(PEN_SIZE, SOLID);
            gfx_Circle(ERASEBALL);                    // erase the ball
        endif

        if ((loops & 0x30) == 0x20)
            gfx_MoveTo(ball_x, ball_y);               // using the balls origin
            MakePolygon(angle, TRIANGLE, 10, BLACK); // undraw old triangle
        endif
        
        if ((loops & 0x30) == 0x30)
            gfx_MoveTo(ball_x, ball_y);               // using the balls origin
            MakePolygon(angle, RECTANGLE, 10, BLACK); // undraw old rectangle
        endif
        
        //=========================================
        // move to new position
        //=========================================
        ball_x := ball_x + xdir * XSPEED;               // move to new X pos
        ball_y := ball_y + ydir * YSPEED;               // move to new Y pos
        collision();                                                // detect collision
        angle := angle + 10;                                 // step to new angle
        //=========================================

        gfx_Set(CLIPPING, OFF);                      // now turn off the clipping
        // redraw the box
        if(ball_x < 108) gfx_Triangle(ball_x, 10, ball_x+3, 20, ball_x+6, 10, MAGENTA);
        // redraw the box
        if(ball_y < 88) gfx_Triangle(10, ball_y, 20, ball_y+3, 10, ball_y+6, ORANGE);
        gfx_Set(CLIPPING, ON);                      // now turn on the clipping

        // redraw required example
        if ((loops & 0x30) == 0x00)
            gfx_MoveTo(ball_x, ball_y);
            txt_Set(TEXT_COLOUR, ball_colour);
            to(GFX); print("4DGL");                             // redraw the text
        endif
        
        if ((loops & 0x30) == 0x10)
            gfx_Set(PEN_SIZE, SOLID);
            //gfx_Set(PEN_SIZE, OUTLINE);
           gfx_Circle(DRAWBALL);                             // redraw the ball
        endif
    
        if ((loops & 0x30) == 0x20)
            gfx_MoveTo(ball_x, ball_y);                       // using the balls origin
            MakePolygon(angle, TRIANGLE, 10, ball_colour);  // make 3 sided polygon = triangle
        endif

        if ((loops & 0x30) == 0x30)
            gfx_MoveTo(ball_x, ball_y);                       // using the balls origin
            MakePolygon(angle, RECTANGLE, 10, ball_colour); // make 4 sided polygon = rectangle
        endif
    forever

endfunc
//----------------------------------------------------------------------------------------//


Copyright © 2007 4D Systems Pty Ltd, Sydney, Australia - All Rights Reserved | Terms and Conditions