Chris Dick
/
Gameduino_Bitmap_demo
Bitmap demo for the Gameduino
Diff: main.cpp
- Revision:
- 0:abda4161bf6e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Dec 20 20:55:38 2012 +0000 @@ -0,0 +1,167 @@ +#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; + } + } + } +} \ No newline at end of file