Bitmap demo for the Gameduino

Dependencies:   Gameduino mbed

main.cpp

Committer:
TheChrisyd
Date:
2012-12-21
Revision:
1:3637b078dd83
Parent:
0:abda4161bf6e

File content as of revision 1:3637b078dd83:

#include "mbed.h"
#include "GD.h"
#include "shield.h"
GDClass GD(ARD_MOSI, ARD_MISO, ARD_SCK, ARD_D9, USBTX, USBRX) ;


// replicate a 2-bit color across the whole byte.  Optimization for setpixel
byte replicate(byte color)
{
    return (color << 6) | (color << 4) | (color << 2) | color;
}

// Set pixel at (x,y) to color.  (note that color is replicated).
void setpixel(byte x, byte y, byte color)
{
  /*
   Because of the way the sprites are laid out in setup(), it's not too
   hard to translate the pixel (x,y) to an address and mask.  Taking the
   two byte values as x7-x0 and y7-y0, the address of the pixel is:

      x5 x4 y7 y6 y5 y4 y3 y2 y1 y0 x3 x2 x1 x0

  (x6, x7) gives the value of the mask.
  */
    unsigned int addr = RAM_SPRIMG | (x & 0xf) | (y << 4) | ((x & 0x30) << 8);
    byte mask = 0xc0 >> ((x >> 5) & 6);
    GD.wr(addr, (GD.rd(addr) & ~mask) | (color & mask));
}

// Draw color line from (x0,y0) to (x1,y1).
void line(byte x0, byte y0, byte x1, byte y1, byte color)
{
    byte swap;
#define SWAP(a, b) (swap = (a), (a) = (b), (b) = swap)

    color = replicate(color);
    byte steep = abs(y1 - y0) > abs(x1 - x0);
    if (steep) {
        SWAP(x0, y0);
        SWAP(x1, y1);
    }
    if (x0 > x1) {
        SWAP(x0, x1);
        SWAP(y0, y1);
    }
    int deltax = x1 - x0;
    int deltay = abs(y1 - y0);
    int error = deltax / 2;
    signed char ystep;
    if (y0 < y1)  
    {
        ystep = 1;
    }
    else
    {
        ystep = -1;
    }
    byte x;
    byte y = y0;
    for (x = x0; x < x1; x++) 
    {
        if (steep)
        {
            setpixel(y, x, color);
        }
        else
        {
            setpixel(x, y, color);
        }
        error -= deltay;
        if (error < 0) 
        {
            y += ystep;
            error += deltax;
        }
    }
}

struct point {
  int x, y;
  signed char xv, yv;
};
static struct point triangle[3];

#define RANDOM_RGB() RGB(rand()%256,rand()%256,rand()%256)

// Restart the drawing
static void restart()
{
    // Clear the screen
    GD.fill(RAM_SPRIMG, 0, 16384);

    // Position triangle at random
    byte i;
    for (i = 0; i < 3; i++) {
        triangle[i].x = 3 + rand()%250;
        triangle[i].y = 3 + rand()%250;
    }
    triangle[0].xv = 1;
    triangle[0].yv = 1;
    triangle[1].xv = -1;
    triangle[1].yv = 1;
    triangle[2].xv = 1;
    triangle[2].yv = -1;

    // Choose a random palette
    GD.wr16(PALETTE4A, RGB(0,0,0));
    GD.wr16(PALETTE4A + 2, RANDOM_RGB());
    GD.wr16(PALETTE4A + 4, RANDOM_RGB());
    GD.wr16(PALETTE4A + 6, RANDOM_RGB());
}

void setup()
{
    int i;

    GD.begin();
    GD.ascii();
    GD.putstr(0, 0,"Bitmap demonstration");

    // Draw 256 sprites left to right, top to bottom, all in 4-color
    // palette mode.  By doing them in column-wise order, the address
    // calculation in setpixel is made simpler.
    // First 64 use bits 0-1, next 64 use bits 2-4, etc.
    // This gives a 256 x 256 4-color bitmap.

   for (i = 0; i < 256; i++) {
       int x =     72 + 16 * ((i >> 4) & 15);
       int y =     22 + 16 * (i & 15);
       int image = i & 63;     /* image 0-63 */
       int pal =   3 - (i >> 6);   /* palettes bits in columns 3,2,1,0 */
       GD.sprite(i, x, y, image, 0x8 | (pal << 1), 0);
    }
    restart();
}

int main()
{
    setup();
    while(1)
    {
        static byte color;

        if (rand()%1000 == 0)
        {
            restart();
        }
        line(triangle[0].x, triangle[0].y, triangle[1].x, triangle[1].y, color);
        line(triangle[1].x, triangle[1].y, triangle[2].x, triangle[2].y, color);
        line(triangle[2].x, triangle[2].y, triangle[0].x, triangle[0].y, color);
        color = (color + 1) & 3;
        byte i;
        for (i = 0; i < 3; i++) 
        {
            triangle[i].x += triangle[i].xv;
            triangle[i].y += triangle[i].yv;
            if (triangle[i].x == 0 || triangle[i].x == 255)
            {
                triangle[i].xv = -triangle[i].xv;
            }
            if (triangle[i].y == 0 || triangle[i].y == 255)
            {
                triangle[i].yv = -triangle[i].yv;
            }
        }
    }
}